在asp.net vnext上使用bearer token身份验证刷新令牌

时间:2016-01-24 15:14:55

标签: asp.net angularjs asp.net-core jwt aspnet-contrib

我有一个使用asp.net vnext的angularJS应用程序,它使用JwtBearerAuthentication进行身份验证。要对应用程序进行身份验证,请使用AspNet.Security.OpenIdConnect.Server。当我登录时,我收到一个json响应,其中包含我可以用于授权请求的access_token。我想,也要收到刷新令牌。这怎么可能?

Startup.cs

public void Configure(IApplicationBuilder app) {
    app.UseJwtBearerAuthentication(options => {
        options.AutomaticAuthenticate = true;
        options.AutomaticChallenge = true;
        options.TokenValidationParameters.ValidateAudience = false;
        options.Authority = Configuration.Get<string>("OAuth:Authority");
        options.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
            metadataAddress: options.Authority + ".well-known/openid-configuration",
            configRetriever: new OpenIdConnectConfigurationRetriever(),
            docRetriever: new HttpDocumentRetriever() { RequireHttps = false });
    });

    app.UseOpenIdConnectServer(configuration => {
        configuration.Issuer = new Uri(Configuration.Get<string>("OpenId:Issuer"));
        configuration.AllowInsecureHttp = true;
        configuration.AuthorizationEndpointPath = PathString.Empty;
        configuration.AuthenticationScheme = OpenIdConnectServerDefaults.AuthenticationScheme;
        configuration.Provider = new AuthorizationProvider();
    });
}

AuthorizationProvider.cs

public class AuthorizationProvider : OpenIdConnectServerProvider {
    public override Task ValidateClientAuthentication(ValidateClientAuthenticationContext context) {
        context.Skipped();

        return Task.FromResult<object>(null);
    }

    public override Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext context) {
        string username = context.UserName;
        string password = context.Password;

        UserManager<ApplicationUser> userManager = context.HttpContext.RequestServices.GetRequiredService<UserManager<ApplicationUser>>();
        ApplicationUser user = userManager.FindByNameAsync(username).Result;

        if (userManager.CheckPasswordAsync(user, password).Result) {
            ClaimsIdentity identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme);
            identity.AddClaim(ClaimTypes.Name, username, "token id_token");

            List<string> roles = userManager.GetRolesAsync(user).Result.ToList();
            foreach (string role in roles) {
                identity.AddClaim(ClaimTypes.Role, role, "token id_token");
            }

            ClaimsPrincipal principal = new ClaimsPrincipal(identity);
            context.Validated(principal);
        } else {
            context.Rejected("invalid credentials");
        }

        return Task.FromResult<object>(null);
    }
}

AngularJS登录代码

$http({
    method: 'POST',
    url: 'connect/token',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    },
    data: $.param({
        grant_type: 'password',
        username: email,
        password: password
    })
}).then(function (response) {
    if (response.status == 200) {
        var token = response.data.access_token;
        localStorage.setItem('token', token);
    }
});

2 个答案:

答案 0 :(得分:3)

offline_access不同,ASOS提供对刷新令牌的内置支持:您不必为此创建自己的令牌提供程序。

请注意,从ASOS beta3开始(2015年10月发布),您现在必须要求并授予GrantResourceOwnerCredentials范围以检索刷新令牌Apple's documentation for interacting with UnsafePointersas recommended by the OpenID Connect specs

您需要更新public override async Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext context) { string username = context.UserName; string password = context.Password; UserManager<ApplicationUser> userManager = context.HttpContext.RequestServices.GetRequiredService<UserManager<ApplicationUser>>(); ApplicationUser user = await userManager.FindByNameAsync(username); if (await userManager.CheckPasswordAsync(user, password)) { ClaimsIdentity identity = new ClaimsIdentity( context.Options.AuthenticationScheme); identity.AddClaim(ClaimTypes.Name, username, OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken); foreach (string role in await userManager.GetRolesAsync(user)) { identity.AddClaim(ClaimTypes.Role, role, OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken); } AuthenticationTicket ticket = new AuthenticationTicket( new ClaimsPrincipal(identity), new AuthenticationProperties(), context.Options.AuthenticationScheme); // Call SetResources with the list of resource servers // the access token should be issued for. ticket.SetResources("resource_server_1"); // Only grant the "offline_access" scope // if it was requested by the client application: List<string> scopes = new List<string>(); if (context.Request.HasScope("offline_access")) { scopes.Add("offline_access"); } // Call SetScopes with the list of scopes you want to grant. ticket.SetScopes(scopes); context.Validate(ticket); } else { context.Reject("invalid credentials"); } return Task.FromResult(0); } 以允许ASOS向您的客户端应用程序发出刷新令牌:

scope

...以及用于指定$http({ method: 'POST', url: 'connect/token', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }, data: $.param({ grant_type: 'password', username: email, password: password, scope: 'offline_access' }) }).then(function (response) { if (response.status == 200) { var token = response.data.access_token; var refreshToken = response.data.refresh_token; localStorage.setItem('token', token); localStorage.setItem('refresh_token', refreshToken); } }); 参数的Angular代码:

refresh_token

要检索新的访问令牌,请使用$http({ method: 'POST', url: 'connect/token', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }, data: $.param({ grant_type: 'refresh_token', refresh_token: refreshToken }) }).then(function (response) { if (response.status == 200) { var token = response.data.access_token; localStorage.setItem('token', token); } }); 授权:

let parameters:[String : AnyObject] = []

答案 1 :(得分:0)

创建刷新令牌提供程序并将其包含在您的身份验证选项中。在这里,您可以找到在类似环境中如何使用它的完整示例:

http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/