[英]Cannot validate token in UseJwtBearerAuthentication. Authorization has been denied
Using a single asp.net(4.6.1) web project, apparently I'm unable to validate the jwt token that was generated on the same server. 使用单个asp.net(4.6.1)Web项目,显然我无法验证在同一服务器上生成的jwt令牌。
Startup.cs : Startup.cs :
var secret = Encoding.UTF8.GetBytes("12341234123412341234");
var jwtFormatter = new CustomJwtFormat("Any", "local", secret);
// This part checks the tokens
app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ExternalBearer,
AuthenticationMode = AuthenticationMode.Active, // Block requests
AllowedAudiences = new []{"Any"},
TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey = new InMemorySymmetricSecurityKey(secret),
ValidAudience = "Any",
ValidIssuer = "local"
}
});
// This part issues tokens
app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = false,
TokenEndpointPath = new PathString("/auth"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = new CustomOAuthProvider(),
AccessTokenFormat = jwtFormatter,
RefreshTokenFormat = jwtFormatter
});
app.UseWebApi(config);
The class that generates the tokens looks like 生成令牌的类看起来像
public class CustomJwtFormat : ISecureDataFormat<AuthenticationTicket>
{
private readonly string _allowedAudience;
private readonly string _issuer;
private readonly byte[] _jwtTokenSignKey;
public CustomJwtFormat(string allowedAudience, string issuer, byte[] jwtTokenSignKey)
{
_allowedAudience = allowedAudience;
_issuer = issuer;
_jwtTokenSignKey = jwtTokenSignKey;
}
public string Protect(AuthenticationTicket data)
{
if (data == null) throw new ArgumentNullException(nameof(data));
var signingCredentials = new SigningCredentials
(
new InMemorySymmetricSecurityKey(_jwtTokenSignKey),
"http://www.w3.org/2001/04/xmldsig-more#hmac-sha256",
"http://www.w3.org/2001/04/xmlenc#sha256"
);
return new JwtSecurityTokenHandler().WriteToken(new JwtSecurityToken(
_issuer,
_allowedAudience,
data.Identity.Claims,
DateTime.UtcNow, DateTime.UtcNow.AddMinutes(10),
signingCredentials
));
}
public AuthenticationTicket Unprotect(string protectedText)
{
throw new NotImplementedException();
}
}
The tokens I receive from /auth
look valid and pass the debugger on jwt.io
(without marking base64 for signature) image http://image.prntscr.com/image/cc16a2705c67494fa09f9df6850d7c54.png 我从/auth
收到的令牌看起来有效并在jwt.io
上传递调试器(没有标记base64用于签名) 图像http://image.prntscr.com/image/cc16a2705c67494fa09f9df6850d7c54.png
However UseJwtBearerAuthentication
refuses to validate the token. 但是, UseJwtBearerAuthentication
拒绝验证令牌。 image http://image.prntscr.com/image/f0bbe31829fa47e98ddbd03fc22e86b5.png 图片http://image.prntscr.com/image/f0bbe31829fa47e98ddbd03fc22e86b5.png
What could be the possible reason for this ? 可能的原因是什么?
Moreover, I've tried manually validating the same token in a controller without [Authorize]
and it would perfectly validate: 此外,我尝试在没有[Authorize]
情况下手动验证控制器中的相同令牌,它将完美地验证:
var t = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEiLCJpc3MiOiJsb2NhbCIsImF1ZCI6IkFueSIsImV4cCI6MTQ3MjkxMDcwMSwibmJmIjoxNDcyOTEwMTAxfQ.ipSrRSGmje7wfzERsd-M1IDFJnN99AIC4Hs7YX4FIeI";
var TokenHandler = new JwtSecurityTokenHandler();;
var key = Encoding.UTF8.GetBytes("12341234123412341234");
SecurityToken validatedToken;
TokenValidationParameters paras = new TokenValidationParameters()
{
IssuerSigningKey = new InMemorySymmetricSecurityKey(key),
ValidAudience = "Any",
ValidIssuer = "local"
};
TokenHandler.ValidateToken(t, paras, out validatedToken);
Owin 3.0.1.0 System.IdentityModel.Tokens.Jwt 4.0.3.308261200 Owin 3.0.1.0 System.IdentityModel.Tokens.Jwt 4.0.3.308261200
The problem wasn't in the token validation, but rather the that the claims were not passed on to Thread.CurrentPrincipal
that the [Authorize]
attribute was reading from. 问题不在于令牌验证,而是声明没有传递给[Authorize]
属性正在读取的Thread.CurrentPrincipal
。
In webapi config: 在webapi配置中:
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(DefaultAuthenticationTypes.ExternalBearer));
In startup config: 在启动配置中:
app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
AuthenticationType = DefaultAuthenticationTypes.ExternalBearer,
...
});
app.UseJwtBearerAuthentication1(new JwtBearerAuthenticationOptions()
{
AuthenticationType = DefaultAuthenticationTypes.ExternalBearer,
..
});
In GrantResourceOwnerCredentials
of the OAuthAuthorizationServerProvider: 在GrantResourceOwnerCredentials
的GrantResourceOwnerCredentials中:
use the same authentication type, which you can read from context.Options
使用相同的身份验证类型,您可以从context.Options
读取
var identity = new ClaimsIdentity(youClaimsList, context.Options.AuthenticationType);
context.Validated(identity);
And ensure all four places have the same string as AuthenticationType. 并确保所有四个地方都具有与AuthenticationType相同的字符串。 If the HostAuthenticationFilter
will have a different authenticationType
as input, it will not pass on the claims from owin to webapi. 如果HostAuthenticationFilter
将具有不同的authenticationType
作为输入,则它不会将owin的声明传递给webapi。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.