我有一个基础api控制器,我从ApiController继承。在其中,我重写了ExecuteAsync并希望使用存储在Principal.Claims var中的一些数据。但在调用base.ExecuteAsync()之前它是空的,并且在调用它之后太晚了。我没有看到其他任何要覆盖的东西来帮助它吗?
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;
}
}
答案 0 :(得分:2)
如果您需要访问控制器中的声明,您可以执行以下操作:
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); }
}
}
}
然后在任何需要的地方使用User属性。
假设请求进入ApiController范围,操作顺序如下:
注意:如果从执行授权过滤器到执行操作方法发生任何异常,则会调用异常过滤器。
之间还会发生一些事情,但这非常接近完整视图。有关详细信息,请查看ApiController source code。
答案 1 :(得分:0)
您可以覆盖OnActionExecuting(),每次执行操作时都会调用它。
public override void OnActionExecuting(ActionExecutingContext context)
{
var user = context.HttpContext.User;
//store user.Claims in property so inherited controllers have access
base.OnActionExecuting(context);
}
答案 2 :(得分:0)
这对我有用(Thread.CurrentPrincipal)
SELECT DISTINCT u.department from User u (based on Department name)
我不确定IAppBuilder(Startup.Configuration)中的注册顺序是否重要,但我注册的第一件事是Authentication中间件。