2014-09-04 190 views
19

我使用OWIN中間件在ASP.NET Web API上實現了一個令牌授權系統。我成功地可以使用REST客戶端進行身份驗證並獲取授權令牌來調用API。如果我將[Authorize]屬性放在我的控制器的GET操作中,它也可以正常工作。如果我沒有有效的令牌,它將使用401消息拒絕資源,但如果我使用[Authorize(Roles="admins")]roles參數,則它不會識別用戶的角色。我驗證了數據庫中的內容,並檢查了usersinroles被正確填充。授權角色WebAPI oauth owin

這是一個代碼片段:

[Authorize(Roles = "admins")] 
public IEnumerable<CompanyModel> Get() 
{ 
    ClaimsPrincipal principal = Request.GetRequestContext().Principal as ClaimsPrincipal; 
    bool isrole = principal.IsInRole("admins"); 

我還檢查動作不roles參數和isrole布爾總是false。我必須啓用某些功能嗎?

回答

39

您必須GrantResourceOwnerCredentials添加方法:

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

一步

在StartUp.cs類步驟,你應該有一個自定義提供,欲行

Provider = new CustomAuthorizationServerProvider() 

例如:

public void ConfigureOAuth(IAppBuilder app) 
{ 
    OAuthAuthorizationServerOptions oAuthServerOptions = new OAuthAuthorizationServerOptions 
    { 
     AllowInsecureHttp = true, 
     TokenEndpointPath = new PathString("/token"), 
     AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30), 
     Provider = new CustomAuthorizationServerProvider() 
    }; 

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

然後,你CustomAuthorizationServerProvider從OAuthAuthorizationServerProvider類繼承將覆蓋GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext上下文)

然後,檢查用戶是否具有正確的用戶名和密碼後,您必須添加

var identity = new ClaimsIdentity(context.Options.AuthenticationType); 
... 
// other claims 
... 
identity.AddClaim(new Claim(ClaimTypes.Role, "admins")); 
... 
var ticket = new AuthenticationTicket(identity, properties); 
context.Validated(ticket); 

編輯

你可以得到用戶角色從DB,而不是使用「管理員」 harcoded串這樣做的:

var roles = await userManager.GetRolesAsync(userId); 

所以,你可以在你的倉庫中添加下面的方法:

public async Task<IList<string>> UserRoles(string userId) 
{ 
    IList<string> roles = await userManager.GetRolesAsync(userId); 

    return roles; 
} 

,然後從overrided GrantResourceOwnerCredentials加入叫它:

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

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

    var roles = repository.UserRoles(user.Id); 
} 
+0

非常感謝你,它幾乎工作,但我如何從用戶registred角色採取的不是「管理員」固定廣告宣稱串? – user2100125 2014-09-07 20:34:03

+0

@ user2100125我編輯了我的答案以從Db中檢索用戶角色。 – 2014-09-08 07:07:55

+0

非常感謝:) – user2100125 2014-09-08 14:41:17