2013-10-28 32 views
7

我的WebAPI 2應用程序具有用於檢查訪問令牌的自定義授權篩選器。如果令牌存在,並且API具有該屬性,那麼我檢查是否存在映射到該令牌的用戶。由於API的性質,大多數方法在特定用戶的上下文中運行(即,「POST api/profile」來更新用戶的簡檔)。爲了做到這一點,我需要獲取來自訪問令牌的目標用戶信息。將主體/用戶上下文設置爲用戶對象

[當前實現,恰好型AuthorizeAttribute的屬性中]

if(myDBContext.MyUsers.Count(x => x.TheAccessToken == clientProvidedToken)){ 
    IPrincipal principal = new GenericPrincipal(new GenericIdentity(myAccessToken), new string[] { "myRole" }); 
    Thread.CurrentPrincipal = principal; 
    HttpContext.Current.User = principal; 
    return true; 
} 

這工作得很好,我能夠再使用訪問令牌做的方法的第二查找。 但是由於我已經在auth時間做了一個查詢,我不想浪費另一個數據庫調用

[我想要做什麼(但顯然是行不通的)

MyUser user = myDBContext.MyUsers.FirstOrDefault(x => x.TheAccessToken == clientProvidedToken); 
if(user != null){ 
    // Set *SOME* property to the User object, such that it can be 
    // access in the body of my controller method 
    // (e.g. /api/profile uses this object to load data) 
    HttpContext.Current.User = user; 
    return true; 
} 

回答

8

你可以使用你自己的主體類。也許是這樣的:

public class MyPrincipal : GenericPrincipal 
{ 
    public MyPrincipal(IIdentity identity, string[] roles) 
     : base(identity, roles) 
    { 
    } 
    public MyUser UserDetails {get; set;} 
} 

那麼你的動作過濾器可以這樣做:

MyUser user = myDBContext.MyUsers.FirstOrDefault(x => x.TheAccessToken == clientProvidedToken); 
if(user != null) 
{ 
    MyPrincipal principal = new MyPrincipal(new GenericIdentity(myAccessToken), new string[] { "myRole" }); 
    principal.UserDetails = user; 
    Thread.CurrentPrincipal = principal; 
    HttpContext.Current.User = principal; 
    return true; 
} 
return false; 

,隨後在實際的方法,你可以把當前用戶,檢查它是否MyPrincipal類型,如果是丟然後訪問的UserDetails:

... 
MyUser currentUser = null; 
MyPrincipal curPrincipal = HttpContext.Current.User as MyPrincipal; 
if (curPrincipal != null) 
{ 
    currentUser = curPrincipal.UserDetails; 
} 
... 

我還沒有試過actaully這段代碼,所以可能有錯別字...

+0

不知道爲什麼我沒有想到擴展GenericPrincipal - 它很好地工作!謝謝! – ShaneC

7

你可以使用一個ClaimsIdentity/ClaimsPrincipal並添加Claims您需要在控制器後,例如演員ID或其他你需要的值。

我做了一個例子,它爲演員設定了聲明,但如果它更適合你,你也可以直接向當前用戶聲明。

var identity = new ClaimsIdentity(HttpContext.Current.User.Identity); 
identity.Actor = new ClaimsIdentity(); 
identity.Actor.AddClaim(new Claim("Your", "Values")); 

var principal = new ClaimsPrincipal(identity); 
Thread.CurrentPrincipal = principal; 
HttpContext.Current.User = Thread.CurrentPrincipal; 
+1

使用聲明更好,因爲符合框架而不是針對工作。或者,如果代碼依賴於HttpContext,也可以使用HttpContext.Profile。 http://msdn.microsoft.com/en-us/library/system.web.httpcontext.profile(v=vs.110).aspx – user3285954

相關問題