I currently have an authentication system based on Identity server 4 (code in .net core), my system works and I have several applications developed in .net that are connected to it. I've been asked to make it possible to use my server to connect to a Wordpress application. I added the mini orange OAuth/OpenID Connect Single Sign On plugin to manage my connection. It works fine. My problem is with retrieving the user's login information. In mini orange's connection test interface, the only value displayed is "sub". I searched, but couldn't find a way to make the other user information (email, first name, last name) appear.
Program.cs of my identity server
builder.Services.AddRazorPages();
builder.Services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
builder.Services.AddIdentityServer()
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = optionsBuilder =>
optionsBuilder.UseSqlServer(configuration.GetConnectionString("BddConnectContext"),
sql => sql.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name));
})
.AddDeveloperSigningCredential()
.AddProfileService<ProfileService>();
builder.Services.AddTransient<IUtilisateurRepository, UtilisateurRepository>();
builder.Services.AddDbContext<BddContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("BddContext")));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseIdentityServer();
app.MapRazorPages().RequireAuthorization();
app.UseEndpoints(option =>
{
option.MapControllerRoute(
name: "default",
pattern: "{controller=Login}/{action=Index}/{id?}"
);
});
app.Run();
I'm not sure if this information is enough, but if it's missing I could add it without any problem.
EDIT
Below is the general configuration of my client
{
"AbsoluteRefreshTokenLifetime": 2592000,
"AccessTokenLifetime": 3600,
"AccessTokenType": 0,
"AllowAccessTokensViaBrowser": false,
"AllowOfflineAccess": true,
"AllowPlainTextPkce": false,
"AllowRememberConsent": true,
"AllowedCorsOrigins": [],
"AllowedGrantTypes": [
"implicit"
],
"AllowedIdentityTokenSigningAlgorithms": [],
"AllowedScopes": [
"email",
"openid",
"profile"
],
"AlwaysIncludeUserClaimsInIdToken": true,
"AlwaysSendClientClaims": false,
"AuthorizationCodeLifetime": 300,
"BackChannelLogoutSessionRequired": true,
"BackChannelLogoutUri": null,
"CibaLifetime": null,
"Claims": [],
"ClientClaimsPrefix": "client_",
"ClientId": "wordpress",
"ClientName": "My WordPress",
"ClientSecrets": [],
"ClientUri": null,
"ConsentLifetime": null,
"CoordinateLifetimeWithUserSession": false,
"Description": null,
"DeviceCodeLifetime": 300,
"EnableLocalLogin": true,
"Enabled": true,
"FrontChannelLogoutSessionRequired": true,
"FrontChannelLogoutUri": null,
"IdentityProviderRestrictions": [],
"IdentityTokenLifetime": 300,
"IncludeJwtId": false,
"LogoUri": null,
"PairWiseSubjectSalt": null,
"PollingInterval": 0,
"PostLogoutRedirectUris": [
"https://sandbox.miniorange.com/signout-callback-oidc"
],
"Properties": {},
"ProtocolType": "oidc",
"RedirectUris": [
"https://sandbox.miniorange.com/314cfc5"
],
"RefreshTokenExpiration": 1,
"RefreshTokenUsage": 1,
"RequireClientSecret": true,
"RequireConsent": false,
"RequirePkce": false,
"RequireRequestObject": false,
"SlidingRefreshTokenLifetime": 1296000,
"UpdateAccessTokenClaimsOnRefresh": false,
"UserCodeType": null,
"UserSsoLifetime": null
}
I also put the configuration of my identity server if it helps
{
"authorization_endpoint": "https://my-server.com/connect/authorize",
"authorization_response_iss_parameter_supported": true,
"backchannel_authentication_endpoint": "https://my-server.com/connect/ciba",
"backchannel_logout_session_supported": true,
"backchannel_logout_supported": true,
"backchannel_token_delivery_modes_supported": [
"poll"
],
"backchannel_user_code_parameter_supported": true,
"check_session_iframe": "https://my-server.com/connect/checksession",
"claims_supported": [
"sub",
"name",
"email",
"birthdate",
"family_name",
"gender",
"given_name",
"locale",
"middle_name",
"nickname",
"picture",
"preferred_username",
"profile",
"updated_at",
"website",
"zoneinfo"
],
"code_challenge_methods_supported": [
"plain",
"S256"
],
"device_authorization_endpoint": "https://my-server.com/connect/deviceauthorization",
"end_session_endpoint": "https://my-server.com/connect/endsession",
"frontchannel_logout_session_supported": true,
"frontchannel_logout_supported": true,
"grant_types_supported": [
"authorization_code",
"client_credentials",
"refresh_token",
"implicit",
"urn:ietf:params:oauth:grant-type:device_code",
"urn:openid:params:grant-type:ciba"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"introspection_endpoint": "https://my-server.com/connect/introspect",
"issuer": "https://my-server.com",
"jwks_uri": "https://my-server.com/.well-known/openid-configuration/jwks",
"request_object_signing_alg_values_supported": [
"RS256",
"RS384",
"RS512",
"PS256",
"PS384",
"PS512",
"ES256",
"ES384",
"ES512",
"HS256",
"HS384",
"HS512"
],
"request_parameter_supported": true,
"response_modes_supported": [
"form_post",
"query",
"fragment"
],
"response_types_supported": [
"code",
"token",
"id_token",
"id_token token",
"code id_token",
"code token",
"code id_token token"
],
"revocation_endpoint": "https://my-server.com/connect/revocation",
"scopes_supported": [
"openid",
"profile",
"email",
"offline_access"
],
"subject_types_supported": [
"public"
],
"token_endpoint": "https://my-server.com/connect/token",
"token_endpoint_auth_methods_supported": [
"client_secret_basic",
"client_secret_post"
],
"userinfo_endpoint": "https://my-server.com/connect/userinfo"
}
My ProfileService
public class ProfileService : IProfileService
{
private readonly IUserCustomRepository _userRepository;
public ProfileService(IUserCustomRepository userRepository)
{
_userRepository = userRepository;
}
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var idUserCustom = context.Subject.FindFirst(x => x.Type == "IdUserCustom");
if (idUserCustom != null)
{
var utilisateur = _userRepository.GetUserCustomById(int.Parse(idUserCustom.Value));
if (utilisateur != null)
{
var listAppli = _userRepository.ListApplicationUser(utilisateur).OrderBy(x => x.RangAffichage).ToList();
context.IssuedClaims = GetClaims(utilisateur, listAppli);
}
}
return Task.FromResult(0);
}
public Task IsActiveAsync(IsActiveContext context)
{
return Task.FromResult(0);
}
private List<Claim> GetClaims(UserCustom customUser, List<Application> listAppli)
{
var result = new List<Claim>
{
new(JwtClaimTypes.Name, customUser.PrenomUserCustom ?? ""),
new(JwtClaimTypes.FamilyName, customUser.NomUserCustom ?? ""),
new(JwtClaimTypes.Email, customUser.EmailUserCustom ?? ""),
new("Login", customUser.LoginUserCustom),
new("UserCustom", JsonConvert.SerializeObject(customUser))
};
if (listAppli.Count > 0)
{
foreach (var appli in listAppli)
{
var item = new Claim("Application", appli.LibelleApplication);
result.Add(item);
}
}
return result;
}
}
Thank you in advance for your answers.