通过 Google OAuth 登录时使用 IProfileService
Using IProfileService when sign-in by Google OAuth
我正在尝试更改 IdentityServer4 AspNetIdentity 示例,以便能够从本地创建的用户和 Google 登录。
我可以通过添加 Google 身份验证来做到这一点:
app.UseIdentity();
app.UseIdentityServer();
var cookieScheme = app.ApplicationServices.GetRequiredService<IOptions<IdentityOptions>>().Value.Cookies.ExternalCookieAuthenticationScheme;
// Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715
app.UseGoogleAuthentication(new GoogleOptions
{
AuthenticationScheme = "Google",
SignInScheme = cookieScheme,
ClientId = "client_id",
ClientSecret = "client_secret"
});
正如预期的那样,主页视图显示了正确的用户声明:
sub
c51da331-0348-45dd-352f-08d4526f6266
name
EMAIL@gmail.com
AspNet.Identity.SecurityStamp
568a167f-a431-4f70-ba66-918f99e95eef
idp
Google
amr
external
auth_time
1486815555
当用户首次使用 Google 帐户登录时,我将一些信息添加到数据库中,我认为我可以通过使用自定义 IProfileService 实现并将 IdentityServer 配置为使用我的方法将它们添加到用户声明中自定义 IProfileService:
var builder = services.AddIdentityServer();
builder.AddTemporarySigningCredential();
builder.AddConfigurationStore(b => b.UseSqlServer(connectionString, options => options.MigrationsAssembly(migrationAssembly)));
builder.AddOperationalStore(b => b.UseSqlServer(connectionString, options => options.MigrationsAssembly(migrationAssembly)));
builder.AddAspNetIdentity<MyUser>();
builder.AddProfileService<MyCustomProfileService>();
但现在当我导航到主页时,用户声明保持不变,甚至 GetProfileDataAsync 方法也不会命中。
如果有人能告诉我这是什么,我将不胜感激。
根据 Adding Custom Claims to an ASPNET Core Identity Implementation on github, the GetProfileDataAsync
method is only called if claims need to be put in a token. Also it has a link to Optimizing Identity Tokens for size post 中的讨论解释,
默认情况下,IdentityServer 的行为符合 OpenID Connect 规范,建议如下(在第 5.4 节中):
The Claims requested by the profile, email, address, and phone scope values are returned from the UserInfo Endpoint, as described in Section 5.3.2, when a response_type value is used that results in an Access Token being issued. However, when no Access Token is issued (which is the case for the response_type value id_token), the resulting Claims are returned in the ID Token.
换句话说,如果只请求身份令牌,则将所有声明放入令牌中。但是,如果还请求访问令牌 => 从身份令牌中删除声明并让客户端使用 userinfo 端点检索它们。
但是,可以通过在客户端配置中设置 AlwaysIncludeUserClaimsInIdToken
标志来覆盖此默认行为(更多 this)。
事实证明,如果 IdentityServer 配置为使用 ASP.NET 身份库,则它不会使用 IProfileService 添加自定义声明,除非(如 ) the UserInfo endpoint get called directly. The design approach is to use ASP.NET Identity mechanism for creating the claims by registering an IUserClaimsPrincipalFactory 所述。
在这种情况下,我们可以创建 IUserClaimsPrincipalFactory 的自定义实现,或者因为 ASP.NET Identity 将加载存储在数据库中的任何其他声明,请使用 AddClaimsAsync method of UserManager 添加任何额外声明 class .
我正在尝试更改 IdentityServer4 AspNetIdentity 示例,以便能够从本地创建的用户和 Google 登录。
我可以通过添加 Google 身份验证来做到这一点:
app.UseIdentity();
app.UseIdentityServer();
var cookieScheme = app.ApplicationServices.GetRequiredService<IOptions<IdentityOptions>>().Value.Cookies.ExternalCookieAuthenticationScheme;
// Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715
app.UseGoogleAuthentication(new GoogleOptions
{
AuthenticationScheme = "Google",
SignInScheme = cookieScheme,
ClientId = "client_id",
ClientSecret = "client_secret"
});
正如预期的那样,主页视图显示了正确的用户声明:
sub
c51da331-0348-45dd-352f-08d4526f6266
name
EMAIL@gmail.com
AspNet.Identity.SecurityStamp
568a167f-a431-4f70-ba66-918f99e95eef
idp
Google
amr
external
auth_time
1486815555
当用户首次使用 Google 帐户登录时,我将一些信息添加到数据库中,我认为我可以通过使用自定义 IProfileService 实现并将 IdentityServer 配置为使用我的方法将它们添加到用户声明中自定义 IProfileService:
var builder = services.AddIdentityServer();
builder.AddTemporarySigningCredential();
builder.AddConfigurationStore(b => b.UseSqlServer(connectionString, options => options.MigrationsAssembly(migrationAssembly)));
builder.AddOperationalStore(b => b.UseSqlServer(connectionString, options => options.MigrationsAssembly(migrationAssembly)));
builder.AddAspNetIdentity<MyUser>();
builder.AddProfileService<MyCustomProfileService>();
但现在当我导航到主页时,用户声明保持不变,甚至 GetProfileDataAsync 方法也不会命中。
如果有人能告诉我这是什么,我将不胜感激。
根据 Adding Custom Claims to an ASPNET Core Identity Implementation on github, the GetProfileDataAsync
method is only called if claims need to be put in a token. Also it has a link to Optimizing Identity Tokens for size post 中的讨论解释,
默认情况下,IdentityServer 的行为符合 OpenID Connect 规范,建议如下(在第 5.4 节中):
The Claims requested by the profile, email, address, and phone scope values are returned from the UserInfo Endpoint, as described in Section 5.3.2, when a response_type value is used that results in an Access Token being issued. However, when no Access Token is issued (which is the case for the response_type value id_token), the resulting Claims are returned in the ID Token.
换句话说,如果只请求身份令牌,则将所有声明放入令牌中。但是,如果还请求访问令牌 => 从身份令牌中删除声明并让客户端使用 userinfo 端点检索它们。
但是,可以通过在客户端配置中设置 AlwaysIncludeUserClaimsInIdToken
标志来覆盖此默认行为(更多 this)。
事实证明,如果 IdentityServer 配置为使用 ASP.NET 身份库,则它不会使用 IProfileService 添加自定义声明,除非(如
在这种情况下,我们可以创建 IUserClaimsPrincipalFactory 的自定义实现,或者因为 ASP.NET Identity 将加载存储在数据库中的任何其他声明,请使用 AddClaimsAsync method of UserManager 添加任何额外声明 class .