2017-05-25 59 views
0

我有幾個索賠添加到了我的JWT令牌。在任何方法中,我的API中的每一個控制器都會得到身份並檢查這些聲明。我想減少代碼的重複,並從一個共同的地方獲得我的主張;可能在startup.cs中分配它們。如何爲所有WebApi控制器獲得一次JWT索賠

例如,我有一個DemoController來實現基本的CRUD操作。同樣的代碼往往出現在我所有的方法,在我所有的控制器:

var identity = (ClaimsPrincipal)Thread.CurrentPrincipal; 

var region = identity.Claims.Where(c => c.Type == ClaimType.Region).Select(c => c.Value).SingleOrDefault(); 

var role = identity.Claims.Where(c => c.Type == ClaimType.Role).Select(c => c.Value).SingleOrDefault(); 

var responseType = identity.Claims.Where(c => c.Type == ClaimType.ResponseType).Select(c => c.Value).SingleOrDefault(); 

If (region == "some region") 
{ 
} 

有沒有什麼方法可以讓我避免重複的代碼都在我的API?我想用可以在整個的WebAPI控制器間共享的對象,這樣我可以寫我這樣的代碼來代替:

if(ApiUser.Region == "Some Region") 
{ 
    // DO SOMETHING 
} 

我已經使用Ninject依賴注入。我認爲有可能在Startup.cs中創建我的ApiUser對象,然後將ApiUser注入到每個控制器中,但我不完全確定如何做到這一點,如果可能的話或者是否存在更好的替代方案。

所有建議都歡迎!

+0

或者創建一個封裝所有重複代碼並讓控制器繼承它的基礎控制器。 – Nkosi

+0

我認爲你的想法是創建一個封裝了這些信息的類,並將該類注入到控制器中,這是可行且合理的解決方案。將它包裝在一個界面中,以便測試它。我總是喜歡注入而不是繼承。 –

+0

與構造函數注入路線一起的問題是,用戶/主體在注入控制器時尚未設置。 – Nkosi

回答

0

您可以創建一個ClaimsAuthenticationManager的實現來執行查詢聲明或者甚至向JWT添加其他自定義聲明。

public class MyClaimsAuthenticationManager : ClaimsAuthenticationManager 
{ 
    public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal) 
    { 
     if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated) 
     // build up your ApiUser class here 

    } 
    return incomingPrincipal; 
} 

然後,您可以使用您的ApiUser類在每個控制器中進行檢查;甚至更好,使用自定義AuthorizationAttribute爲您想要做的每種類型的檢查。