2015-01-12 41 views
16

我已經遵循教程來保護在C#中使用OAuth的Web API。返回API結束點「此請求的授權已被拒絕。」當發送持票人令牌

我正在做一些測試,到目前爲止我已經能夠從/token成功獲取訪問令牌。我使用名爲「高級REST客戶端」的Chrome擴展程序對其進行測試。

{"access_token":"...","token_type":"bearer","expires_in":86399} 

這就是我從/token得到的結果。一切看起來不錯。

我的下一個請求,就是我的測試API控制器:

namespace API.Controllers 
{ 
    [Authorize] 
    [RoutePrefix("api/Social")] 
    public class SocialController : ApiController 
    { 
     .... 


     [HttpPost] 
     public IHttpActionResult Schedule(SocialPost post) 
     { 
      var test = HttpContext.Current.GetOwinContext().Authentication.User; 

      .... 
      return Ok(); 
     } 
    } 
} 

的請求是POST並有標題:

Authorization: Bearer XXXXXXXTOKEHEREXXXXXXX 

我得到:在JSON返回Authorization has been denied for this request.

我試着做一個GET,我得到了我所期望的,該方法不支持,因爲我沒有實現它。

這裏是我的授權提供:

public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider 
{ 
    public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 
    { 
     context.Validated(); 
    } 

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
    { 

     context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); 

     using (var repo = new AuthRepository()) 
     { 
      IdentityUser user = await repo.FindUser(context.UserName, context.Password); 

      if (user == null) 
      { 
       context.SetError("invalid_grant", "The user name or password is incorrect."); 
       return; 
      } 
     } 

     var identity = new ClaimsIdentity(context.Options.AuthenticationType); 
     identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName)); 
     identity.AddClaim(new Claim(ClaimTypes.Role, "User")); 

     context.Validated(identity); 

    } 
} 

任何幫助將是巨大的。我不確定它是否是錯誤的請求或代碼。

編輯: 這是我Startup.cs

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     var config = new HttpConfiguration(); 
     WebApiConfig.Register(config); 
     app.UseWebApi(config); 
     ConfigureOAuth(app); 
    } 

    public void ConfigureOAuth(IAppBuilder app) 
    { 
     var oAuthServerOptions = new OAuthAuthorizationServerOptions() 
     { 
      AllowInsecureHttp = true, 
      TokenEndpointPath = new PathString("/token"), 
      AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), 
      Provider = new SimpleAuthorizationServerProvider() 
     }; 

     // Token Generation 
     app.UseOAuthAuthorizationServer(oAuthServerOptions); 
     app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); 

    } 
} 

回答

27

問題很簡單:你的OWIN管道的 修改訂單。

public void Configuration(IAppBuilder app) 
{ 
    ConfigureOAuth(app); 
    var config = new HttpConfiguration(); 
    WebApiConfig.Register(config); 
    app.UseWebApi(config); 
} 

對於您的配置OWIN管道順序相當重要。在你的情況下,你嘗試在OAuth處理程序之前使用你的Web API處理程序。在它內部,您驗證了您的請求,發現您採取了安全措施,並嘗試使用當前的Owin.Context.User進行驗證。此時此用戶不存在,因爲它使用稍後調用的OAuth處理程序的令牌進行設置。

+0

如果你沒有註冊WebApi,你將如何做到這一點?我只是使用默認的Web API模板。 GET請求正常工作,POST請求給我401.雖然令牌是相同的。 – mwijnands

+1

這讓我抓不住!感謝您花時間發佈此答案。 – heymega

+0

重構後幾小時,我試圖找出這個問題的原因。 – Tomino

2

您必須添加一個要求用這個模式:

http://schemas.microsoft.com/ws/2008/06/identity/claims/role 

最好的辦法是使用預先定義的組聲明:

identity.AddClaim(new Claim(ClaimTypes.Role, "User")); 

您可以在找到ClaimTypes 10。

你必須要考慮的另一件事是過濾器的角色在你的控制器/行動:

[Authorize(Roles="User")] 

你可以找到一個簡單的示例應用程序,自託管owin有一個jQuery客戶here

+0

我加了:'identity.AddClaim(new Claim(ClaimTypes.Role,「User」));'無濟於事。用戶是否有資本是否重要?我在看到您的評論之前添加了此內容。我不認爲這很重要。我會檢查你的鏈接。 –

+0

這是一個常數,可以是任何東西。 – LeftyX

+0

我試着改變'[Authorize]'將角色包含在我的控制器中,但我仍然沒有得到授權。我在角色「用戶」中創建了一個新用戶,併成功獲得了新的令牌。根據您的建議更改更新我的代碼。 –

0

看起來像「System.IdentityModel.Tokens.Jwt」與其他Owin組件共存的版本不正確。

如果您使用的是「Microsoft.Owin.Security.Jwt」2.1.0版本,則應該使用版本3.0.2的「System.IdentityModel.Tokens.Jwt」程序集。

從包管理器控制檯,嘗試:

Update-Package System.IdentityModel.Tokens.Jwt -Version 3.0.2 
相關問題