2017-06-06 104 views
1

我將基於令牌的身份驗證添加到我的OWIN中間件,並可以生成令牌。但是在使用時,帶有Authorize屬性的API調用令牌總是會得到「授權已被拒絕。」雖然沒有Authorize屬性,但它工作正常。這是我的startup.cs和控制器方法。任何想法,有什麼不對?「消息」:「此請求的授權已被拒絕。」 OWIN中間件

startup.cs

public void Configuration(IAppBuilder app) 
      { 
       var issuer = ConfigurationManager.AppSettings["issuer"]; 
       var secret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["secret"]); 
       app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions 
       { 
        AuthenticationType = DefaultAuthenticationTypes.ExternalBearer, 
        AllowInsecureHttp = true, 
        TokenEndpointPath = new PathString("/token"), 
        AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30), 
        Provider = new SimpleAuthProvider(), 
        AccessTokenFormat = new JwtFormat(issuer) 
       }); 
       app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions 
       { 
        AuthenticationType = DefaultAuthenticationTypes.ExternalBearer, 
        AuthenticationMode = AuthenticationMode.Active, 
        AllowedAudiences = new[] { "*" }, 
        IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[] 
        { 
         new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret) 
        } 
       }); 
       container = BuildDI(); 
       var config = new HttpConfiguration(); 
       config.Formatters.XmlFormatter.UseXmlSerializer = true; 
       config.MapHttpAttributeRoutes(); 
       config.SuppressDefaultHostAuthentication(); 
       config.Filters.Add(new HostAuthenticationFilter(DefaultAuthenticationTypes.ExternalBearer)); 
       config.DependencyResolver = new AutofacWebApiDependencyResolver(container); 
       app.UseCors(CorsOptions.AllowAll); 
       app.UseSerilogRequestContext("RequestId"); 
       app.UseAutofacMiddleware(container); 
       app.UseAutofacWebApi(config); 
       app.UseWebApi(config); 
       RegisterShutdownCallback(app, container); 
      } 

public class SimpleAuthProvider: OAuthAuthorizationServerProvider 
     { 
      public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
      { 

       if (context.UserName != context.Password) 
       { 
        context.SetError("invalid_grant", "The user name or password is incorrect"); 
        context.Rejected(); 
        return Task.FromResult<object>(null); 
       } 

       var ticket = new AuthenticationTicket(SetClaimsIdentity(context), new AuthenticationProperties()); 
       context.Validated(ticket); 

       return Task.FromResult<object>(null); 
      } 

      public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 
      { 
       context.Validated(); 
       return Task.FromResult<object>(null); 
      } 

      private static ClaimsIdentity SetClaimsIdentity(OAuthGrantResourceOwnerCredentialsContext context) 
      { 
       var identity = new ClaimsIdentity(DefaultAuthenticationTypes.ExternalBearer); 
       identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName)); 
       return identity; 
      } 
     } 

API控制器的方法:

[HttpGet] 
     [Route("sampleroute")] 
     [Authorize] 
     public async Task<HttpResponseMessage> GetSamples(string search) 
     { 
      try 
      { 

       HttpResponseMessage response; 
       using (HttpClient client = new HttpClient(Common.CreateHttpClientHandler())) 
       { 
        response = await client.GetAsync("test url"); 
       } 
       var result = response.Content.ReadAsStringAsync().Result; 
       Samples[] sampleArray = JsonConvert.DeserializeObject<Samples[]>(result); 
       var filteredSamples = sampleArray .ToList().Where(y => y.NY_SampleName.ToUpper().Contains(search.ToUpper())).Select(n=>n); 
       log.Information("<==========Ended==========>"); 
       return Request.CreateResponse(HttpStatusCode.OK,filteredSamples); 

      } 
      catch (Exception ex) 
      { 
       log.Error($"Error occured while pulling the Samples: {ex.ToString()}"); 
       return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.ToString()); 
      } 
     } 
+0

只是爲了確定。在授權屬性中是否包含令牌和持有者? I.E.授權:持票人「令牌」 – allencage

+0

@allencage不,我沒有。我怎麼做? – user3154990

+0

@RuardvanElburg我在郵遞員測試...我通過調用localhost/api/token獲取令牌,並將它用於具有Authorize屬性的API調用。 lcoalhost/api是我的主機網址。 – user3154990

回答

1

這可能是允許的觀衆的問題。 此處

app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions 
{ 
    ...  
    AllowedAudiences = new[] { "*" }, 
    ... 
} 

您設置允許的受衆羣體。將根據AllowedAudiences列表檢查令牌aud索賠。但是你絕不會將任何觀衆添加到令牌中。

在我們的項目我使用的CustomJwtFormat基於在http://bitoftech.net/2014/10/27/json-web-token-asp-net-web-api-2-jwt-owin-authorization-server/

令牌示出將與呼叫生成的代碼來

var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey); 

第二個參數是負責在JWT的aud權利要求:

https://msdn.microsoft.com/en-us/library/dn451037(v=vs.114).aspx

受衆 類型:System.String

如果此值不爲空,則會添加{aud,'audience'}聲明。

在令牌授權中設置aud聲明之後應該可以正常工作。

+0

感謝隊友,我在創建導致問題的令牌時傳遞null給觀衆。 – user3154990

+0

很高興幫助:) – jps

1

從我的理解,你需要添加標題:授權:承載 「令牌」。 如果您還沒有修改的授權請求的默認實現的步驟是這些:

/api/Account/Register 
  • 郵政/令牌以下項目:
      在端點

      1. 註冊用戶

      2. grant_type:密碼
      3. 用戶名:「您註冊的用戶名」
      4. 密碼:
  • 您將收到一個令牌響應
  • 複製該令牌,並創建一個請求給您類型的[授權]過濾器固定的方法:「在你的用戶註冊的密碼」 :

    Authorization: Bearer "the_token_you_copied_earlier" 
    

    不用說,這可能是很容易爲你,如果你使用的郵遞員或提琴手發出和接收請求,因爲它顯示了你的一切是如何工作的。

  • +0

    @allenceage我在這裏發佈之前完全相同的方式,並用盡了想法。 :) – user3154990

    +0

    @ user3154990我的解決方案適用於開箱即用的OAuth,從我在代碼中看到的未使用默認實現的方式工作。如果您嘗試構建的授權不是強制性的,請嘗試默認方法。 – allencage

    相關問題