2017-02-20 150 views
9

我試圖創建Jwt令牌授權。爲了這個目的,我有這樣的代碼發行人部分:我Jwt令牌授權不起作用

public void ConfigureOAuth(IAppBuilder app) 
{ 
    var issuer = SiteGlobal.Issuer; 
    var audience = SiteGlobal.Audience; 
    var secret = TextEncodings.Base64Url.Decode(SiteGlobal.Secret); 
    app.UseJwtBearerAuthentication(
    new JwtBearerAuthenticationOptions 
    { 
     AuthenticationMode = AuthenticationMode.Active, 
     AllowedAudiences = new[] { audience }, 
     IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[] 
     { 
      new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret) 
     } 
    }); 
} 

至於我可以看到發出的令牌是有效的(:

public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
{ 
    context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] {"*"}); 
    Users user; 
    using (var db = new UserStore()) 
    { 
     user = Task.Run(()=> db.FindUser(context.UserName, context.Password, context.ClientId)).Result; 
    } 
    if (user == null) 
    { 
     context.SetError("invalid_grant", "The user name or password is incorrect"); 
     return Task.FromResult<object>(null); 
    } 
    var identity = new ClaimsIdentity("JWT"); 
    identity.AddClaim(new Claim(ClaimTypes.Name, user.Email)); 
    identity.AddClaim(new Claim("sub", context.UserName)); 
    identity.AddClaim(new Claim(ClaimTypes.Role, user.Roles.Name)); 

    var props = new AuthenticationProperties(new Dictionary<string, string> 
    { 
     { 
      "audience", context.ClientId ?? string.Empty 
     } 
    }); 
    var ticket = new AuthenticationTicket(identity, props); 
    context.Validated(ticket); 
    return Task.FromResult<object>(null); 
} 

和「資源」部分應該接受承載令牌在jwt.io上進行了驗證),所以問題在於別的。當我在郵遞員中發送令牌時,調用控制器受到[Authorize]屬性的保護,它總是返回401代碼。你能否建議如何解決這個問題?

P.S.這是我如何實現定製Jwt fortmat:

public string Protect(AuthenticationTicket data) 
{ 
    if (data == null) 
    { 
     throw new ArgumentNullException("data"); 
    } 
    string audienceId = data.Properties.Dictionary.ContainsKey(AudiencePropertyKey) ? data.Properties.Dictionary[AudiencePropertyKey] : null; 
    if (string.IsNullOrWhiteSpace(audienceId)) throw new InvalidOperationException("AuthenticationTicket.Properties does not include audience"); 
    Audience audience; 
    using (var store = new AudienceStore()) 
    { 
     audience = Task.Run(()=> store.FindAudience(audienceId)).Result; 
    } 
    var symmetricKeyAsBase64 = audience.Base64Secret; 
    var signingKey = new InMemorySymmetricSecurityKey(Encoding.UTF8.GetBytes(symmetricKeyAsBase64)); 
    var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.Sha256Digest); 
    var issued = data.Properties.IssuedUtc; 
    var expires = data.Properties.ExpiresUtc; 
    var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingCredentials); 
    var handler = new JwtSecurityTokenHandler(); 
    var jwt = handler.WriteToken(token); 
    return jwt; 
} 

P.S.夥計們,我很抱歉,但我忘記解釋說,「發行人」部分代碼是獨立應用程序,而「受衆」是受保護的web api。這是兩個不同的應用程序獨立運行。

+0

請問http://security.stackexchange.com/a/128882/131820有幫助嗎? – Tatranskymedved

+0

我對此不確定。頭文件有問題嗎,我會收到一些不好的請求,但不會不合理。 –

+0

我沒有使用'jwt'的exp,只通過URL通過'REST'查詢,其中請求標頭'Authorization:Basic '是需要的,如果有錯誤(pass/name/syntax)它向我扔了401。 – Tatranskymedved

回答

2

在郵遞員確保您使用以下格式發送授權頭:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ 

Postman Authorization Header

確保你離開的授權選項卡設置爲Type: No Auth

如果您仍然遇到問題,請在您的GrantResourceOwnerCredentials中設置斷點並查看是否達到該點。如果您想在事件鏈的早期進行調試,也可考慮覆蓋ValidateClientAuthentication方法OAuthAuthorizationServerProvider,該方法應在GrantResourceOwnerCredentials之前調用。

+0

郵差的Tha代碼:Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9。eyJ1bmlxdWVfbmFtZSI6ImFuZHJleS5zaGVka29AZ21haWwuY29tIiwic3ViIjoiYW5kcmV5LnNoZWRrb0BnbWFpbC5jb20iLCJyb2xlIjoiQWRtaW4iLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjUyNzk5IiwiYXVkIjoiMDk5MTUzYzI2MjUxNDliYzhlY2IzZTg1ZTAzZjAwMjIiLCJleHAiOjE0ODc3NzIxOTEsIm5iZiI6MTQ4Nzc3MDM5MX0.5GFpvU08CjaS5LTH0vRVFIGuilenkEgVu_aJLma4lPo –

+0

這是問題 - 在我沒有安裝Asp.Net身份「resorce」 API,在本教程中說的 - http://bitoftech.net/2014/10/27/json-web-token-asp-淨網頁API-2,智威湯遜 - owin授權服務器/評論頁-3 /#評論-97300。方法GrantResourceOwnerCredentials我只有「發行者」部分。 –

+0

@ andrey.shedko你沒有發佈你試圖通過郵遞員運行的內容,但401表明某些東西沒有通過你的授權。設置中斷點應允許您檢查並找到具體的故障點。如果您刪除授權屬性並通過郵遞員運行請求,它會起作用嗎? – cchamberlain

2

我剛剛嘗試運行SON Web Token in ASP.NET Web API 2 using Owin中提到的demo project,並且所有按預期工作。

我注意到您的Protect方法的實現有很大不同。我建議你將你的實現與本文給出的例子進行比較。嘗試先做好這項工作。

另請確保兩臺服務器上的頒發者,受衆和祕密相同。

如果您提供完整的源代碼,我可以嘗試調查更多。