4
votes

I'm trying to get IdentityServer4 get to work with ASP.NET Core Identity using my own UserStore for SSO. While the guides seem rather straightforward, and the authentication process itself seems to work, in the application (another ASP.NET Core MVC application) I get the following error:

Error loading external login information

My setup is as follows:

For the ASP.NET MVC application (the client):

services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies", options =>
{
    options.ExpireTimeSpan =TimeSpan.FromMinutes(30);
})
.AddOpenIdConnect("oidc", options =>
{
    options.SignInScheme = "Cookies";

    options.Authority = "https://localhost:5001/";

    options.ClientId = "clientId";
    options.ClientSecret = "secret";
    options.SaveTokens = true;
    options.ResponseType = "code id_token";
    options.Scope.Add(IdentityServerConstants.StandardScopes.Profile);
    options.Scope.Add(IdentityServerConstants.StandardScopes.Email);
    options.Scope.Add(IdentityServerConstants.StandardScopes.OfflineAccess);

    options.GetClaimsFromUserInfoEndpoint = true;
});

For the IdentityServer4 application:

services.AddScoped<UserManager<User>, MyUserManager>();
services.AddIdentity<User, UserGroup>()
    .AddRoleStore<MyRoleStore>()
    .AddUserStore<MyUserStore>()
    .AddDefaultTokenProviders();

services.Configure<IdentityOptions>(options =>
{
    options.ClaimsIdentity.UserIdClaimType = JwtClaimTypes.Subject;
    options.ClaimsIdentity.UserNameClaimType = JwtClaimTypes.Name;
    options.ClaimsIdentity.RoleClaimType = JwtClaimTypes.Role;
});

services.AddIdentityServer()
    .AddDeveloperSigningCredential()
    .AddInMemoryApiResources(OpenIDConfig.GetApiResources())
    .AddInMemoryIdentityResources(OpenIDConfig.GetIdentityResources())
    .AddInMemoryClients(OpenIDConfig.GetClients())
    .AddResourceOwnerValidator<ResourceOwnerPasswordValidator<User>>()
    .AddProfileService<ProfileService<User>>();

The main issue is that I don't know where to even start looking for why there is a problem with this after a successful authentication flow.

1
Can you add the code of the ProfileService? That's where I would start to look. - Ruard van Elburg
ProfileService<T> is part of IdentityServer4 - Daniel Rusznyak
Can you disable options.GetClaimsFromUserInfoEndpoint flag in MVC client and try whether it works? As previous @RuardvanElburg mentioned most probably there's a issue with ProfileService implementation in IdentityServer. - tha4
@ThomasLevesque Not for IS4, but I've found a similar issue with Google and the problem was that on certain platforms and in certain browsers, you have to disable SameSite for external cookies, since "Lax" isn't properly supported. services.ConfigureExternalCookie(options => { options.Cookie.SameSite = SameSiteMode.None; }); - Daniel Rusznyak
@DanielRusznyak in fact the problem was that I was changing the default SignInScheme in the Google options. It has to be IdentityConstants.ExternalScheme, because that's what SignInManager.GetExternalLoginInfoAsync uses. - Thomas Levesque

1 Answers

4
votes

Since it does help me - but I've almost missed anserw which was in comment I'll put it here. Comment is made by @Thomas Levesque and you might thank him for that ansertw ;-)

in fact the problem was that I was changing the default SignInScheme in the Google options. It has to be IdentityConstants.ExternalScheme, because that's what SignInManager.GetExternalLoginInfoAsync uses.