How to find application content from ASP.NET web API method?

In my code (ASP.NET Identity 2.1) I install the following statements:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>(); ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password); if (user == null) { context.SetError("invalid_grant", "The user name or password is incorrect."); return; } ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType); ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager, CookieAuthenticationDefaults.AuthenticationType); AuthenticationProperties properties = CreateProperties( user.UserName, oAuthIdentity, user.FirstName, user.LastName, user.Organization); AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties); context.Validated(ticket); context.Request.Context.Authentication.SignIn(cookiesIdentity); } 

Here is the CreateProperites method in which role requests are added:

  public static AuthenticationProperties CreateProperties( string userName, ClaimsIdentity oAuthIdentity, string firstName, string lastName, int organization) { IDictionary<string, string> data = new Dictionary<string, string> { { "userName", userName}, { "firstName", firstName}, { "lastName", lastName}, { "organization", organization.ToString()}, { "roles",string.Join(":",oAuthIdentity.Claims.Where(c=> c.Type == ClaimTypes.Role).Select(c => c.Value).ToArray())} }; return new AuthenticationProperties(data); } 

On my client, I issue a request for a token and get it like this:

  this.$http({ method: 'POST', url: '/Token', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, data: 'grant_type=password&username=' + encodeURIComponent(userName) + '&password=' + encodeURIComponent(password), }) .success((data: any, status, headers, cfg) => { self.data.roles = data.roles; 

I see that self.data.roles is correctly filled with roles. Now back to the server, and I want to check the contents of the role requirements. Can someone help by telling me how to do this? I know that I can do the following in a method:

  [HttpGet] [Route("Retrieve")] public async Task<IHttpActionResult> Retrieve() { var x = User; 

x gets the value

 System.Security.Claims.ClaimsPrinciple and System.Security.Claims.ClaimsIdentity 

but inside x I cannot find information about the claims themselves.

Note that I tried a sentence posted earlier in SO:

  var identity = (ClaimsIdentity)User.Identity; IEnumerable<Claim> claims = identity.Claims; // The following line returns null var roles = identity.Claims.Where(r => r.Type == "roles").FirstOrDefault(); 

But I still can’t claim that the information related to the role requirement was found by me. I know that he should be there when he gets to the client.

Please note that I am looking for a specific application. Not any claimed system. But the one I tried to add containing a concatenated list of roles.

+5
source share
2 answers

Have you tried this?

var roleClaims = identity.Claims.Where(c => c.Type == ClaimTypes.Role);

UPDATE

First of all, you are not adding a claim. You add some data to the AuthenticationTicket property dictionary. This data is comma-separated roles, and the key you selected is called "roles". So this is not a requirement.

When you say that this does not work for me, I believe that you want to find a comma separated value that you put in the dictionary. If so, you cannot get it from User in the controller. When you send a carrier token, the token ClaimsIdentity reads the token, obtains ClaimsIdentity from the token, and sets this in context so that you can read it with User .

Everything that you put in AuthenticationTicket is intended for use by middleware (actually the handler). So, if you want to get any data from AuthenticationTicket , you need to call AuthenticateAsync on the middleware explorer yourself. By doing var result = await AuthenticationManager.AuthenticateAsync(OAuthDefaults.AuthenticationType); , you get the whole ticket, not just ClaimsIdentity . result looking at the result , you can get your comma-separated roles, but then realize that the middleware has already done this for you once, and you call it again.

By the way, if you want to add a custom application, you need to add it to oAuthIdentity in GrantResourceOwnerCredentials .

 public override async Task GrantResourceOwnerCredentials( OAuthGrantResourceOwnerCredentialsContext context) { // snip ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType); oAuthIdentity.AddClaim(new Claim("urn:roles", "a,b,c"); } 

If you do this like this, you can read from User .

var myRoleClaims = identity.Claims.Where(c => c.Type == "urn:roles");

+5
source

I think the problem is that you are looking at the wrong authentication types, User.Identity on the cookie and the "active" authenticationType, which is: CookieAuthenticationDefaults.AuthenticationType

To look at the requirements for your roles, you probably need to call IAuthenticationManager.Authenticate (OAuthDefaults.AuthenticationType), and then I think you will see the pending roles that you expect.

Edit: added example

  var result = await AuthenticationManager.AuthenticateAsync(OAuthDefaults.AuthenticationType); // do something with result.Identity 
+1
source

Source: https://habr.com/ru/post/1206692/


All Articles