diff --git a/src/Api/IdentityServer/ProfileService.cs b/src/Api/IdentityServer/ProfileService.cs index 93b7c172ac..85b2893461 100644 --- a/src/Api/IdentityServer/ProfileService.cs +++ b/src/Api/IdentityServer/ProfileService.cs @@ -30,11 +30,13 @@ namespace Bit.Api.IdentityServer public async Task GetProfileDataAsync(ProfileDataRequestContext context) { - var claims = context.Subject.Claims.ToList(); + var existingClaims = context.Subject.Claims; + var newClaims = new List(); + var user = await _userService.GetUserByPrincipalAsync(context.Subject); if(user != null) { - claims.AddRange(new List + newClaims.AddRange(new List { new Claim("plan", "0"), // free plan hard coded for now new Claim("sstamp", user.SecurityStamp), @@ -47,13 +49,18 @@ namespace Bit.Api.IdentityServer if(!string.IsNullOrWhiteSpace(user.Name)) { - claims.Add(new Claim("name", user.Name)); + newClaims.Add(new Claim("name", user.Name)); } } - if(claims.Count > 0) + // filter out any of the new claims + var existingClaimsToKeep = existingClaims + .Where(c => newClaims.Count == 0 || !newClaims.Any(nc => nc.Type == c.Type)).ToList(); + + newClaims.AddRange(existingClaimsToKeep); + if(newClaims.Any()) { - context.AddFilteredClaims(claims); + context.AddFilteredClaims(newClaims); } } diff --git a/src/Api/IdentityServer/ResourceOwnerPasswordValidator.cs b/src/Api/IdentityServer/ResourceOwnerPasswordValidator.cs index e0c9221fdd..bb84b7ab28 100644 --- a/src/Api/IdentityServer/ResourceOwnerPasswordValidator.cs +++ b/src/Api/IdentityServer/ResourceOwnerPasswordValidator.cs @@ -7,10 +7,8 @@ using IdentityServer4.Models; using IdentityServer4.Validation; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Authentication; using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using System; @@ -28,20 +26,22 @@ namespace Bit.Api.IdentityServer private JwtBearerOptions _jwtBearerOptions; private JwtBearerIdentityOptions _jwtBearerIdentityOptions; private readonly IDeviceRepository _deviceRepository; - private readonly IHttpContextAccessor _httpContextAccessor; public ResourceOwnerPasswordValidator( - IDeviceRepository deviceRepository, - IHttpContextAccessor httpContextAccessor) + UserManager userManager, + IOptions identityOptionsAccessor, + IOptions jwtIdentityOptionsAccessor, + IDeviceRepository deviceRepository) { + _userManager = userManager; + _identityOptions = identityOptionsAccessor?.Value ?? new IdentityOptions(); + _jwtBearerIdentityOptions = jwtIdentityOptionsAccessor?.Value; + _jwtBearerOptions = Core.Identity.JwtBearerAppBuilderExtensions.BuildJwtBearerOptions(_jwtBearerIdentityOptions); _deviceRepository = deviceRepository; - _httpContextAccessor = httpContextAccessor; } public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { - Init(); - var oldAuthBearer = context.Request.Raw["OldAuthBearer"]?.ToString(); var twoFactorToken = context.Request.Raw["TwoFactorToken"]?.ToString(); var twoFactorProvider = context.Request.Raw["TwoFactorProvider"]?.ToString(); @@ -97,17 +97,6 @@ namespace Bit.Api.IdentityServer BuildErrorResult(twoFactorRequest, context); } - private void Init() - { - var httpContext = _httpContextAccessor.HttpContext; - _userManager = httpContext.RequestServices.GetRequiredService>(); - _identityOptions = - httpContext.RequestServices.GetRequiredService>()?.Value ?? new IdentityOptions(); - _jwtBearerIdentityOptions = - httpContext.RequestServices.GetRequiredService>()?.Value; - _jwtBearerOptions = Core.Identity.JwtBearerAppBuilderExtensions.BuildJwtBearerOptions(_jwtBearerIdentityOptions); - } - private void BuildSuccessResult(User user, ResourceOwnerPasswordValidationContext context, Device device) { var claims = new List diff --git a/src/Api/Startup.cs b/src/Api/Startup.cs index 6d6498e220..924625955a 100644 --- a/src/Api/Startup.cs +++ b/src/Api/Startup.cs @@ -104,8 +104,8 @@ namespace Bit.Api identityServerBuilder.AddTemporarySigningCredential(); } - services.AddSingleton(); - services.AddSingleton(); + services.AddScoped(); + services.AddScoped(); services.AddSingleton(); // Identity @@ -257,12 +257,7 @@ namespace Bit.Api NameClaimType = ClaimTypes.Email, // Version "2" until we retire the old jwt scheme and replace it with this one. AuthenticationScheme = "Bearer2", - TokenRetriever = TokenRetrieval.FromAuthorizationHeaderOrQueryString("Bearer2", "access_token2"), - JwtBearerEvents = new JwtBearerEvents - { - OnTokenValidated = JwtBearerEventImplementations.ValidatedTokenAsync, - OnAuthenticationFailed = JwtBearerEventImplementations.AuthenticationFailedAsync - } + TokenRetriever = TokenRetrieval.FromAuthorizationHeaderOrQueryString("Bearer2", "access_token2") }); // Add Jwt authentication to the request pipeline.