Alastair Crabtree
5 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with
48 additions and
3 deletions
backend/src/Squidex.Infrastructure/Security/Extensions.cs
backend/src/Squidex/Areas/IdentityServer/Controllers/Account/AccountController.cs
backend/src/Squidex/Areas/IdentityServer/Controllers/Extensions.cs
backend/src/Squidex/Config/Authentication/OidcHandler.cs
backend/src/Squidex/Config/Authentication/OidcServices.cs
backend/src/Squidex/Config/MyIdentityOptions.cs
backend/src/Squidex/appsettings.json
@ -67,6 +67,12 @@ namespace Squidex.Infrastructure.Security
return principal . Claims . FirstOrDefault ( x = > x . Type = = OpenIdClaims . Email ) ? . Value ;
return principal . Claims . FirstOrDefault ( x = > x . Type = = OpenIdClaims . Email ) ? . Value ;
}
}
public static string? TryFindEmail ( this ClaimsPrincipal principal )
{
return principal . Claims . FirstOrDefault ( x = > x . Type = = ClaimTypes . Email ) ? . Value ? ?
principal . Claims . FirstOrDefault ( x = > x . Type = = OpenIdClaims . Email ) ? . Value ;
}
public static bool IsInClient ( this ClaimsPrincipal principal , string client )
public static bool IsInClient ( this ClaimsPrincipal principal , string client )
{
{
return principal . Claims . Any ( x = > x . Type = = OpenIdClaims . ClientId & & string . Equals ( x . Value , client , StringComparison . OrdinalIgnoreCase ) ) ;
return principal . Claims . Any ( x = > x . Type = = OpenIdClaims . ClientId & & string . Equals ( x . Value , client , StringComparison . OrdinalIgnoreCase ) ) ;
@ -294,7 +294,7 @@ namespace Squidex.Areas.IdentityServer.Controllers.Account
}
}
else
else
{
{
var email = externalLogin . Principal . FindFirst ( ClaimTypes . Email ) ? . Value ! ;
var email = externalLogin . Principal . TryFindEmail ( ) ;
user = await userManager . FindByEmailWithClaimsAsync ( email ) ;
user = await userManager . FindByEmailWithClaimsAsync ( email ) ;
@ -12,6 +12,7 @@ using System.Security.Claims;
using System.Threading.Tasks ;
using System.Threading.Tasks ;
using Microsoft.AspNetCore.Authentication.OpenIdConnect ;
using Microsoft.AspNetCore.Authentication.OpenIdConnect ;
using Microsoft.AspNetCore.Identity ;
using Microsoft.AspNetCore.Identity ;
using Squidex.Infrastructure.Security ;
using Squidex.Web ;
using Squidex.Web ;
namespace Squidex.Areas.IdentityServer.Controllers
namespace Squidex.Areas.IdentityServer.Controllers
@ -22,7 +23,7 @@ namespace Squidex.Areas.IdentityServer.Controllers
{
{
var externalLogin = await signInManager . GetExternalLoginInfoAsync ( expectedXsrf ) ;
var externalLogin = await signInManager . GetExternalLoginInfoAsync ( expectedXsrf ) ;
var email = externalLogin . Principal . FindFirst ( ClaimTypes . Email ) ? . Value ;
var email = externalLogin . Principal . TryFindEmail ( ) ;
if ( string . IsNullOrWhiteSpace ( email ) )
if ( string . IsNullOrWhiteSpace ( email ) )
{
{
@ -40,5 +40,19 @@ namespace Squidex.Config.Authentication
return base . TokenValidated ( context ) ;
return base . TokenValidated ( context ) ;
}
}
public override Task RedirectToIdentityProviderForSignOut ( RedirectContext context )
{
if ( ! string . IsNullOrEmpty ( options . OidcOnSignoutRedirectUrl ) )
{
var logoutUri = options . OidcOnSignoutRedirectUrl ;
context . Response . Redirect ( logoutUri ) ;
context . HandleResponse ( ) ;
return Task . CompletedTask ;
}
return base . RedirectToIdentityProviderForSignOut ( context ) ;
}
}
}
}
}
@ -24,9 +24,21 @@ namespace Squidex.Config.Authentication
options . Authority = identityOptions . OidcAuthority ;
options . Authority = identityOptions . OidcAuthority ;
options . ClientId = identityOptions . OidcClient ;
options . ClientId = identityOptions . OidcClient ;
options . ClientSecret = identityOptions . OidcSecret ;
options . ClientSecret = identityOptions . OidcSecret ;
options . RequireHttpsMetadata = false ;
options . RequireHttpsMetadata = identityOptions . RequiresHttps ;
options . Events = new OidcHandler ( identityOptions ) ;
options . Events = new OidcHandler ( identityOptions ) ;
if ( ! string . IsNullOrEmpty ( identityOptions . OidcMetadataAddress ) )
{
options . MetadataAddress = identityOptions . OidcMetadataAddress ;
}
if ( ! string . IsNullOrEmpty ( identityOptions . OidcResponseType ) )
{
options . ResponseType = identityOptions . OidcResponseType ;
}
options . GetClaimsFromUserInfoEndpoint = identityOptions . OidcGetClaimsFromUserInfoEndpoint ;
if ( identityOptions . OidcScopes ! = null )
if ( identityOptions . OidcScopes ! = null )
{
{
foreach ( var scope in identityOptions . OidcScopes )
foreach ( var scope in identityOptions . OidcScopes )
@ -47,12 +47,20 @@ namespace Squidex.Config
public string OidcAuthority { get ; set ; }
public string OidcAuthority { get ; set ; }
public string OidcMetadataAddress { get ; set ; }
public string OidcRoleClaimType { get ; set ; }
public string OidcRoleClaimType { get ; set ; }
public string [ ] OidcScopes { get ; set ; }
public string [ ] OidcScopes { get ; set ; }
public string OidcResponseType { get ; set ; }
public bool OidcGetClaimsFromUserInfoEndpoint { get ; set ; }
public Dictionary < string , string [ ] > OidcRoleMapping { get ; set ; }
public Dictionary < string , string [ ] > OidcRoleMapping { get ; set ; }
public string OidcOnSignoutRedirectUrl { get ; set ; }
public bool AdminRecreate { get ; set ; }
public bool AdminRecreate { get ; set ; }
public bool AllowPasswordAuth { get ; set ; }
public bool AllowPasswordAuth { get ; set ; }
@ -648,9 +648,13 @@
"oidcAuthority" : "" ,
"oidcAuthority" : "" ,
"oidcClient" : "" ,
"oidcClient" : "" ,
"oidcSecret" : "" ,
"oidcSecret" : "" ,
"oidcMetadataAddress" : "" ,
"oidcScopes" : [
"oidcScopes" : [
"email"
"email"
] ,
] ,
"oidcResponseType" : "id_token" , / / o r "code"
"oidcGetClaimsFromUserInfoEndpoint" : false ,
"oidcOnSignoutRedirectUrl" : "" ,
/ *
/ *
* L o c k n e w u s e r s a u t o m a t i c a l l y , t h e a d m i n i s t r a t o r m u s t u n l o c k t h e m .
* L o c k n e w u s e r s a u t o m a t i c a l l y , t h e a d m i n i s t r a t o r m u s t u n l o c k t h e m .