The issue with OpenID is often that the IDP itself can be configured in a million ways.
Since you seem to use AzureAD you can use the extension AddMicrosoftIdentityWebApp (https://learn.microsoft.com/en-us/samples/azure-samples/active-directory-aspnetcore-webapp-openidconnect-v2/active-directory-aspnetcore-webapp-openidconnect-v2/).
Here's an idea on how you can implement it. Begin by adding the package Microsoft.Identity.Web, implement the others as stated on the documentation if need be.
var configurationSection = _configuration.GetSection("AzureAd");
services
.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(options =>
{
configurationSection.Bind(options);
options.TokenValidationParameters = new TokenValidationParameters
{
RoleClaimType = ClaimConstants.Roles,
// Value will be overwritten by MicrosoftIdentity by we set it later in
// by configure the Options later.
NameClaimType = "onpremisessamaccountname", // or whatever your nameclaim is, this is for onprem synced users
ValidateIssuer = false
};
options.Scope.Clear();
options.Scope.Add(OpenIdConnectScope.OfflineAccess); // if you need refresh tokens
options.Scope.Add(OpenIdConnectScope.Email);
options.Scope.Add(OpenIdConnectScope.OpenIdProfile);
options.MapInboundClaims = false;
},
options =>
{
options.AccessDeniedPath = "/AccessDenied";
options.Cookie.Domain = null;
options.Events.OnSignedIn = async ctx =>
{
if (ctx.Principal?.Identity is ClaimsIdentity claimsIdentity)
{
// Syncs user and roles so they are available to the CMS
var synchronizingUserService = ctx
.HttpContext
.RequestServices
.GetRequiredService<ISynchronizingUserService>();
await synchronizingUserService.SynchronizeAsync(claimsIdentity);
await Task.CompletedTask;
};
};
});
And the configuration section for AzureAD in appsettings
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "yourdomainonmicrosoft.onmicrosoft.com",
"TenantId": "",
"ClientId": "",
"ClientSecret": ""
},
Configure according to your needs
So I figured out that actual problem here. As it turns out, it had to do with the TokenValidationParameters.
options.TokenValidationParameters = new TokenValidationParameters
{
RoleClaimType = ClaimTypes.Role,
NameClaimType = "preferred_username",
ValidateIssuer = false
};
The above code snippet comes from the Opti Docs when configuring OpenIdConnect and in .NET 6 ClaimTypes.Role evaluates to "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" (while previously it evaluated to "roles")
Eric' post using AddMicrosoftIdentityWebApp includes the following TokenValidationParameters:
options.TokenValidationParameters = new TokenValidationParameters
{
RoleClaimType = ClaimConstants.Roles,
NameClaimType = "preferred_username",
ValidateIssuer = false
};
In ClaimConstants.Roles evaluates to "roles" which is the correct value
Yikes!
Hello,
We are configuring OpenIDConnect during an upgrade to CMS 12 and are plagued with the AccessDenied problem (which I have seen in other posts without a clear solution)
We are forced at the moment to configure the app with "responseType: id_token" due to not being supplied with the secret. So our code contains the following:
As you can see, the only thing differing from the recommended setup is the option.ResponseType setting. When attempting to access the back office at /episerver/cms, we get redirected to Azure AD login, and when I put a breakpoint in the above code in the OnSignedIn function I can see the role claims containing the expected "WebAdmins" role.
BUT, when continuing we are re-directed to /Account/AccessDenied?ReturnUrl=%2Fepiserver%2Fcms
What are we doing wrong?
Thanks for any help with this, Stephen