I tried configuring the site with "Windows Authentication" and using the concept of "virtual roles" as a possible solution, but only getting "unauthorized" when I load it up. I did this in startup.cs. Anything else I need to do? Or maybe version 12 doesnt support "windows authentication" either.
Changes in startup.cs:
services.AddCms();//.AddCmsAspNetIdentity<ApplicationUser>();
services.AddAuthentication(IISDefaults.AuthenticationScheme);
Changes in laungSettings.json:
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:50108/",
"sslPort": 44344
}
},
Added this to appsettings.json (to make local administrators-users be mapped to the Administrator group)
"EpiServer": {
"Cms": {
"MappedRoles": {
"Items": {
"Administrator": {
"MappedRoles": [ "Administrators" ],
"ShouldMatchAll": "false"
}
}
}
}
}
But sadly it doenst work. Any suggestions? Thanks!
If the server is on the newtwork you can use this package Microsoft.AspNetCorre.Authentication.Negotiate
Yes, thank you. Thats the package Im using. I actually got the "windows authentication" part working, and it logs me in automaticly with a local account in my dev-environment. To make it work I had to "turn off" the normal .net Identity functionality (by leaving out .AddCmsAspNetIdentity<ApplicationUser>()). But only if I first gave "Everyone" access to the site at root-level.
Ideally I would like to log in by windows authentication and then somehow "translate" to an internal user so I can take advantage of the group-settings etc. But for now I have no idea how to do that. So any suggestions would be much appreciated. There must be some solution for using version 12 in an intranet environment with SSO?
In startup you need to implement the authenticated event when you configure teh Negogiate package to sync the user. The default secutriy event provider will also include synched users so you can conto
options.Events = new NegotiateEvents()
{
OnAuthenticated = context =>
{
// Create claims identity to sync, map internal roles to Opti roles here
var synchronizingUserService = context
.HttpContext
.RequestServices
.GetRequiredService<ISynchronizingUserService>();
await synchronizingUserService.SynchronizeAsync(claimsIdentity);
return Task.CompletedTask;
}
};
Thanks for your help. Tried like this in startup.cs:
services.AddCms().AddAuthentication(options =>
{
options.DefaultScheme = IISDefaults.AuthenticationScheme;
}).AddNegotiate(options =>
options.Events = new NegotiateEvents()
{
OnAuthenticated = async context =>
{
// Create claims identity to sync, map internal roles to Opti roles here
var claimsIdentity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Role,"WebAdmins"),
new Claim(ClaimTypes.Name,"rickard")
}, "ApplicationCookie", ClaimTypes.Name, ClaimTypes.Role);
var synchronizingUserService = context
.HttpContext
.RequestServices
.GetRequiredService<ISynchronizingUserService>();
await synchronizingUserService.SynchronizeAsync(claimsIdentity);
}
}
);
But the OnAuthenticated event doesnt even hit, so no new claims is added to the user :(
Yeah I see now in the docs
Claims transformations
When hosting with IIS, AuthenticateAsync isn't called internally to initialize a user.
Therefore, an IClaimsTransformation implementation used to transform claims after every authentication isn't activated by default.
For more information and a code example that activates claims transformations, see Differences between in-process and out-of-process hosting.
These docs go into more details.
Here is an example link to an implementation.
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/claims?view=aspnetcore-6.0
Here is how you register the new class. We have a implementation as well so you want to add another and not replace.
services.TryAddEnumerable(Microsoft.Extensions.DependencyInjection.ServiceDescriptor.Singleton<IClaimsTransformation, VirtualRoleClaimsTransformer>());
Good stuff, thank you! This actually seems to be working the way I want, gonna test it out more on monday to be 100% sure. But in my quick test I can login using windows authentication, then use my own claimstransformer to add 2 more roles (WebAdmins, CmsAdmins), and the user gets acces to the site and cms-admin mode!
So I ended up with this Startup.cs
//Note that Im not adding .AddCmsAspNetIdentity<ApplicationUser>(). If I do that the "normal" login seems to
//override the windows authentication. Maybe its possible to use both, but I dont need it in my example
services.AddCms().AddAuthentication(options =>
{
options.DefaultScheme = IISDefaults.AuthenticationScheme;
}).AddNegotiate();
// This line hooks in my ClaimsTransformer class which basicly adds another identity to the principal with some more roles that I want
services.TryAddEnumerable(ServiceDescriptor.Singleton<IClaimsTransformation, ClaimsTransformer>());
For reference this is my ClaimsTransformer.cs. This is just simply adding two more roles
public class ClaimsTransformer : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var claimsIdentity = new ClaimsIdentity();
claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, "WebAdmins"));
claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, "CmsAdmins"));
principal.AddIdentity(claimsIdentity);
return Task.FromResult(principal);
}
}
Great, I m assuming since the users are on the network you are doing any additional checks, but you might want to do some additional validation before adding them as Webadmin
Yes, I will check AD-groups and assign appropriate roles. This was just a quick test where I added 2 roles without checking anything. Thanks for all your help!
Hi!
In previous versions it was very convenient to use the Active Directory Role Provider integration with the cms, so you could have SSO and restrict access to pages based on Active Directory groups.
Is there any way to achieve a similar behaviour in the .net core based version 12? My scenario is a intranet-like situation with my own AD-server, so using Azure AD is not an option.
thanks!