使用OpenIdDict在ASP.Net Core 2.1 Web API中从Google索赔时遇到了麻烦。
由于我对自己存储用户名/密码没有兴趣,因此我在ASP.Net MVC模板中选择了“不进行身份验证”。我将依靠外部提供商(例如Google)进行身份验证。客户端是SPA,所以我使用的是隐式流程。
我的代码基于本教程(使用Google而不是GitHub除外): https://www.jerriepelser.com/blog/implementing-openiddict-authorization-server-part-2/
从Google返回了令牌-但是,当我检查JWT时,它不包含任何索赔信息。 我想念什么?
我的Startup.cs如下:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Register OpenIdDict database (EF Core)
services.AddDbContext<PD.Server.DataAccess.AuthorizationDbContext>(o =>
{
o.UseSqlServer(Configuration.GetConnectionString("AuthorizationDbContext"));
o.UseOpenIddict();
});
// Authentication
services.AddAuthentication(auth =>
{
auth.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
auth.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
auth.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie()
.AddGoogle(o =>
{
o.ClientId = Configuration["Authentication:Google:ClientId";
o.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
o.CallbackPath = "/signin-google";
});
services.AddOpenIddict()
.AddCore(o => o.UseEntityFrameworkCore().UseDbContext<AuthorizationDbContext>() )
.AddServer(o =>
{
o.UseMvc(); // Register MVC Binder
o.EnableAuthorizationEndpoint("/connect/authorize")
.EnableLogoutEndpoint("/connect/logout"); // Enable the Authorization end-point
o.RegisterScopes(OpenIddictConstants.Scopes.Email,
OpenIddictConstants.Scopes.Profile,
OpenIddictConstants.Scopes.Roles);
o.AllowImplicitFlow(); // Enable Implicit Flow (i.e. OAuth2 authentication for SPA's)
o.EnableRequestCaching();
o.DisableHttpsRequirement(); // DEV ONLY!
o.AddEphemeralSigningKey(); // DEV ONLY!
})
.AddValidation();
// Cors
services.AddCors();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors(builder =>
{
builder.WithOrigins("https://localhost:5001");
builder.WithMethods("GET");
builder.WithHeaders("Authorization");
});
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
app.MigrateDatabase();
// Configure the OpenIdDict Database (not shown)
InitializeAsync(app.ApplicationServices, CancellationToken.None).GetAwaiter().GetResult();
}
我的身份验证方法:
[HttpGet("~/connect/authorize")]
public IActionResult Authorize(OpenIdConnectRequest request)
{
if (!User.Identity.IsAuthenticated) return Challenge("Google");
var claims = new List<Claim>();
claims.Add(new Claim(OpenIdConnectConstants.Claims.Subject, User.FindFirstValue(ClaimTypes.NameIdentifier), OpenIdConnectConstants.Destinations.IdentityToken));
claims.Add(new Claim(OpenIdConnectConstants.Claims.Name, User.FindFirstValue(ClaimTypes.Name), OpenIdConnectConstants.Destinations.IdentityToken));
claims.Add(new Claim(OpenIdConnectConstants.Claims.Email, User.FindFirstValue(ClaimTypes.Email), OpenIdConnectConstants.Destinations.IdentityToken));
claims.Add(new Claim(OpenIdConnectConstants.Claims.EmailVerified, "true", OpenIdConnectConstants.Destinations.IdentityToken));
var identity = new ClaimsIdentity(claims, "OpenIddict");
var principle = new ClaimsPrincipal(identity);
// Create a new Authentication Ticket
var ticket = new AuthenticationTicket(principle, new AuthenticationProperties(), OpenIdConnectServerDefaults.AuthenticationScheme);
return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme);
}
谢谢。
答案 0 :(得分:1)
您的声明目的地设置不正确。
使用带有3个参数的Claim
构造函数时,实际设置的是声明值类型,而不是目的地(这是OpenIddict的特定概念)。
考虑使用以下语法:
claims.Add(new Claim(OpenIdConnectConstants.Claims.Email, User.FindFirstValue(ClaimTypes.Email)).SetDestinations(OpenIdConnectConstants.Destinations.IdentityToken));