mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-03-01 09:00:03 +01:00
105 lines
4.2 KiB
C#
105 lines
4.2 KiB
C#
|
using System.Collections.Generic;
|
||
|
using System.Security.Claims;
|
||
|
using System.Threading.Tasks;
|
||
|
using AspNet.Security.OpenIdConnect.Extensions;
|
||
|
using AspNet.Security.OpenIdConnect.Primitives;
|
||
|
using BTCPayServer.Models;
|
||
|
using Microsoft.AspNetCore.Authentication;
|
||
|
using Microsoft.AspNetCore.Identity;
|
||
|
using Microsoft.Extensions.Options;
|
||
|
using OpenIddict.Abstractions;
|
||
|
using OpenIddict.Server;
|
||
|
|
||
|
namespace BTCPayServer.Authentication.OpenId
|
||
|
{
|
||
|
public abstract class BaseOpenIdGrantHandler<T> : IOpenIddictServerEventHandler<T>
|
||
|
where T : class, IOpenIddictServerEvent
|
||
|
{
|
||
|
protected readonly SignInManager<ApplicationUser> _signInManager;
|
||
|
protected readonly IOptions<IdentityOptions> _identityOptions;
|
||
|
|
||
|
protected BaseOpenIdGrantHandler(SignInManager<ApplicationUser> signInManager,
|
||
|
IOptions<IdentityOptions> identityOptions)
|
||
|
{
|
||
|
_signInManager = signInManager;
|
||
|
_identityOptions = identityOptions;
|
||
|
}
|
||
|
|
||
|
protected async Task<AuthenticationTicket> CreateTicketAsync(
|
||
|
OpenIdConnectRequest request, ApplicationUser user,
|
||
|
AuthenticationProperties properties = null)
|
||
|
{
|
||
|
// Create a new ClaimsPrincipal containing the claims that
|
||
|
// will be used to create an id_token, a token or a code.
|
||
|
var principal = await _signInManager.CreateUserPrincipalAsync(user);
|
||
|
|
||
|
// Create a new authentication ticket holding the user identity.
|
||
|
var ticket = new AuthenticationTicket(principal, properties,
|
||
|
OpenIddictServerDefaults.AuthenticationScheme);
|
||
|
|
||
|
if (!request.IsAuthorizationCodeGrantType() && !request.IsRefreshTokenGrantType())
|
||
|
{
|
||
|
// Note: in this sample, the granted scopes match the requested scope
|
||
|
// but you may want to allow the user to uncheck specific scopes.
|
||
|
// For that, simply restrict the list of scopes before calling SetScopes.
|
||
|
ticket.SetScopes(request.GetScopes());
|
||
|
}
|
||
|
|
||
|
foreach (var claim in ticket.Principal.Claims)
|
||
|
{
|
||
|
claim.SetDestinations(GetDestinations(claim, ticket));
|
||
|
}
|
||
|
|
||
|
return ticket;
|
||
|
}
|
||
|
|
||
|
private IEnumerable<string> GetDestinations(Claim claim, AuthenticationTicket ticket)
|
||
|
{
|
||
|
// Note: by default, claims are NOT automatically included in the access and identity tokens.
|
||
|
// To allow OpenIddict to serialize them, you must attach them a destination, that specifies
|
||
|
// whether they should be included in access tokens, in identity tokens or in both.
|
||
|
|
||
|
|
||
|
switch (claim.Type)
|
||
|
{
|
||
|
case OpenIddictConstants.Claims.Name:
|
||
|
yield return OpenIddictConstants.Destinations.AccessToken;
|
||
|
|
||
|
if (ticket.HasScope(OpenIddictConstants.Scopes.Profile))
|
||
|
yield return OpenIddictConstants.Destinations.IdentityToken;
|
||
|
|
||
|
yield break;
|
||
|
|
||
|
case OpenIddictConstants.Claims.Email:
|
||
|
yield return OpenIddictConstants.Destinations.AccessToken;
|
||
|
|
||
|
if (ticket.HasScope(OpenIddictConstants.Scopes.Email))
|
||
|
yield return OpenIddictConstants.Destinations.IdentityToken;
|
||
|
|
||
|
yield break;
|
||
|
|
||
|
case OpenIddictConstants.Claims.Role:
|
||
|
yield return OpenIddictConstants.Destinations.AccessToken;
|
||
|
|
||
|
if (ticket.HasScope(OpenIddictConstants.Scopes.Roles))
|
||
|
yield return OpenIddictConstants.Destinations.IdentityToken;
|
||
|
|
||
|
yield break;
|
||
|
default:
|
||
|
if (claim.Type == _identityOptions.Value.ClaimsIdentity.SecurityStampClaimType)
|
||
|
{
|
||
|
// Never include the security stamp in the access and identity tokens, as it's a secret value.
|
||
|
yield break;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
yield return OpenIddictConstants.Destinations.AccessToken;
|
||
|
yield break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public abstract Task<OpenIddictServerEventState> HandleAsync(T notification);
|
||
|
}
|
||
|
}
|