Merge pull request #16537 from abpframework/IAbpOpenIddictClaimsPrincipalHandler

Refactor `ClaimsPrincipal` handle way of OpenIddict.
pull/16498/head
liangshiwei 2 years ago committed by GitHub
commit 748e1d5db6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -71,7 +71,13 @@ public class MyTokenExtensionGrant : ITokenExtensionGrant
var claimsPrincipal = await userClaimsPrincipalFactory.CreateAsync(user);
claimsPrincipal.SetScopes(principal.GetScopes());
claimsPrincipal.SetResources(await GetResourcesAsync(context, principal.GetScopes()));
//abp version < 7.3
await context.HttpContext.RequestServices.GetRequiredService<AbpOpenIddictClaimDestinationsManager>().SetAsync(principal);
//For abp version >= 7.3
await context.HttpContext.RequestServices.GetRequiredService<AbpOpenIddictClaimsPrincipalManager>().HandleAsync(context.Request, principal);
return new SignInResult(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, claimsPrincipal);
}

@ -323,16 +323,16 @@ Configure<TokenCleanupOptions>(options =>
[Claims Principal Factory](https://docs.abp.io/en/abp/latest/Authorization#claims-principal-factory) can be used to add/remove claims to the `ClaimsPrincipal`.
The `AbpDefaultOpenIddictClaimDestinationsProvider` service will add `Name`, `Email,` and `Role` types of Claims to `access_token` and `id_token`, other claims are only added to `access_token` by default, and remove the `SecurityStampClaimType` secret claim of `Identity`.
The `AbpDefaultOpenIddictClaimsPrincipalHandler` service will add `Name`, `Email,` and `Role` types of Claims to `access_token` and `id_token`, other claims are only added to `access_token` by default, and remove the `SecurityStampClaimType` secret claim of `Identity`.
Create a service that inherits from `IAbpOpenIddictClaimDestinationsProvider` and add it to DI to fully control the destinations of claims.
Create a service that inherits from `IAbpOpenIddictClaimsPrincipalHandler` and add it to DI to fully control the destinations of claims.
```cs
public class MyClaimDestinationsProvider : IAbpOpenIddictClaimDestinationsProvider, ITransientDependency
public class MyClaimDestinationsHandler : IAbpOpenIddictClaimsPrincipalHandler, ITransientDependency
{
public virtual Task SetDestinationsAsync(AbpOpenIddictClaimDestinationsProviderContext context)
public virtual Task HandleAsync(AbpOpenIddictClaimsPrincipalHandlerContext context)
{
foreach (var claim in context.Claims)
foreach (var claim in context.Principal.Claims)
{
if (claim.Type == MyClaims.MyClaimsType)
{
@ -351,7 +351,7 @@ public class MyClaimDestinationsProvider : IAbpOpenIddictClaimDestinationsProvid
Configure<AbpOpenIddictClaimDestinationsOptions>(options =>
{
options.ClaimDestinationsProvider.Add<MyClaimDestinationsProvider>();
options.ClaimsPrincipalHandlers.Add<MyClaimDestinationsHandler>();
});
```

@ -78,7 +78,7 @@ public class MyTokenExtensionGrant : ITokenExtensionGrant
var claimsPrincipal = await userClaimsPrincipalFactory.CreateAsync(user);
claimsPrincipal.SetScopes(principal.GetScopes());
claimsPrincipal.SetResources(await GetResourcesAsync(context, principal.GetScopes()));
await context.HttpContext.RequestServices.GetRequiredService<AbpOpenIddictClaimDestinationsManager>().SetAsync(principal);
await context.HttpContext.RequestServices.GetRequiredService<AbpOpenIddictClaimsPrincipalManager>().HandleAsync(context.Request, principal);
return new SignInResult(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, claimsPrincipal);
}

@ -22,9 +22,9 @@ public class AbpOpenIddictAspNetCoreModule : AbpModule
{
AddOpenIddictServer(context.Services);
Configure<AbpOpenIddictClaimDestinationsOptions>(options =>
Configure<AbpOpenIddictClaimsPrincipalOptions>(options =>
{
options.ClaimDestinationsProvider.Add<AbpDefaultOpenIddictClaimDestinationsProvider>();
options.ClaimsPrincipalHandlers.Add<AbpDefaultOpenIddictClaimsPrincipalHandler>();
});
Configure<RazorViewEngineOptions>(options =>

@ -1,32 +0,0 @@
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.OpenIddict;
public class AbpOpenIddictClaimDestinationsManager : ISingletonDependency
{
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected IOptions<AbpOpenIddictClaimDestinationsOptions> Options { get; }
public AbpOpenIddictClaimDestinationsManager(IServiceScopeFactory serviceScopeFactory, IOptions<AbpOpenIddictClaimDestinationsOptions> options)
{
ServiceScopeFactory = serviceScopeFactory;
Options = options;
}
public virtual async Task SetAsync(ClaimsPrincipal principal)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
foreach (var providerType in Options.Value.ClaimDestinationsProvider)
{
var provider = (IAbpOpenIddictClaimDestinationsProvider)scope.ServiceProvider.GetRequiredService(providerType);
await provider.SetDestinationsAsync(new AbpOpenIddictClaimDestinationsProviderContext(scope.ServiceProvider, principal, principal.Claims.ToArray()));
}
}
}
}

@ -1,13 +0,0 @@
using Volo.Abp.Collections;
namespace Volo.Abp.OpenIddict;
public class AbpOpenIddictClaimDestinationsOptions
{
public ITypeList<IAbpOpenIddictClaimDestinationsProvider> ClaimDestinationsProvider { get; }
public AbpOpenIddictClaimDestinationsOptions()
{
ClaimDestinationsProvider = new TypeList<IAbpOpenIddictClaimDestinationsProvider>();
}
}

@ -1,20 +0,0 @@
using System;
using System.Security.Claims;
namespace Volo.Abp.OpenIddict;
public class AbpOpenIddictClaimDestinationsProviderContext
{
public IServiceProvider ScopeServiceProvider { get; }
public ClaimsPrincipal Principal{ get;}
public Claim[] Claims { get; }
public AbpOpenIddictClaimDestinationsProviderContext(IServiceProvider scopeServiceProvider, ClaimsPrincipal principal, Claim[] claims)
{
ScopeServiceProvider = scopeServiceProvider;
Principal = principal;
Claims = claims;
}
}

@ -1,8 +0,0 @@
using System.Threading.Tasks;
namespace Volo.Abp.OpenIddict;
public interface IAbpOpenIddictClaimDestinationsProvider
{
Task SetDestinationsAsync(AbpOpenIddictClaimDestinationsProviderContext context);
}

@ -9,16 +9,16 @@ using Volo.Abp.Security.Claims;
namespace Volo.Abp.OpenIddict;
public class AbpDefaultOpenIddictClaimDestinationsProvider : IAbpOpenIddictClaimDestinationsProvider, ITransientDependency
public class AbpDefaultOpenIddictClaimsPrincipalHandler : IAbpOpenIddictClaimsPrincipalHandler, ITransientDependency
{
public virtual Task SetDestinationsAsync(AbpOpenIddictClaimDestinationsProviderContext context)
public virtual Task HandleAsync(AbpOpenIddictClaimsPrincipalHandlerContext context)
{
var securityStampClaimType = context
.ScopeServiceProvider
.GetRequiredService<IOptions<IdentityOptions>>().Value
.ClaimsIdentity.SecurityStampClaimType;
foreach (var claim in context.Claims)
foreach (var claim in context.Principal.Claims)
{
if (claim.Type == AbpClaimTypes.TenantId)
{

@ -0,0 +1,21 @@
using System;
using System.Security.Claims;
using OpenIddict.Abstractions;
namespace Volo.Abp.OpenIddict;
public class AbpOpenIddictClaimsPrincipalHandlerContext
{
public IServiceProvider ScopeServiceProvider { get; }
public OpenIddictRequest OpenIddictRequest { get; }
public ClaimsPrincipal Principal { get;}
public AbpOpenIddictClaimsPrincipalHandlerContext(IServiceProvider scopeServiceProvider, OpenIddictRequest openIddictRequest, ClaimsPrincipal principal)
{
ScopeServiceProvider = scopeServiceProvider;
OpenIddictRequest = openIddictRequest;
Principal = principal;
}
}

@ -0,0 +1,32 @@
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OpenIddict.Abstractions;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.OpenIddict;
public class AbpOpenIddictClaimsPrincipalManager : ISingletonDependency
{
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected IOptions<AbpOpenIddictClaimsPrincipalOptions> Options { get; }
public AbpOpenIddictClaimsPrincipalManager(IServiceScopeFactory serviceScopeFactory, IOptions<AbpOpenIddictClaimsPrincipalOptions> options)
{
ServiceScopeFactory = serviceScopeFactory;
Options = options;
}
public virtual async Task HandleAsync(OpenIddictRequest openIddictRequest, ClaimsPrincipal principal)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
foreach (var providerType in Options.Value.ClaimsPrincipalHandlers)
{
var provider = (IAbpOpenIddictClaimsPrincipalHandler)scope.ServiceProvider.GetRequiredService(providerType);
await provider.HandleAsync(new AbpOpenIddictClaimsPrincipalHandlerContext(scope.ServiceProvider, openIddictRequest, principal));
}
}
}
}

@ -0,0 +1,13 @@
using Volo.Abp.Collections;
namespace Volo.Abp.OpenIddict;
public class AbpOpenIddictClaimsPrincipalOptions
{
public ITypeList<IAbpOpenIddictClaimsPrincipalHandler> ClaimsPrincipalHandlers { get; }
public AbpOpenIddictClaimsPrincipalOptions()
{
ClaimsPrincipalHandlers = new TypeList<IAbpOpenIddictClaimsPrincipalHandler>();
}
}

@ -0,0 +1,8 @@
using System.Threading.Tasks;
namespace Volo.Abp.OpenIddict;
public interface IAbpOpenIddictClaimsPrincipalHandler
{
Task HandleAsync(AbpOpenIddictClaimsPrincipalHandlerContext context);
}

@ -25,7 +25,7 @@ public abstract class AbpOpenIdDictControllerBase : AbpController
protected IOpenIddictAuthorizationManager AuthorizationManager => LazyServiceProvider.LazyGetRequiredService<IOpenIddictAuthorizationManager>();
protected IOpenIddictScopeManager ScopeManager => LazyServiceProvider.LazyGetRequiredService<IOpenIddictScopeManager>();
protected IOpenIddictTokenManager TokenManager => LazyServiceProvider.LazyGetRequiredService<IOpenIddictTokenManager>();
protected AbpOpenIddictClaimDestinationsManager OpenIddictClaimDestinationsManager => LazyServiceProvider.LazyGetRequiredService<AbpOpenIddictClaimDestinationsManager>();
protected AbpOpenIddictClaimsPrincipalManager OpenIddictClaimsPrincipalManager => LazyServiceProvider.LazyGetRequiredService<AbpOpenIddictClaimsPrincipalManager>();
protected AbpOpenIdDictControllerBase()
{
@ -55,11 +55,6 @@ public abstract class AbpOpenIdDictControllerBase : AbpController
return resources;
}
protected virtual async Task SetClaimsDestinationsAsync(ClaimsPrincipal principal)
{
await OpenIddictClaimDestinationsManager.SetAsync(principal);
}
protected virtual async Task<bool> HasFormValueAsync(string name)
{
if (Request.HasFormContentType)

@ -132,7 +132,7 @@ public class AuthorizeController : AbpOpenIdDictControllerBase
principal.SetAuthorizationId(await AuthorizationManager.GetIdAsync(authorization));
await SetClaimsDestinationsAsync(principal);
await OpenIddictClaimsPrincipalManager.HandleAsync(request, principal);
return SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
@ -227,7 +227,7 @@ public class AuthorizeController : AbpOpenIdDictControllerBase
principal.SetScopes(request.GetScopes());
principal.SetResources(await GetResourcesAsync(request.GetScopes()));
await SetClaimsDestinationsAsync(principal);
await OpenIddictClaimsPrincipalManager.HandleAsync(request, principal);
// Returning a SignInResult will ask OpenIddict to issue the appropriate access/identity tokens.
return SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);

@ -44,7 +44,7 @@ public partial class TokenController
}));
}
await SetClaimsDestinationsAsync(principal);
await OpenIddictClaimsPrincipalManager.HandleAsync(request, principal);
// Returning a SignInResult will ask OpenIddict to issue the appropriate access/identity tokens.
return SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);

@ -44,7 +44,7 @@ public partial class TokenController
}));
}
await SetClaimsDestinationsAsync(principal);
await OpenIddictClaimsPrincipalManager.HandleAsync(request, principal);
// Returning a SignInResult will ask OpenIddict to issue the appropriate access/identity tokens.
return SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);

@ -323,7 +323,7 @@ public partial class TokenController
principal.SetScopes(request.GetScopes());
principal.SetResources(await GetResourcesAsync(request.GetScopes()));
await SetClaimsDestinationsAsync(principal);
await OpenIddictClaimsPrincipalManager.HandleAsync(request, principal);
await IdentitySecurityLogManager.SaveAsync(
new IdentitySecurityLogContext

@ -44,7 +44,7 @@ public partial class TokenController
}));
}
await SetClaimsDestinationsAsync(principal);
await OpenIddictClaimsPrincipalManager.HandleAsync(request, principal);
// Returning a SignInResult will ask OpenIddict to issue the appropriate access/identity tokens.
return SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);

Loading…
Cancel
Save