Token Based Authentication in ASP.NET Core (refreshed)

前端 未结 5 673
隐瞒了意图╮
隐瞒了意图╮ 2020-11-27 09:47

I\'m working with ASP.NET Core application. I\'m trying to implement Token Based Authentication but can not figure out how to use new Security System.

My sce

5条回答
  •  误落风尘
    2020-11-27 10:19

    To achieve what you describe, you'll need both an OAuth2/OpenID Connect authorization server and a middleware validating access tokens for your API. Katana used to offer an OAuthAuthorizationServerMiddleware, but it doesn't exist anymore in ASP.NET Core.

    I suggest having a look to AspNet.Security.OpenIdConnect.Server, an experimental fork of the OAuth2 authorization server middleware which is used by the tutorial you mentioned: there's an OWIN/Katana 3 version, and an ASP.NET Core version that supports both net451 (.NET Desktop) and netstandard1.4 (compatible with .NET Core).

    https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server

    Don't miss the MVC Core sample that shows how to configure an OpenID Connect authorization server using AspNet.Security.OpenIdConnect.Server and how to validate the encrypted access tokens issued by the server middleware: https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/blob/dev/samples/Mvc/Mvc.Server/Startup.cs

    You can also read this blog post, that explains how to implement the resource owner password grant, which is the OAuth2 equivalent of basic authentication: http://kevinchalet.com/2016/07/13/creating-your-own-openid-connect-server-with-asos-implementing-the-resource-owner-password-credentials-grant/

    Startup.cs

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication();
        }
    
        public void Configure(IApplicationBuilder app)
        {
            // Add a new middleware validating the encrypted
            // access tokens issued by the OIDC server.
            app.UseOAuthValidation();
    
            // Add a new middleware issuing tokens.
            app.UseOpenIdConnectServer(options =>
            {
                options.TokenEndpointPath = "/connect/token";
    
                // Override OnValidateTokenRequest to skip client authentication.
                options.Provider.OnValidateTokenRequest = context =>
                {
                    // Reject the token requests that don't use
                    // grant_type=password or grant_type=refresh_token.
                    if (!context.Request.IsPasswordGrantType() &&
                        !context.Request.IsRefreshTokenGrantType())
                    {
                        context.Reject(
                            error: OpenIdConnectConstants.Errors.UnsupportedGrantType,
                            description: "Only grant_type=password and refresh_token " +
                                         "requests are accepted by this 
                        return Task.FromResult(0);
                    }
    
                    // Since there's only one application and since it's a public client
                    // (i.e a client that cannot keep its credentials private),
                    // call Skip() to inform the server the request should be
                    // accepted without enforcing client authentication.
                    context.Skip();
    
                    return Task.FromResult(0);
                };
    
                // Override OnHandleTokenRequest to support
                // grant_type=password token requests.
                options.Provider.OnHandleTokenRequest = context =>
                {
                    // Only handle grant_type=password token requests and let the
                    // OpenID Connect server middleware handle the other grant types.
                    if (context.Request.IsPasswordGrantType())
                    {
                        // Do your credentials validation here.
                        // Note: you can call Reject() with a message
                        // to indicate that authentication failed.
    
                        var identity = new ClaimsIdentity(context.Options.AuthenticationScheme);
                        identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "[unique id]");
    
                        // By default, claims are not serialized
                        // in the access and identity tokens.
                        // Use the overload taking a "destinations"
                        // parameter to make sure your claims
                        // are correctly inserted in the appropriate tokens.
                        identity.AddClaim("urn:customclaim", "value",
                            OpenIdConnectConstants.Destinations.AccessToken,
                            OpenIdConnectConstants.Destinations.IdentityToken);
    
                        var ticket = new AuthenticationTicket(
                            new ClaimsPrincipal(identity),
                            new AuthenticationProperties(),
                            context.Options.AuthenticationScheme);
    
                        // Call SetScopes with the list of scopes you want to grant
                        // (specify offline_access to issue a refresh token).
                        ticket.SetScopes("profile", "offline_access");
    
                        context.Validate(ticket);
                    }
    
                    return Task.FromResult(0);
                };
            });
        }
    }
    

    project.json

    {
      "dependencies": {
        "AspNet.Security.OAuth.Validation": "1.0.0",
        "AspNet.Security.OpenIdConnect.Server": "1.0.0"
      }
    }
    

    Good luck!

提交回复
热议问题