Reputation: 69928
I have set up Resource Owner Password Credentials grant using the answer below:
https://stackoverflow.com/a/67324222/3850405
I have then followed this guide to set up name and role claim:
Everything works well but with normal Authorization Code Grant but with ROPC I do not get neither name or role claim.
The reason we are not using Client Credentials Grant can be seen here:
https://github.com/dotnet/aspnetcore/issues/44122
ProfileService.cs:
using IdentityModel;
using Duende.IdentityServer.Models;
using Duende.IdentityServer.Services;
using System.Threading.Tasks;
public class ProfileService : IProfileService
{
public ProfileService()
{
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var nameClaim = context.Subject.FindAll(JwtClaimTypes.Name);
context.IssuedClaims.AddRange(nameClaim);
var roleClaims = context.Subject.FindAll(JwtClaimTypes.Role);
context.IssuedClaims.AddRange(roleClaims);
await Task.CompletedTask;
}
public async Task IsActiveAsync(IsActiveContext context)
{
await Task.CompletedTask;
}
}
Startup.cs (Program.cs in .NET6):
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
{
options.Clients.AddIdentityServerSPA("WebApplication4.Client", builder =>
{
builder.WithRedirectUri("/authentication/login-callback");
builder.WithLogoutRedirectUri("/authentication/logout-callback");
});
//Or Duende.IdentityServer.Models.Client
options.Clients.Add(new IdentityServer4.Models.Client
{
ClientId = "WebApplication4.Integration",
AllowedGrantTypes = { GrantType.ResourceOwnerPassword },
//Use Configuration.GetSection("MySecretValue").Value; to get a value from appsettings.json
ClientSecrets = { new Secret("MySecretValue".Sha256()) },
AllowedScopes = { "WebApplication4.ServerAPI", "openid", "profile" }
});
});
services.AddTransient<IProfileService, ProfileService>();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");
Upvotes: 2
Views: 251
Reputation: 69928
Turned out to be a configuration issue.
Microsoft says Use one of the following approaches:
but using a Profile Service like public class ProfileService : IProfileServic
only works with Authorization Code Grant and not Resource Owner Password Credentials. Removing the ProfileService
and instead using this code everything worked:
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
options.IdentityResources["openid"].UserClaims.Add("name");
options.ApiResources.Single().UserClaims.Add("name");
options.IdentityResources["openid"].UserClaims.Add("role");
options.ApiResources.Single().UserClaims.Add("role");
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");
Upvotes: 4