Ray
Ray

Reputation: 43

IdentityServer4 User.Identity.Name is empty

When I want to get the current user name in mvc client,it returns empty. My config.cs code:

    public static IEnumerable<Client> GetClients()
    {
        return new List<Client>
        {
            new Client
            {
                ClientName="Desktop",
                 ClientId = "Desktop",

                AllowedGrantTypes = GrantTypes.Code,
                AllowOfflineAccess = true,
                ClientSecrets = { new Secret("secret".Sha256()) },

                RedirectUris =           { "https://localhost:5001/signin-oidc" },
                PostLogoutRedirectUris = { "https://localhost:5001/" },
                FrontChannelLogoutUri =    "https://localhost:5001/signout-oidc",

                AllowedScopes =
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    "sms",

                    "mail.send",
                    "mail.search"
                },
                RequireConsent = false
            }
        };
    }

My MVC Client Startup.cs file:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        services.AddHttpContextAccessor();

        services.AddAuthentication(options=> {
            options.DefaultScheme = "Cookies";
            options.DefaultChallengeScheme = "oidc";
        })
            .AddCookie("Cookies",options=> {
                options.Cookie.Name = this.Configuration["Cookies:IDS"];                    
            })
            .AddOpenIdConnect("oidc",options=> {
                options.Authority = this.Configuration["IDS"];
                options.RequireHttpsMetadata = true;
                options.ClientId = "Desktop";
                options.ClientSecret = "secret";
                options.ResponseType = "code";
                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;

                options.Scope.Clear();
                options.Scope.Add("openid");
                options.Scope.Add("profile");
                options.Scope.Add("sms");
                options.Scope.Add("mail.send");
                options.Scope.Add("mail.search");
            });
    }

My Login code:

    [HttpPost]
    [Route("/Home/LoginPost")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> LoginPostAsync(LoginInputModel model)
    {
        var context = await Interaction.GetAuthorizationContextAsync(model.ReturnUrl);
        if (ModelState.IsValid)
        {
            //await this.signInManager.SignInAsync(new RWongAccountUser()
            //{
            //    PhoneNumber = model.Identity
            //},isPersistent:false);

            var signInResult = await this.signInManager.PasswordSignInAsync(model.Identity, model.Password, isPersistent: false, lockoutOnFailure: false);
                            

            if (signInResult.Succeeded)
            {
                var user = await this.userManager.FindByNameAsync(model.Identity);
                //await this.Events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.UserName, clientId: context?.Client.ClientId));
                await this.Events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.UserName, "Desktop"));
                return Content("Succeeded");
            }
            if (signInResult.IsLockedOut)
            {
                return Content("IsLockedOut");
            }
            if (signInResult.IsNotAllowed)
            {
                return Content("IsNotAllowed");
            }
        }
        return Content("Failed");
    }

When I want to get the current user name like this:User.Identity.Name, it returns empty. But I can get names from user claims.

How can I get the current user name via [User.Identity.Name] directly? Thanks!

Upvotes: 2

Views: 1469

Answers (1)

Tore Nestenius
Tore Nestenius

Reputation: 19981

Then Microsoft and IdentityServer have different opinion on what the name of the claims should be, so you need to point out, which claim is the name claim, by using:

    .AddJwtBearer(opt =>
    {
        opt.TokenValidationParameters.RoleClaimType = "roles";
        opt.TokenValidationParameters.NameClaimType = "name";

        ...

To debug claim issues, it can be very good to actually look at what does the access token actually contain? Use a tool like https://jwt.io/ to do that.

To complement this answer, I wrote a blog post that goes into more detail about this topic: Debugging JwtBearer Claim Problems in ASP.NET Core

Upvotes: 3

Related Questions