問題描述
使用單個(gè) asp.net(4.6.1) Web 項(xiàng)目,顯然我無法驗(yàn)證在同一服務(wù)器上生成的 jwt 令牌.
Startup.cs:
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.
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);
生成令牌的類看起來像
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();
}
}
我從 /auth
收到的令牌看起來有效,并在 jwt.io
上通過調(diào)試器(沒有標(biāo)記 base64 進(jìn)行簽名)
The tokens I receive from /auth
look valid and pass the debugger on jwt.io
(without marking base64 for signature)
但是 UseJwtBearerAuthentication
拒絕驗(yàn)證令牌.
However UseJwtBearerAuthentication
refuses to validate the token.
這可能是什么原因?
此外,我嘗試在沒有 [Authorize]
的情況下手動(dòng)驗(yàn)證控制器中的相同令牌,它會(huì)完美驗(yàn)證:
Moreover, I've tried manually validating the same token in a controller without [Authorize]
and it would perfectly validate:
<代碼>變種T =" eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEiLCJpc3MiOiJsb2NhbCIsImF1ZCI6IkFueSIsImV4cCI6MTQ3MjkxMDcwMSwibmJmIjoxNDcyOTEwMTAxfQ.ipSrRSGmje7wfzERsd-M1IDFJnN99AIC4Hs7YX4FIeI英寸;var TokenHandler = new JwtSecurityTokenHandler();;var key = Encoding.UTF8.GetBytes("12341234123412341234");SecurityToken 驗(yàn)證令牌;TokenValidationParameters paras = new TokenValidationParameters(){IssuerSigningKey = new InMemorySymmetricSecurityKey(key),ValidAudience =任何",ValidIssuer =本地"};TokenHandler.ValidateToken(t, paras, out validToken);
歐文 3.0.1.0System.IdentityModel.Tokens.Jwt 4.0.3.308261200
Owin 3.0.1.0 System.IdentityModel.Tokens.Jwt 4.0.3.308261200
推薦答案
問題不在于令牌驗(yàn)證,而在于聲明沒有傳遞給 Thread.CurrentPrincipal
[Authorize]
屬性正在讀取.
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.
在 webapi 配置中:
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(DefaultAuthenticationTypes.ExternalBearer));
在啟動(dòng)配置中:
app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
AuthenticationType = DefaultAuthenticationTypes.ExternalBearer,
...
});
app.UseJwtBearerAuthentication1(new JwtBearerAuthenticationOptions()
{
AuthenticationType = DefaultAuthenticationTypes.ExternalBearer,
..
});
在 OAuthAuthorizationServerProvider 的 GrantResourceOwnerCredentials
中:
使用相同的身份驗(yàn)證類型,您可以從 context.Options
var identity = new ClaimsIdentity(youClaimsList, context.Options.AuthenticationType);
context.Validated(identity);
并確保所有 四個(gè) 位置都具有與 AuthenticationType 相同的字符串.如果 HostAuthenticationFilter
將具有不同的 authenticationType
作為輸入,它不會(huì)將聲明從 owin 傳遞到 webapi.
And ensure all four places have the same string as AuthenticationType.
If the HostAuthenticationFilter
will have a different authenticationType
as input, it will not pass on the claims from owin to webapi.
這篇關(guān)于無法驗(yàn)證 UseJwtBearerAuthentication 中的令牌.授權(quán)被拒絕的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!