Search code examples
identityserver4

IdentityServer4 with Windows authentication and custom claims


I have a problem with windows auth and custom claims.
I have an identityServer with windows auth and User.Identity.Name show my AD name. But I cannot understand, how should I add some properties from my storage to this user. I have now something like this:

var claims = new List<Claim> {
      new Claim("devhomepage", "www.devsite.com", ClaimValueTypes.String)};
var userIdentity = new ClaimsIdentity(claims, "siteinfo");
User.AddIdentity(userIdentity);
await HttpContext.SignInAsync(User);
return RedirectToLocal(returnUrl);

and it doesn't work :-) my client will be not authorized.

here is a config for the server

new Client
                {
                    ClientId = "mvc",
                    ClientName = "MVC Client",
                    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },
                    RedirectUris = {"http://localhost:60640/signin-oidc"},// where to redirect to after login
                    PostLogoutRedirectUris = {"http://localhost:60640/signout-callback-oidc"},// where to redirect to after logout
                    AllowedScopes = new List<string>
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                    },
                    AllowOfflineAccess = true,
                    RequireConsent = false

and is't a client

services.AddAuthentication(options =>
                {
                    options.DefaultScheme = "Cookies";
                    options.DefaultChallengeScheme = "oidc";
                })
                .AddCookie("Cookies")
                .AddOpenIdConnect("oidc", options =>
                {
                    options.SignInScheme = "Cookies";
                    options.Authority = "http://localhost:49245/";
                    options.RequireHttpsMetadata = false;
                    options.ClientId = "mvc";
                    options.ClientSecret = "secret";
                    options.ResponseType = "code id_token";
                    options.GetClaimsFromUserInfoEndpoint = true;
                    options.SaveTokens = true;
                });

Solution

  • For SignIn I must use Microsoft.AspNetCore.Identity.SignInManager class with method SignInAsync(/*I should take hire a TUser object, that I stored in my database, and make mapping with my AD account */)

    To use custom claims (will be used for all samples with custom claims in IS4):

    public class ProfileService : IProfileService
        {
            protected UserManager<IdentityUser> _userManager;
    
            public ProfileService(UserManager<IdentityUser> userManager)
            {
                _userManager = userManager;
            }
    
            public async Task GetProfileDataAsync(ProfileDataRequestContext context)
            {
                //>Processing
                var user = await _userManager.GetUserAsync(context.Subject);
                //my custom claims
                var claims = new List<Claim>
                    {
                        new Claim("devhomepage", "www"),
                        new Claim("reporting","reps")
                    };
    
                context.IssuedClaims.AddRange(claims);
            }
    
            public async Task IsActiveAsync(IsActiveContext context)
            {
                //>Processing
                var user = await _userManager.GetUserAsync(context.Subject);
    
                context.IsActive = (user != null);
            }
        }
    

    But this service I must register only after my IdentityService

    services.AddIdentityServer()
    ...
    services.AddTransient<IProfileService, ProfileService>();
    }
    

    of ConfigureServices