我正在尝试使用 ASP.NET Core 1.0 为 SPA 设置 Bearer 身份验证。我几乎已经将它用于 JwtToken 与 OpenIdConnect 服务器,但有一个问题,即我的自定义声明未随 token 一起返回。
我的 Startup.cs 验证逻辑如下:
private void ConfigureAuthentication(IApplicationBuilder app)
{
app.UseJwtBearerAuthentication(options =>
{
options.AutomaticAuthenticate = true;
options.Authority = "http://localhost:53844";
options.Audience = "http://localhost:53844";
options.RequireHttpsMetadata = false;
});
app.UseOpenIdConnectServer(options =>
{
options.TokenEndpointPath = "/api/v1/token";
options.AllowInsecureHttp = true;
options.AuthorizationEndpointPath = PathString.Empty;
options.Provider = new OpenIdConnectServerProvider
{
OnValidateClientAuthentication = context =>
{
context.Skipped();
return Task.FromResult<Object>(null);
},
OnGrantResourceOwnerCredentials = async context =>
{
var usersService = app.ApplicationServices.GetService<IUsersService>();
User user = usersService.getUser(context.Username, context.Password);
var identity = new ClaimsIdentity(new List<Claim>(), OpenIdConnectServerDefaults.AuthenticationScheme);
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()));
identity.AddClaim(new Claim(ClaimTypes.Name, user.Id.ToString()));
identity.AddClaim(new Claim("myclaim", "4815162342"));
var ticket = new AuthenticationTicket(
new ClaimsPrincipal(identity),
new AuthenticationProperties(),
context.Options.AuthenticationScheme);
ticket.SetResources(new[] { "http://localhost:53844" });
ticket.SetAudiences(new [] {"http://localhost:53844"});
ticket.SetScopes(new [] {"email", "offline_access" });
context.Validated(ticket);
}
};
});
}
access_token 和 refresh_token 均已成功生成,并且在 Authorization header 系统中传递 access_token 时将请求视为已授权。
唯一的问题是除了 NameIdentifier 之外的所有声明都没有通过。
我使用以下代码来接收我对经过身份验证的请求的声明:
public class WebUserContext : IUserContext
{
private readonly IHttpContextAccessor contextAccessor;
public WebUserContext(IHttpContextAccessor contextAccessor)
{
this.contextAccessor = contextAccessor;
}
public long UserId
{
get
{
ClaimsIdentity identity = Principal?.Identity as ClaimsIdentity;
if (identity == null)
{
return -1;
}
Claim claim = identity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name); // There is no such claim in claims collection
return long.Parse(claim.Value);
}
}
private ClaimsPrincipal Principal => contextAccessor.HttpContext.User as ClaimsPrincipal;
}
我的声明未通过或未从 token 中提取的原因可能是什么?
最佳答案
What can be the reason my claims are not passed or extracted from the token?
安全。
与 OAuthAuthorizationServerMiddleware
不同,ASOS 不假设访问 token 总是由您自己的资源服务器使用(尽管我同意这是一种常见情况)并且拒绝序列化未明确指定“目的地”,以避免将 secret 数据泄露给未经授权的各方。
由于 JWT 是 ASOS beta4 (but not in the next beta) 中的默认格式,您还必须记住,即使是客户端应用程序(或用户)也可以读取您的访问 token 。
因此,您必须在您的声明中明确附加一个“目的地”:
identity.AddClaim(ClaimTypes.Name, "Pinpoint", destination: "id_token token");
指定 id_token
以在身份 token 中序列化声明,token
以在访问 token 中序列化它或同时在两个 token 中序列化它(没有等效的授权代码或刷新 token ,因为它们始终是加密的并且只能由授权服务器本身读取)
关于authentication - ASP.NET 核心 1.0。 Bearer Token,无法访问自定义声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35038158/