How do I use bearer Tokens with MVC 6 API?

2019-04-09 06:49发布

问题:

I am working through some MVC 6 and ASP.NET 5 samples and I am having issues finding any worthy documentation on using bearer tokens to secure API's. I am able to make such samples work with VS 2013, MVC 5 but I am unable to port these over to VS 2015 and MVC 6. Does anyone know of any good samples of implementing bearer tokens in MVC 6 in order to secure API's?

回答1:

In order to authenticate a request using bearer tokens, you can pull down the Microsoft.AspNet.Security.OAuthBearer package. Then, you can add the OAuthBearerAuthenticationMiddleware middleware to the pipeline by using the UseOAuthBearerAuthentication extension method.

Example:

public void Configure(IApplicationBuilder app)
{

    // ...

    app.UseOAuthBearerAuthentication(options =>
    {
        options.Audience = "Redplace-With-Real-Audience-Info";
        options.Authority = "Redplace-With-Real-Authority-Info";
    });
}

Also, have a look at WebApp-WebAPI-OpenIdConnect-AspNet5 sample.



回答2:

There is no middleware in Asp.Net Core, which generates bearer token. You can create your own solution or implement some community based approaches like

  • OpenIdConnect
  • OpenIdDict
  • IdentityServer4


回答3:

I have implemented a single page application with token based authentication implementation using MVC 6, OpenId and the Aurelia front end framework. In Startup.cs, the Configure method looks like so:

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{


    app.UseIISPlatformHandler();

    // Add a new middleware validating access tokens.
    app.UseJwtBearerAuthentication(options => {
        // Automatic authentication must be enabled
        // for SignalR to receive the access token.
        options.AutomaticAuthenticate = true;

        // Automatically disable the HTTPS requirement for development scenarios.
        options.RequireHttpsMetadata = !env.IsDevelopment();

        // Note: the audience must correspond to the address of the SignalR server.
        options.Audience = clientUri;

        // Note: the authority must match the address of the identity server.
        options.Authority = serverUri;

    });

    // Add a new middleware issuing access tokens.
    app.UseOpenIdConnectServer(options => {
        options.Provider = new AuthenticationProvider();
    });

    app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear());

    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

The authentication provider is defined like so:

public class AuthenticationProvider : OpenIdConnectServerProvider
    {
        public override Task ValidateClientAuthentication(ValidateClientAuthenticationContext context)
        {
            if (context.ClientId == "AureliaNetAuthApp")
            {
                // Note: the context is marked as skipped instead of validated because the client
                // is not trusted (JavaScript applications cannot keep their credentials secret).
                context.Skipped();
            }

            else {
                // If the client_id doesn't correspond to the
                // intended identifier, reject the request.
                context.Rejected();
            }

            return Task.FromResult(0);
        }

        public override Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext context)
        {
            var user = new { Id = "users-123", Email = "alex@123.com", Password = "AureliaNetAuth" };

            if (context.UserName != user.Email || context.Password != user.Password)
            {
                context.Rejected("Invalid username or password.");

                return Task.FromResult(0);
            }

            var identity = new ClaimsIdentity(OpenIdConnectDefaults.AuthenticationScheme);
            identity.AddClaim(ClaimTypes.NameIdentifier, user.Id, "id_token token");
            identity.AddClaim(ClaimTypes.Name, user.Email, "id_token token");

            context.Validated(new ClaimsPrincipal(identity));

            return Task.FromResult(0);
        }
    }

This defines a token endpoint which can be reached at the url /connect/token.

So to request a token from the client side, here is the javascript code, taken from the AuthService in authSvc.js:

login(username, password) {
    var baseUrl = yourBaseUrl;

    var data = "client_id=" + yourAppClientId
               + "&grant_type=password"
               + "&username=" + username
               + "&password=" + password
               + "&resource=" + encodeURIComponent(baseUrl);

    return this.http.fetch(baseUrl + 'connect/token', {
        method: 'post',
        body : data
    });
}

Full source can be seen here:

https://github.com/alexandre-spieser/AureliaAspNetCoreAuth

Hope this helps,

Best,

Alex