在 asp.net vnext 上使用不记名令牌身份验证刷新令牌
Posted
技术标签:
【中文标题】在 asp.net vnext 上使用不记名令牌身份验证刷新令牌【英文标题】:refresh token with bearer token authentication on asp.net vnext 【发布时间】:2016-04-30 20:48:21 【问题描述】:我有一个使用 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);
);
【问题讨论】:
附带说明,您不应禁用受众验证 (options.TokenValidationParameters.ValidateAudience = false
)。相反,请考虑使用ticket.SetResources(new[] "resource_server_1" )
在访问令牌中设置正确的受众并在您的 JWT 不记名中间件选项中进行配置:options.Audience = "resource_server_1"
。
你让我免于问另一个问题。我会试试看。谢谢
【参考方案1】:
创建您的刷新令牌提供程序并将其包含到您的身份验证选项中。在这里您可以找到在类似环境中如何使用它的完整示例:
http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/
【讨论】:
【参考方案2】:与OAuthAuthorizationServerMiddleware
不同,ASOS 提供了对刷新令牌的内置支持:您不必为此创建自己的令牌提供程序。
请注意,从 ASOS beta3(2015 年 10 月发布)开始,您现在必须请求并授予 offline_access
范围以检索刷新令牌,as recommended by the OpenID Connect specs:https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/issues/128
您需要更新您的 GrantResourceOwnerCredentials
以允许 ASOS 向您的客户端应用程序发出刷新令牌:
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);
...和你的Angular代码来指定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);
);
要检索新的访问令牌,请使用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);
);
【讨论】:
是否有任何关于在 EF 上持久化刷新令牌的示例? 已更新以匹配 ASOS beta5 中使用的新名称(适用于 ASP.NET Core RC2)。以上是关于在 asp.net vnext 上使用不记名令牌身份验证刷新令牌的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Asp .Net Core SignalR Hub 中获取不记名令牌?
Asp.net core 2 - 不记名令牌出现 401 错误
不记名令牌出现 401 错误 - asp.net core 3.1
ASP.NET Core API 使用 JWT 不记名令牌进行身份验证