首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ApiController覆盖以访问User.Claims

ApiController覆盖以访问User.Claims
EN

Stack Overflow用户
提问于 2016-04-25 19:44:39
回答 3查看 1.9K关注 0票数 0

我有一个从ApiController继承的基本api控制器。在它中,我将覆盖ExecuteAsync,并希望使用存储在Principal.Claims var中的一些数据。但是在调用base.ExecuteAsync()之前它是空的,在调用它之后太晚了。我没看到还有什么能帮上忙的?

代码语言:javascript
复制
public class ApiControllerBase : ApiController
{
    public MyUser CurrentUser { get; set; }

    public override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
    {
        // principal.claims is empty
        ClaimsPrincipal principal = (ClaimsPrincipal)RequestContext.Principal; // principal.claims is empty

        var rv = base.ExecuteAsync(controllerContext, cancellationToken);

        // principal.claims is now populated but the controller.action that inherits from this basecontroller has already fired and thrown an exception since CurrentUser is null.
        principal = (ClaimsPrincipal)RequestContext.Principal;
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-04-25 20:14:47

如果需要访问控制器中的索赔,可以执行以下操作:

代码语言:javascript
复制
public class MyUser 
{
    private readonly ClaimsIdentity _identity;

    public SeaUser(ClaimsIdentity identity)
    {
        _identity= identity;
    }

    public IEnumerable<Claim> Claims { get { return _identity.Claims; } }
}

public abstract class BaseController : ApiController
{
    private MyUser _user;

    public new MyUser User
    {
        get 
        { 
            return _user ?? (_user = User.Identity != null 
                                  ? new MyUser((ClaimsIdentity)User.Identity) 
                                  : null); }
        }
    }
}

然后在任何需要的地方使用用户属性。

假设请求进入ApiController范围,操作顺序如下:

  • 调用ExecuteAsync的ApiController方法。
  • 调用ApiController的Initialize方法。
  • 检索已注册的操作选择器。
  • 调用已注册动作选择器的SelectAction方法。如果只匹配一个操作方法,则管道将继续。
  • 检索所选操作的所有已注册筛选器。
  • 将调用授权筛选器。授权过滤器 决定要么让管道继续执行,要么终止管道。
  • 如果授权筛选器没有终止请求,则执行操作参数绑定。
  • ApiController.ModelState设置。
  • 将调用操作筛选器。该操作筛选一个决定,要么让管道继续执行,要么终止管道。
  • 如果Action没有终止请求,则检索已注册的Action。
  • 调用注册的Action的InvokeActionAsync方法来调用所选的操作方法。

注意:如果授权筛选器的执行到操作方法的执行过程中出现任何异常,则调用异常筛选器。

还有一些事情发生在中间,但这是非常接近一个完整的观点。有关更多信息,请查看ApiController源代码

票数 2
EN

Stack Overflow用户

发布于 2016-04-25 20:09:47

您可以重写OnActionExecuting(),每次执行操作时都会调用它。

代码语言:javascript
复制
public override void OnActionExecuting(ActionExecutingContext context)
    {
        var user = context.HttpContext.User;
        //store user.Claims in property so inherited controllers have access
        base.OnActionExecuting(context);
    }
票数 0
EN

Stack Overflow用户

发布于 2016-04-25 20:20:48

这对我有用(Thread.CurrentPrincipal)

代码语言:javascript
复制
public override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
{
    var principal = Thread.CurrentPrincipal as ClaimsPrincipal;
    return base.ExecuteAsync(controllerContext, cancellationToken);
}

我不确定IAppBuilder (Startup.Configuration)中的注册顺序是否重要,但我首先注册的是身份验证中间件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36849692

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档