Sha*_*neC 9 c# authentication authorization asp.net-web-api
我的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;
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,然后我可以使用访问令牌在方法中进行第二次查找.但由于我已经在auth时间进行查找,所以我不想浪费另一个DB调用.
[我想做什么(但显然不起作用)]
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;
}
Run Code Online (Sandbox Code Playgroud)
use*_*080 10
你可以使用自己的主要课程.也许是这样的:
public class MyPrincipal : GenericPrincipal
{
public MyPrincipal(IIdentity identity, string[] roles)
: base(identity, roles)
{
}
public MyUser UserDetails {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
然后你的动作过滤器可以做:
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;
Run Code Online (Sandbox Code Playgroud)
然后在您的实际方法中,您可以获取当前用户,检查它是否为类型MyPrincipal
,如果是,则转换它然后访问UserDetails:
...
MyUser currentUser = null;
MyPrincipal curPrincipal = HttpContext.Current.User as MyPrincipal;
if (curPrincipal != null)
{
currentUser = curPrincipal.UserDetails;
}
...
Run Code Online (Sandbox Code Playgroud)
我没有尝试过这个代码,所以可能会有拼写错误...
您可以稍后在控制器中使用a 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;
Run Code Online (Sandbox Code Playgroud)