Virtual Happy Hour this month, Jun 28, we'll be getting a sneak preview at our soon to launch SaaS CMS!

Try our conversational search powered by Generative AI!

Problems when adding Azure AD Authentication and Authorization

Vote:
 

Hello there!

I have problems adding/configuring Azure AD Authentication and Autorization - OpenID. I have tried to do it on the Allow template for .Net core (CMS 12.6.x)

The loggin works fine. The user is correctly mapped to the correct role (in my case Webadmins).
The problem is that I have problem viewing and assigning roles in the episerver admin UI.

1.Under Admin->Access Rights->Adminster Groups do I get this:

it might be that this is not possible with AAD?

2. When using Admin->Access Rights->Set Access Rights can I not see the roles from AAD.

This is a bigger problem than #1. How to setup enable roles/groups in AAD to show up in the Admin UI?

I have tried to tweak different thing, bot no luck. The code looks like this right now:

        services
            //.AddCmsAspNetIdentity<ApplicationUser>()
            .AddCms()
            .AddAlloy()
            //.AddAdminUserRegistration()
            .AddEmbeddedLocalization<Startup>();

        services
            .AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = "azure-cookie";
                options.DefaultChallengeScheme = "azure"; // OpenIdConnectDefaults.AuthenticationScheme;
            })
            .AddCookie("azure-cookie", options =>
            {
                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);
                    }
                };
            })
            .AddOpenIdConnect("azure", options =>
            {
                options.SignInScheme = "azure-cookie";
                options.SignOutScheme = "azure-cookie";
                options.ResponseType = OpenIdConnectResponseType.Code;
                options.CallbackPath = _configuration["Authentication:AzureCallback"];
                options.UsePkce = true;

                options.ClientId = _configuration["Authentication:AzureClientID"];
                options.Authority = _configuration["Authentication:AzureTenantID"];

                options.Scope.Clear();
                options.Scope.Add(OpenIdConnectScope.OpenId);
                options.Scope.Add(OpenIdConnectScope.OfflineAccess);
                options.Scope.Add(OpenIdConnectScope.Email);
                options.MapInboundClaims = false;

                options.TokenValidationParameters = new TokenValidationParameters
                {
                    RoleClaimType = "roles",
                    NameClaimType = "email",
                    //RoleClaimType = ClaimTypes.Role,
                    //NameClaimType = "preferred_username",

                    ValidateIssuer = false
                };

                options.Events.OnRedirectToIdentityProvider = ctx =>
                {
                    // Prevent redirect loop
                    if (ctx.Response.StatusCode == 401)
                    {
                        ctx.HandleResponse();
                    }

                    return Task.CompletedTask;
                };

                options.Events.OnAuthenticationFailed = context =>
                {
                    context.HandleResponse();
                    context.Response.BodyWriter.WriteAsync(Encoding.ASCII.GetBytes(context.Exception.Message));
                    return Task.CompletedTask;
                };

                options.Events.OnTokenValidated = context =>
                {
                    // Debug: Enable to print claims debug information in the console
                    var user = context.Principal.Identity;
                    if (user != null)
                    {
                        var claims = ((ClaimsIdentity)context.Principal.Identity).Claims;

                        // Testing. Ta bort sen!
                        var claimsIdentity = (ClaimsIdentity)context.Principal.Identity;
                        //claimsIdentity?.AddClaim(new Claim(ClaimTypes.Role, "WebAdmins"));

                        foreach (var claim in claims)
                        {
                            Console.WriteLine($"{claim.Type}: {claim.Value}");
                        }
                    }

                    return Task.CompletedTask;
                };
            });

        // Required by Wangkanai.Detection
        services.AddDetection();

        services.AddSession(options =>
        {
            options.IdleTimeout = TimeSpan.FromSeconds(30);
            options.Cookie.HttpOnly = true;
            options.Cookie.IsEssential = true;
        });

Am i missing someting to make Episerver get hold of my roles and groups in AAD?

#291494
Nov 11, 2022 13:45
Vote:
 

await synchronizingUserService.SynchronizeAsync(claimsIdentity);

Make sure that claimsIdentity has the roles on the correct claim name when calling the above line.

And about assigning roles in the CMS that is not the preferred way with any type of federated auth, the roles should be handled in the identity provider.

If you still need a "role manager" you can build and store those in some custom way. I believe that is easier than bending the built-in manager to work in a mixed way between Azure AD and AspNetIdentity.

#291499
Edited, Nov 11, 2022 16:52
Vote:
 

First: Maybe I was a bit unclear in my post. We are aiming for ONKY AAD user and roles. So no AspNetIdentity. If so does it seem correct if "Administer groups" should not be possible/available. Just want to verify that.

Second: The more relevant problem is that I can not see/get any roles passed from AAD in Set access rights. Corrently only one role is used (not tried to configure for more roles from AAD, but thats the next step). The logged in user is Webadmin, but it does not show up in Set Access rights. I can only see the user there. (See the first snapshot above). 
Note: Since I can access the Episerver-admin at all does it seem to me that the role Webadmins is the, but not shown in Set Access rights.

I can see the role in where await synchronizingUserService.SynchronizeAsync(claimsIdentity);



I can also see the role in the episerver database:

So for me does it seem ok, but why is not the Role Webadmin showing in the Set Access right?

#291625
Nov 14, 2022 8:50
Vote:
 

I would try adding some new roles and see if they show up in the set rights UI.

Maybe try to delete all AspNetIdentity-tables and/or run Profiler and see where the SQL queries looks for roles.

#291629
Nov 14, 2022 9:49
Sven Tegelmo - Nov 14, 2022 10:58
Now do the groups/roles show up in the GUI. For some reason did the sepecific Webadmins role not show up. But when configuring to show other roles did it work. Strange!
Anyway. Its working fine now. Thanks for your help and wise ideas to test/check :)
Johan Kronberg - Nov 14, 2022 11:59
Great!
Vote:
 

You must configure your application to use the same role claim type as the one in your access token from Azure AD. From your screenshot I can see that you're using "roles" as the roles claim type, then you need to configure the CMS application to use that type too:

options.TokenValidationParameters = new TokenValidationParameters
{
    ...
    RoleClaimType = "roles",
    ...
};

In your sample code you used claimsIdentity?.AddClaim(new Claim(ClaimTypes.Role, "WebAdmins")); but ClaimTypes.Role is probably not "roles".

Also not that the roles are synced during login, so if you make code changes, you need to login again to sync new roles. After that they the should be available in the UI when granting permission.

#291700
Nov 15, 2022 12:24
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.