The dbo.Clients table in the IdentityServer database contains both ClientId and ClientName, however requesting a client credentials token doesn't include the client name in the token.
Is there a way to either retrieve client information from IdentityServer given the client id, or request that the client name be added to the token?
You can add them dynamically using a custom token request validator :
public class ClaimClientsUpdated : ICustomTokenRequestValidator
{
public Task ValidateAsync(CustomTokenRequestValidationContext context)
{
context.Result.ValidatedRequest.Client.AlwaysSendClientClaims = true;
context.Result.ValidatedRequest.ClientClaims.Add(new Claim("name", context.Result.ValidatedRequest.Client.ClientName));
return Task.FromResult(0);
}
}
Register in DI :
services.AddTransient<ICustomTokenRequestValidator, ClaimClientsUpdated>();
It will add prefix "client_" to custom claims , so claim will be "client_name": "value" in access token .
You can add information about the client in general by adding claims to the ClientClaims table. E.g. Type = Name, Value = MyCustomName
Which is added as claim (assuming prefix client_):
"client_Name": "MyCustomName"
This will allow you to add information about the client without having to add or change code.
The drawback for the client name is that you'll have to add a claim with redundant information, as Clients.ClientName is not the source. The advantage is that it's configuration only.
Related
I have created an ASP.NET Core application that successfully authenticates users with Azure AD and have seen that for an authenticated user an instance of type System.Security.Claims.ClaimsPrincipal is returned containing a single identity of type System.Security.Claims.ClaimsIdentity with a Type property valued "preferred_username" that carries the user's UPN. Among the claims that are returned there is for example one with its Type property valued "name" which seems to contain the user's display name. I was wondering if there is a way to have other users' attributes/properties also returned in the form of claims.
I was wondering if there is a way to have other user's
attributes/properties also returned in the form of claims.
Obviously you can retrieve optional claims within your token using azure active directory. To achieve that you would need few settings in Token configuration under azure active directory blade.
What Additional Claim can be added:
Currently, you can include these optional claims in your both idToken, accessToken and saml2Token
Settings For Optional Claims:
If you would like to include additional claims within your token you ought to configure as following:
Select Token configuration in your app:
Select Add optional claim and Include your claims:
You should have profile access permission:
Check your Manifest if the claims added accordingly:
Now You can Call Optional Claims which are available ClaimTypes Class:
Note: You can check the available claims fields witin ClaimTypes Class here.
Code Snippet:
You can implement within your application as following:
var username = HttpContext.User.Identity.Name;
var givenName = HttpContext.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.GivenName)?.Value;
var email = HttpContext.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value;
var country = HttpContext.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Country)?.Value;
Note: If you would like to know more details on optional claims you could check our official document here.
I am trying to use OpenIddict as an authorization server and I managed to produce a token, however I have no idea how to put the "aud" claim in the token.
I could of course manually add it to the created ClaimsPrincipal, but I'm wondering if there is a way for that like in IdentityServer. In IdentityServer you could declare api resources, and for those resources, you could declare scopes. If a scope of an API resource was requested, the name of the api resource was included as an audience.
Is there a way to tell OpenIddict that if a scope is requested, include a special audience, or it has to be implemented manually?
You can attach a list of resources to a scope when creating it via the scope manager:
await manager.CreateAsync(new OpenIddictScopeDescriptor
{
DisplayName = "Demo API access",
DisplayNames =
{
[CultureInfo.GetCultureInfo("fr-FR")] = "Accès à l'API de démo"
},
Name = "demo_api",
Resources =
{
"resource_server"
}
});
Then, use ListResourcesAsync(scopes) to list all the resources associated with the specified scopes. E.g:
principal.SetResources(await _scopeManager.ListResourcesAsync(principal.GetScopes()).ToListAsync());
I am using ASP.NET Core 2.2 and I need to generate custom tokens in my application.
Asp.Net Core Identity UserManager can generate classic tokens like EmailVerification, ...
But it has also a method to generate tokens with different purposes (MSFT Docs):
public virtual System.Threading.Tasks.Task<string> GenerateUserTokenAsync (TUser user, string tokenProvider, string purpose);
I need to generate a token with the following information:
Purpose = AddUserToProject
User = A given user
ProjectId = The Project Id to which the User should be added.
RoleId = The Role Id of the User in the Project
On GenerateUserTokenAsync I can add the User and the Purpose ...
But I'm not sure how to add (3) and (4) e.g. ProjectId and RoleId.
And how can I retrieve it later so I can actually perform the action.
How should I do this?
You can create a custom token provider, and then instruct ASP.NET Core to use that. Create a class that implements IUserTokenProvider<TUser, TKey>. Then, you can either explicitly use it:
var token = await _userManager.GenerateUserTokenAsync(user, "MyCustomTokenProvider", purpose);
Or you can sub it in for any or all of the Identity token providers in ConfigureServices:
services.AddIdentity<IdentityUser, IdentityRole>(o => {
o.Tokens.PasswordResetTokenProvider = nameof(MyCustomTokenProvider);
// rinse and repeat for other token providers you want to change
// see: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity-configuration?view=aspnetcore-2.2#tokens
})
.AddTokenProvider<MyCustomTokenProvider>(nameof(MyCustomTokenProvider));
[1]:
I'm using the new ASP.NET Core Identity API Authorization found in dotnet-core3-preview, the docs are found here https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization?view=aspnetcore-3.0
I'm succesfully running the typical login process, and the token are set and sent in the Bearer token. However rightnow I have an api end point that should return some user details from the database, so I'm trying to extract the user id from the token to query the database.
Yet, I'm not able to find the id in any of the claims, as per my screenshot below, how can I accomplish this?
[HttpGet]
[Authorize]
public async Task<IActionResult> GetUserByToken(){
var ls = User.Claims.AsQueryable();
return Ok(ls);
}
The user id could be find in claim : http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier :
var userID = User.Claims.Where(a => a.Type == ClaimTypes.NameIdentifier).FirstOrDefault().Value;
That id value equals Id column in AspNetUsers table which created by ASP.NET Identity .
I prefer using this instead which is shorter:
var userId = User.FindFirst(ClaimTypes.NameIdentifier).Value
I am using the Web Api 2 Auth template in my project.I want to get the user id when the client request with Api Key. My question is :
1 How can I get the api client user's Id.
-Is right or wrong resolve it through the Api requesting ?
-or take the userId in the http header directly?
-or query it from database using the Api key?
2 I create the MyApiController inherit from ApiController,I want to get the claims in it.So I write some code in it.like this
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
var principal = Request.GetRequestContext().Principal as ClaimsPrincipal;
CorpId = (from c in principal.Claims where c.Type.Contains("CorpId") select c.Value).FirstOrDefault();
UserId = (from c in principal.Claims where c.Type.Contains("UserId") select c.Value).FirstOrDefault();
}
I found the claim is null in the MyApiController. But when I do it in the action controller,It worked ?
You'd rather get request specific data when the request is executed (i.e. in Controller.Get method), not when the controller is created. Or use a filter attribute if values are not needed in controller method.