我试图通过使用AspNew.Security.OpenIdConnect.Server来发布令牌并使用Microsoft.AspNetCore.Authentication.JwtBearer进行验证,试图让一个简单的端点正常工作并使用JWT令牌。
我可以生成令牌,但尝试验证令牌失败,错误为Bearer was not authenticated. Failure message: No SecurityTokenValidator available for token: {token}
此时我已将所有内容剥离并具有以下内容:
project.json
{
"dependencies": {
"Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-final",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-rc2-final",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0-rc2-final",
"Microsoft.Extensions.Configuration.Json": "1.0.0-rc2-final",
"Microsoft.Extensions.Logging": "1.0.0-rc2-final",
"Microsoft.Extensions.Logging.Console": "1.0.0-rc2-final",
"Microsoft.Extensions.Logging.Debug": "1.0.0-rc2-final",
"AspNet.Security.OAuth.Validation": "1.0.0-alpha1-final",
"AspNet.Security.OpenIdConnect.Server": "1.0.0-beta5-final",
"Microsoft.AspNetCore.Authentication": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Authentication.JwtBearer": "1.0.0-rc2-final"
},
"tools": {
"Microsoft.AspNetCore.Server.IISIntegration.Tools": {
"version": "1.0.0-preview1-final",
"imports": "portable-net45+win8+dnxcore50"
}
},
"frameworks": {
"net461": { }
},
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"publishOptions": {
"include": [
"wwwroot",
"Views",
"appsettings.json",
"web.config"
]
},
"scripts": {
"postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
}
}
Startup.cs方法:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy(JwtBearerDefaults.AuthenticationScheme,
builder =>
{
builder.
AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).
RequireAuthenticatedUser().
Build();
}
);
}
);
services.AddAuthentication();
services.AddDistributedMemoryCache();
services.AddMvc();
services.AddOptions();
}
// 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)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
var jwtOptions = new JwtBearerOptions()
{
AuthenticationScheme = JwtBearerDefaults.AuthenticationScheme,
AutomaticAuthenticate = true,
Authority = "http://localhost:5000/",
Audience = "http://localhost:5000/",
RequireHttpsMetadata = false
};
jwtOptions.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>
(
metadataAddress: jwtOptions.Authority + ".well-known/openid-configuration",
configRetriever: new OpenIdConnectConfigurationRetriever(),
docRetriever: new HttpDocumentRetriever { RequireHttps = false }
);
app.UseJwtBearerAuthentication(jwtOptions);
app.UseOpenIdConnectServer(options =>
{
options.AllowInsecureHttp = true;
options.AuthorizationEndpointPath = Microsoft.AspNetCore.Http.PathString.Empty;
options.Provider = new OpenIdConnectServerProvider
{
OnValidateTokenRequest = context =>
{
context.Skip();
return Task.FromResult(0);
},
OnGrantResourceOwnerCredentials = context =>
{
var identity = new ClaimsIdentity(context.Options.AuthenticationScheme);
identity.AddClaim(ClaimTypes.NameIdentifier, "[unique id]");
identity.AddClaim("urn:customclaim", "value", OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken);
var ticket = new AuthenticationTicket(
new ClaimsPrincipal(identity),
new Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties(),
context.Options.AuthenticationScheme);
ticket.SetScopes("profile", "offline_access");
context.Validate(ticket);
return Task.FromResult(0);
}
};
});
app.UseMvc();
}
使用grant_type = password,username = foo,password = bar将x-url编码的POST发送到http://localhost:5000,生成预期的access_token。
我已将[Authorize("Bearer")]
属性添加到ValuesController,这在调用JwtBearerMiddlewear时按预期工作,但我无法获取令牌进行验证。
有没有人使用.net核心RC2?我在RC1上做了同样的事情,但一直无法做到这一点。
感谢。
答案 0 :(得分:11)
从beta5开始(对于ASP.NET Core RC2),the OpenID Connect server middleware no longer uses JWT as the default format for access tokens。相反,它使用不透明的令牌,由坚如磐石的ASP.NET核心数据保护堆栈加密(与身份验证cookie完全相同)。
您有3个选项可以修复您看到的错误:
AspNet.Security.OAuth.Validation
中的project.json
引用,并将app.UseJwtBearerAuthentication(...)
替换为app.UseOAuthValidation()
。您也可以从Microsoft.AspNetCore.Authentication.JwtBearer
删除project.json
。options.AccessTokenHandler = new JwtSecurityTokenHandler();
强制OpenID Connect服务器中间件使用JWT令牌。请注意,您还必须致电ticket.SetResources(...)
以将适当的受众群体附加到JWT令牌(有关详情,请参阅此SO post)。ValidateIntrospectionRequest
事件来验证客户端凭据。只有在你知道自己在做什么的情况下才能使用它。答案 1 :(得分:0)
旁注,如果有人有同样的错误(没有可用于令牌的 SecurityTokenValidator):
仔细检查客户端发送的认证头是否真的格式正确:
Authorize: Bearer [ey....]
No SecurityTokenValidator available for token 错误表示没有为请求中找到的授权标头格式注册处理程序。例如,如果收到的请求包含标头值“Bearer Bearer ey82383...”,或者“Bearer”关键字被省略或拼写错误,则会出现此错误。