1
votes

I am using this Angular Lib for OpenID Connect Code Flow with PKCE to create an SPA with openid connect authentication. Further I am using the identity server 4.

OIDC Config in SPA

{
"stsServer": "http://localhost:5000",
"redirect_url": "http://localhost:4200",
"client_id": "angularclient",
"response_type": "code",
"scope": "openid profile email address phone api1",
"post_logout_redirect_uri": "http://localhost:4200",
"start_checksession": true,
"silent_renew": true,
"silent_renew_url": "http://localhost:4200/silent-renew.html",
"post_login_route": "/home",
"forbidden_route": "/forbidden",
"unauthorized_route": "/unauthorized",
"log_console_warning_active": true,
"log_console_debug_active": true,
"max_id_token_iat_offset_allowed_in_seconds": 10
}

OIDC Config of Identiy Server

new Client
{
    ClientName = "angularclient",
    ClientId = "angularclient",
    AccessTokenType = AccessTokenType.Reference,
    // RequireConsent = false,
    AccessTokenLifetime = 3600,// 330 seconds, default 60 minutes
    IdentityTokenLifetime = 3600,

    RequireClientSecret = false,
    AllowedGrantTypes = GrantTypes.Code,
    RequirePkce = true,

    AllowAccessTokensViaBrowser = true,
    RedirectUris = new List<string>
    {
        "http://localhost:4200",
        "http://localhost:4200/callback.html",
        "http://localhost:4200/silent-renew.html"
    },
    PostLogoutRedirectUris = new List<string>
    {
        "http://localhost:4200/",
        "http://localhost:4200"
    },
    AllowedCorsOrigins = new List<string>
    {
        "http://localhost:4200"
    },
    AllowedScopes = new List<string>
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        IdentityServerConstants.StandardScopes.Email,
        IdentityServerConstants.StandardScopes.Address,
        IdentityServerConstants.StandardScopes.Phone,
        "api1"
    }
}

When I am accessing the userinfo_endpoint only the sub claim is returned.

{ "sub": "818727" }

What I am missing in my configuration? Do I have to configure the claims which are returned from userinfo_endpoint?

1
How is your IProfileService implemented? That’s where claims are retrieved/formed docs.identityserver.io/en/latest/reference/profileservice.htmlRandy
You need to either implement IProfileService or set the claims along with signinShantanu

1 Answers

1
votes

With the CustomProfileService the claims are returned. Thanks to @Randy and @Shantanu for the hint.

public class CustomProfileService : IProfileService
{
    private readonly TestUserStore _users;

    public CustomProfileService(TestUserStore users = null)
    {
        _users = users ?? new TestUserStore(TestUsers.Users);
    }

    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var sub = context.Subject.FindFirst("sub").Value;
        if (sub != null)
        {
            var user = _users.FindBySubjectId(sub);
            var claimsPrincipal = await GetClaimsAsync(user);
            var claims = claimsPrincipal.Claims.ToList();

            if (context.RequestedClaimTypes != null && context.RequestedClaimTypes.Any())
            {
                claims = claims.Where(x => context.RequestedClaimTypes.Contains(x.Type)).ToList();
            }

            context.IssuedClaims = claims;
        }
    }

    public async Task IsActiveAsync(IsActiveContext context)
    {
    }

    private async Task<ClaimsPrincipal> GetClaimsAsync(TestUser user)
    {
        if (user == null)
        {
            throw new ArgumentNullException(nameof(user));
        }

        return await Task.Factory.StartNew(() =>
        {
            var claimsIdentity = new ClaimsIdentity();
            claimsIdentity.AddClaims(user.Claims);

            return new ClaimsPrincipal(claimsIdentity);
        });
    }
}

Startup.cs

builder.Services.AddTransient<IProfileService, CustomProfileService>();