使用OpenIdDict在ASP.Net Core 2.1中从Google索赔

时间:2018-12-18 03:37:30

标签: jwt asp.net-core-2.1 openiddict

使用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);
    }

谢谢。

1 个答案:

答案 0 :(得分:1)

您的声明目的地设置不正确。

使用带有3个参数的Claim构造函数时,实际设置的是声明值类型,而不是目的地(这是OpenIddict的特定概念)。

考虑使用以下语法:

claims.Add(new Claim(OpenIdConnectConstants.Claims.Email, User.FindFirstValue(ClaimTypes.Email)).SetDestinations(OpenIdConnectConstants.Destinations.IdentityToken));