Set main / user context for user object

My WebAPI 2 application has a custom authorization filter that checks the access token. If a token is present and the API has an attribute, then I check to see if there is a user that maps to this token.

Due to the nature of the API, most methods are run in the context of a particular user (that is, the "POST api / profile" to update the user profile). To do this, I need the information about the target user that I get from the access token.

[Current implementation, happening inside an attribute of type 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; } 

This works fine, and I can use the access token to perform a second search in the method. But since I’m already doing auth searches, I don’t want to spend another DB call .

[What I would like to do (but obviously does not work)]

 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 // (eg /api/profile uses this object to load data) HttpContext.Current.User = user; return true; } 
+7
authentication c # authorization asp.net-web-api
source share
2 answers

You can use your own main class. Maybe something like:

 public class MyPrincipal : GenericPrincipal { public MyPrincipal(IIdentity identity, string[] roles) : base(identity, roles) { } public MyUser UserDetails {get; set;} } 

Then your action filter could do:

 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; 

And then in your actual method, you can take the current user, check if he is of type MyPrincipal , and if he has thrown it, and then access the UserDetails:

 ... MyUser currentUser = null; MyPrincipal curPrincipal = HttpContext.Current.User as MyPrincipal; if (curPrincipal != null) { currentUser = curPrincipal.UserDetails; } ... 

I have not executed this code, so there may be typos ...

+8
source share

You can use ClaimsIdentity/ClaimsPrincipal and add Claims , which you will need later in your controller, for example, the identifier of participants or other values ​​that you need.

I gave an example that claims the Actor, but if it suits you better, you can also apply directly to the current user.

 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; 
+7
source share

All Articles