2 votes

IdentityServer4 Net Core 2 n'appelle pas le iProfileService personnalisé

J'ai mis à niveau mon projet Identity Server vers Net Core 2 et maintenant je ne suis pas en mesure d'obtenir l'objet iProfileService à appeler pour ajouter des revendications d'utilisateur personnalisées. Cela fonctionnait dans Net Core 1.

Fonction ConfigureServices de Startup.cs

            // Add application services.
        services.AddTransient<IEmailSender, AuthMessageSender>();
        services.AddTransient<ISmsSender, AuthMessageSender>();
        services.AddTransient<IProfileService, M25ProfileService>();

        //Load certificate
        var cert = new X509Certificate2(Path.Combine(_environment.ContentRootPath, "m25id-cert.pfx"), "mypassword");

        services.AddIdentityServer()
            .AddSigningCredential(cert)
            .AddConfigurationStore(options =>
            {
                options.ConfigureDbContext = builder =>
                    builder.UseSqlServer(connectionString,
                        sql => sql.MigrationsAssembly(migrationsAssembly));
            })
            .AddOperationalStore(options =>
            {
                options.ConfigureDbContext = builder =>
                    builder.UseSqlServer(connectionString,
                        sql => sql.MigrationsAssembly(migrationsAssembly));
                //options.EnableTokenCleanup = true;
                //options.TokenCleanupInterval = 30;
            })
            .AddProfileService<M25ProfileService>()
            .AddAspNetIdentity<ApplicationUser>();

M25ProfileService.cs

    public class M25ProfileService : IProfileService
{
    public M25ProfileService(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }

    public Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var user = _userManager.GetUserAsync(context.Subject).Result;

        var claims = new List<Claim>
        {
            new Claim(JwtClaimTypes.GivenName, user.FirstName),
            new Claim(JwtClaimTypes.FamilyName, user.LastName),
            new Claim(IdentityServerConstants.StandardScopes.Email, user.Email),
            new Claim("uid", user.Id),
            new Claim(JwtClaimTypes.ZoneInfo, user.TimeZone)
        };
        if (user.UserType != null) claims.Add(new Claim("mut", ((int)user.UserType).ToString()));
        context.IssuedClaims.AddRange(claims);
        return Task.FromResult(0);

    }

    public Task IsActiveAsync(IsActiveContext context)
    {
        var user = _userManager.GetUserAsync(context.Subject).Result;
        context.IsActive = user != null;
        return Task.FromResult(0);
    }
}

}

Config.cs

    public class Config
{
    // try adding claims to id token
    public static IEnumerable<IdentityResource> GetIdentityResources()
    {
        var m25Profile = new IdentityResource(
            "m25.profile", 
            "m25 Profile", 
            new[]
            {
                ClaimTypes.Name,
                ClaimTypes.Email,
                IdentityServerConstants.StandardScopes.OpenId,
                JwtClaimTypes.GivenName,
                JwtClaimTypes.FamilyName,
                IdentityServerConstants.StandardScopes.Email,
                "uid",
                JwtClaimTypes.ZoneInfo
            }
        );

        return new List<IdentityResource>
        {
            new IdentityResources.OpenId(),
            new IdentityResources.Profile(),
            new IdentityResources.Email(),
            m25Profile
        };
    }

    public static IEnumerable<ApiResource> GetApiResources()
    {
        //Try adding claims to access token
        return new List<ApiResource>
        {
            new ApiResource(
                "m25api",
                "message25 API",
                new[]
                {
                    ClaimTypes.Name,
                    ClaimTypes.Email,
                    IdentityServerConstants.StandardScopes.OpenId,
                    JwtClaimTypes.GivenName,
                    JwtClaimTypes.FamilyName,
                    IdentityServerConstants.StandardScopes.Email,
                    "uid",
                    JwtClaimTypes.ZoneInfo
                }
            )
        };
    }

