如何为所有WebApi控制器获取JWT声明一次

时间:2017-05-25 19:32:46

标签: c# asp.net-web-api asp.net-web-api2 ninject

我在JWT令牌中添加了几个声明。在任何方法中,我的API中的每个控制器都获得了身份并检查了这些声明。我想减少代码的重复,并从一个共同的地方获得我的主张;可能在startup.cs中分配它们。

例如,我有一个实现基本CRUD操作的DemoController。在我的所有控制器中,相同的代码往往出现在我的所有控制器中:

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注入每个控制器,但我不完全确定如何执行此操作,如果有可能或是否存在更好的可行选择。

欢迎所有建议!

1 个答案:

答案 0 :(得分: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进行您想要执行的每种类型的检查。