    public static IEnumerable<Client> GetClients()
    {
        // client credentials client
        return new List<Client>
        {
            new Client
            {
                ClientId = "client",
                ClientName = "Client",
                AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

                ClientSecrets =
                {
                    new Secret("secret".Sha256())
                },
                AllowedScopes = new List<string>
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    IdentityServerConstants.StandardScopes.Email,
                    "m25api"
                }
            },

            // Local Development Client
            new Client
            {
                ClientId = "m25AppDev",
                ClientName = "me25",
                AllowedGrantTypes = GrantTypes.Implicit,
                AllowAccessTokensViaBrowser = true,
                RequireConsent = false,

                RedirectUris = { "http://localhost:4200/authorize.html" },
                PostLogoutRedirectUris = { "http://localhost:4200/index.html" },
                AllowedCorsOrigins = { "http://localhost:4200" },

                AllowedScopes =
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    IdentityServerConstants.StandardScopes.Email,
                    JwtClaimTypes.GivenName,
                    "mut",
                    "m25api"
                },
                AllowOfflineAccess = true,

                IdentityTokenLifetime = 300,
                AccessTokenLifetime = 86400
            }
        };
    }
}

La première chose que j'essaie de faire, c'est de faire en sorte que le serveur d'identité me permette de me connecter et d'afficher les demandes de l'utilisateur de manière similaire aux échantillons id4. Lorsque je me connecte, les demandes standard sont listées mais aucune des demandes personnalisées. J'ai placé des points d'arrêt dans la classe M25ProfileService mais ils ne sont jamais atteints. Il semble que ID4 n'utilise jamais la classe ProfileService du client, mais je l'ai dans mon fichier startup.cs.

J'ai également essayé à partir de mon client JS de test et j'ai obtenu les mêmes résultats. Voici un extrait de mon JS Client :

var config = {
    authority: "http://localhost:5000",
    client_id: "m25AppDev",
    redirect_uri: "http://localhost:4200/authorize.html",
    response_type: "id_token token",
    scope:"openid profile m25api",
    post_logout_redirect_uri : "http://localhost:4200/index.html"
};
var mgr = new Oidc.UserManager(config);

mgr.getUser().then(function (user) {
    if (user) {
        log("User logged in", user.profile);
        document.getElementById("accessToken").innerHTML = "Bearer " + user.access_token + "\r\n";
    }
    else {
        log("User not logged in");
    }
});

function login() {
    mgr.signinRedirect();
}

A ce stade, je ne suis pas sûr de ce qu'il faut essayer. Je pensais que si j'ajoutais les revendications au jeton d'identification (fonction GetIdentityResources() de ce que je comprends) et même au jeton d'accès (fonction GetApiResources() de ce que je comprends), je verrais les revendications mais rien ne semble fonctionner. Aidez-moi, s'il vous plaît ! Merci d'avance !

De plus, j'avais l'habitude de pouvoir obtenir les réclamations personnalisées de mon client ainsi que de la page d'index du serveur d'identité qui s'affiche après le journal.

4voto

leastprivilege Points 4949

Changez l'ordre de ces lignes de code :

.AddProfileService<M25ProfileService>()
.AddAspNetIdentity<ApplicationUser>();

L'un écrase l'autre.

2voto

206mph Points 96

J'ai trouvé la solution. Merci à un peu de code sur GitHub, j'ai pu comprendre ce qui me manquait. J'ai juste eu besoin d'ajouter ces 2 lignes à la configuration de chaque client dans config.cs et tout a fonctionné parfaitement !

AlwaysSendClientClaims = true,
AlwaysIncludeUserClaimsInIdToken = true

Cela fonctionne pour les clients distants. Cependant, je n'arrive toujours pas à le faire fonctionner lorsque je suis sur le serveur ID lui-même et que je me connecte (pas depuis un client). Ce n'est pas un gros problème pour l'instant, mais cela pourrait le devenir à l'avenir. Si/quand je trouve cette solution, j'essaierai de mettre à jour ma réponse. En attendant, j'espère que cela aidera d'autres personnes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X