예제 #1
1
 public virtual Task <ClaimsPrincipal> GetClaimsPrincipalAsync(
     string token,
     TokenValidationParameters validationParameters
     )
 {
     return(Task.FromResult(
                securityTokenValidator.ValidateToken(
                    token,
                    validationParameters,
                    out var securityToken
                    )
                ));
 }
예제 #2
0
        public async Task <IActionResult> Callback(string returnUrl, string jwt)
        {
            var validationParameters = _tokenValidationParametersFactory.Create();

            try
            {
                var userPrincipal = _jwtTokenValidator.ValidateToken(jwt, validationParameters, out SecurityToken jwtToken);

                await _authenticationService.SignInAsync(HttpContext, AuthSchemes.CookieAuth, userPrincipal,
                                                         new AuthenticationProperties
                {
                    ExpiresUtc   = DateTime.UtcNow.AddMinutes(_authOptions.CookieAuthLifeTime),
                    IsPersistent = false,
                    AllowRefresh = false
                });
            }
            catch (Exception ex)
            {
                _logger.LogInformation($"Jwt token validation failed. Exception: {ex.ToString()}");
                return(Redirect($"/{_authOptions.AccessDeniedPath}"));
            }

            if (_authOptions.AddJwtCookie)
            {
                HttpContext.Response.Cookies.Append(JWTTokenKeys.Cookie, jwt);
            }

            if (_authOptions.AddJwtToSession)
            {
                HttpContext.Session.SetString(JWTTokenKeys.Session, jwt);
            }

            return(RedirectToLocal(returnUrl));
        }
예제 #3
0
        protected override async Task <IValueProvider> BuildAsync(SignalRConnectionInfoAttribute attrResolved,
                                                                  IReadOnlyDictionary <string, object> bindingData)
        {
            var azureSignalRClient = await Utils.GetAzureSignalRClientAsync(attrResolved.ConnectionStringSetting, attrResolved.HubName, _managerStore).ConfigureAwait(false);

            bindingData.TryGetValue(HttpRequestName, out var requestObj);
            var request     = requestObj as HttpRequest;
            var httpContext = request?.HttpContext;

            if (bindingData.ContainsKey(HttpRequestName) && _securityTokenValidator != null)
            {
                var tokenResult = _securityTokenValidator.ValidateToken(request);

                if (tokenResult.Status != SecurityTokenStatus.Valid)
                {
                    return(new SignalRConnectionInfoValueProvider(null, _userType, ""));
                }

                var signalRConnectionDetail = new SignalRConnectionDetail
                {
                    UserId = attrResolved.UserId,
                    Claims = azureSignalRClient.GetCustomClaims(attrResolved.IdToken, attrResolved.ClaimTypeList),
                };
                _signalRConnectionInfoConfigurer?.Configure(tokenResult, request, signalRConnectionDetail);
                var customizedInfo = await azureSignalRClient.GetClientConnectionInfoAsync(signalRConnectionDetail.UserId,
                                                                                           signalRConnectionDetail.Claims, httpContext).ConfigureAwait(false);

                return(new SignalRConnectionInfoValueProvider(customizedInfo, _userType, ""));
            }

            var info = await azureSignalRClient.GetClientConnectionInfoAsync(attrResolved.UserId, attrResolved.IdToken,
                                                                             attrResolved.ClaimTypeList, httpContext).ConfigureAwait(false);

            return(new SignalRConnectionInfoValueProvider(info, _userType, ""));
        }
        /// <summary>
        /// Checks that incoming requests have a valid access token, and sets the current user identity using that access token.
        /// </summary>
        /// <param name="request">the current <see cref="HttpRequestMessage"/>.</param>
        /// <param name="cancellationToken">a <see cref="CancellationToken"/> set by application.</param>
        /// <returns>A <see cref="HttpResponseMessage"/>.</returns>
        protected async override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            // check there is a jwt in the authorization header, return 'Unauthorized' error if the token is null.
            if (request.Headers.Authorization == null || request.Headers.Authorization.Parameter == null)
            {
                return(BuildResponseErrorMessage(HttpStatusCode.Unauthorized));
            }

            OpenIdConnectConfiguration config = null;

            try
            {
                config = await _configManager.GetConfigurationAsync(cancellationToken).ConfigureAwait(false);
            }
            catch (Exception)
            {
                return(new HttpResponseMessage(HttpStatusCode.InternalServerError));
            }

            TokenValidationParameters validationParameters = new TokenValidationParameters
            {
                // App Id URI and AppId of this service application are both valid audiences.
                ValidAudiences = new[] { _audience, _clientId },
                // Support Azure AD V1 and V2 endpoints.
                ValidIssuers      = new[] { config.Issuer, $"{config.Issuer}/v2.0" },
                IssuerSigningKeys = config.SigningKeys
            };

            try
            {
                // Validate token.
                var claimsPrincipal = _tokenValidator.ValidateToken(request.Headers.Authorization.Parameter, validationParameters, out SecurityToken _);

                // Set the ClaimsPrincipal on the current thread.
                Thread.CurrentPrincipal = claimsPrincipal;

                // Set the ClaimsPrincipal on HttpContext.Current if the app is running in web hosted environment.
                if (HttpContext.Current != null)
                {
                    HttpContext.Current.User = claimsPrincipal;
                }

                // If the token is scoped, verify that required permission is set in the scope claim.
                if (ClaimsPrincipal.Current.FindFirst(_scopeClaimType) != null && ClaimsPrincipal.Current.FindFirst(_scopeClaimType).Value != "user_impersonation")
                {
                    return(BuildResponseErrorMessage(HttpStatusCode.Forbidden));
                }

                return(await base.SendAsync(request, cancellationToken));
            }
            catch (SecurityTokenValidationException)
            {
                return(BuildResponseErrorMessage(HttpStatusCode.Unauthorized));
            }
            catch (Exception)
            {
                return(new HttpResponseMessage(HttpStatusCode.InternalServerError));
            }
        }
예제 #5
0
        public async Task <ClaimsPrincipal> ValidateTokenAsync(string token)
        {
            return(await _validationRequestPolicy
                   .ExecuteAsync(async() =>
            {
                var authConfig = await _configManager.GetConfigurationAsync(CancellationToken.None);
                var validationParams = BuildTokenValidationParameters(authConfig);

                return _tokenValidator.ValidateToken(token, validationParams, out var validatedToken);
            }));
        }
        public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters,
                                             out SecurityToken validatedToken)
        {
            var result = _underlyingValidator.ValidateToken(securityToken, validationParameters, out validatedToken);

            var claim = result.Claims.SingleOrDefault(x => x.Type == JwtRegisteredClaimNames.Typ && x.Value == TokenTypes.Access);

            if (claim == null)
            {
                throw new SecurityTokenException();
            }

            return(result);
        }
        public static ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, ISecurityTokenValidator tokenValidator, ExpectedException expectedException)
        {
            ClaimsPrincipal retVal = null;

            try
            {
                retVal = tokenValidator.ValidateToken(securityToken, validationParameters, out SecurityToken validatedToken);
                expectedException.ProcessNoException();
            }
            catch (Exception ex)
            {
                expectedException.ProcessException(ex);
            }

            return(retVal);
        }
        private ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, ISecurityTokenValidator tokenValidator, ExpectedException expectedException)
        {
            ClaimsPrincipal princiapl = null;

            try
            {
                SecurityToken validatedToken;
                princiapl = tokenValidator.ValidateToken(securityToken, validationParameters, out validatedToken);
                expectedException.ProcessNoException();
            }
            catch (Exception exception)
            {
                expectedException.ProcessException(exception);
            }

            return(princiapl);
        }
예제 #9
0
        public ClaimsPrincipal ValidateToken(string jwtToken)
        {
            IdentityModelEventSource.ShowPII = true;

            var validationParameters = new TokenValidationParameters
            {
                ValidateLifetime = true,
                ValidAudience    = tokensJWT.Issuer,
                ValidIssuer      = tokensJWT.Issuer,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokensJWT.Key))
            };

            return(securityTokenValidator.ValidateToken(
                       jwtToken,
                       validationParameters,
                       out SecurityToken validatedToken));
        }
        public ClaimsPrincipal ValidateToken(string token, TokenValidationParameters jwtConfig)
        {
            try
            {
                _logger.LogTrace("Validating token with config", new { jwtConfig });

                var claimsPrincipal = _jwtValidator.ValidateToken(token, jwtConfig, out _);

                _logger.LogTrace("Successfully validated token");

                return(claimsPrincipal);
            }
            catch (Exception ex)
            {
                throw new TokenValidationException(ex);
            }
        }
예제 #11
0
        public Maybe <IEnumerable <Claim> > Validate(string accessToken, TokenValidationParameters parameters)
        {
            try
            {
                var tokenWithoutBearer = accessToken.Replace(ConstantKey.BearerWithSpace, string.Empty);
                var claimsPrincipal    = _securityTokenValidator.ValidateToken(tokenWithoutBearer, parameters, out var securityToken);

                var jwtSecurityToken = securityToken as JwtSecurityToken;
                var result           = !jwtSecurityToken?.Header.Alg.Equals(HexadoTokenSpecific.GetAlgorithm, StringComparison.InvariantCultureIgnoreCase);

                return(result.HasValue
                    ? claimsPrincipal.Claims.ToMaybe()
                    : Maybe <IEnumerable <Claim> > .Nothing);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error occured during token validation!");
                return(Maybe <IEnumerable <Claim> > .Nothing);
            }
        }
예제 #12
0
        protected override Task <IValueProvider> BuildAsync(SignalRConnectionInfoAttribute attrResolved,
                                                            IReadOnlyDictionary <string, object> bindingData)
        {
            var azureSignalRClient = Utils.GetAzureSignalRClient(attrResolved.ConnectionStringSetting, attrResolved.HubName);

            if (!bindingData.ContainsKey(HttpRequestName) || securityTokenValidator == null)
            {
                var info = azureSignalRClient.GetClientConnectionInfo(attrResolved.UserId, attrResolved.IdToken,
                                                                      attrResolved.ClaimTypeList);
                return(Task.FromResult <IValueProvider>(new SignalRConnectionInfoValueProvider(info, userType, "")));
            }

            var request = bindingData[HttpRequestName] as HttpRequest;

            var tokenResult = securityTokenValidator.ValidateToken(request);

            if (tokenResult.Status != SecurityTokenStatus.Valid)
            {
                return(Task.FromResult <IValueProvider>(new SignalRConnectionInfoValueProvider(null, userType, "")));
            }

            if (signalRConnectionInfoConfigurer == null)
            {
                var info = azureSignalRClient.GetClientConnectionInfo(attrResolved.UserId, attrResolved.IdToken,
                                                                      attrResolved.ClaimTypeList);
                return(Task.FromResult <IValueProvider>(new SignalRConnectionInfoValueProvider(info, userType, "")));
            }

            var signalRConnectionDetail = new SignalRConnectionDetail
            {
                UserId = attrResolved.UserId,
                Claims = azureSignalRClient.GetCustomClaims(attrResolved.IdToken, attrResolved.ClaimTypeList),
            };

            signalRConnectionInfoConfigurer.Configure(tokenResult, request, signalRConnectionDetail);
            var customizedInfo = azureSignalRClient.GetClientConnectionInfo(signalRConnectionDetail.UserId,
                                                                            signalRConnectionDetail.Claims);

            return(Task.FromResult <IValueProvider>(new SignalRConnectionInfoValueProvider(customizedInfo, userType, "")));
        }
        public async Task <ClaimsPrincipal> ValidateTokenAsync(string token)
        {
            if (!securityTokenValidator.CanReadToken(token))
            {
                logger.LogError(AuthenticationResources.TokenInvalid);
                return(null);
            }

            if (ValidationParameters == null)
            {
                var openIdConnectConfiguration = await configurationManager.GetConfigurationAsync(CancellationToken.None);

                ValidationParameters = new TokenValidationParameters()
                {
                    IssuerSigningKeys        = openIdConnectConfiguration.SigningKeys,
                    RequireSignedTokens      = true,
                    ValidAudiences           = tokenValidatorConfiguration.ValidAudiences,
                    ValidateAudience         = true,
                    ValidIssuers             = tokenValidatorConfiguration.ValidIssuers,
                    ValidateIssuer           = true,
                    ValidateIssuerSigningKey = true,
                    ValidateLifetime         = true,
                };
            }

            ClaimsPrincipal claimsPrincipal = null;

            try
            {
                claimsPrincipal = securityTokenValidator.ValidateToken(token, ValidationParameters, out _);
            }
            catch (SecurityTokenException ex)
            {
                logger.LogError(ex.Message);
            }

            return(claimsPrincipal);
        }
예제 #14
0
        public static ClaimsPrincipal ValidateToken(this SecurityTokenHandlerCollection tokenHandlers, string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
        {
            if (tokenHandlers == null)
            {
                throw new ArgumentNullException("tokenHandlers");
            }

            if (securityToken == null)
            {
                throw new ArgumentNullException("securityToken");
            }

            if (validationParameters == null)
            {
                throw new ArgumentNullException("validationParameters");
            }

            bool iSecurityTokenValidatorFound = false;

            foreach (SecurityTokenHandler tokenHandler in tokenHandlers)
            {
                ISecurityTokenValidator securityTokenValidator = tokenHandler as ISecurityTokenValidator;
                if (securityTokenValidator != null && securityTokenValidator.CanReadToken(securityToken))
                {
                    iSecurityTokenValidatorFound = true;
                    return(securityTokenValidator.ValidateToken(securityToken, validationParameters, out validatedToken));
                }
            }

            if (iSecurityTokenValidatorFound)
            {
                throw new SecurityTokenValidationException(ErrorMessages.IDX10201);
            }
            else
            {
                throw new SecurityTokenValidationException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10201, securityToken));
            }
        }
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            //See https://gist.github.com/elanderson/c50b2107de8ee2ed856353dfed9168a2
            Stream tmpBody;
            string sBody;

            Context.Request.EnableRewind();
            tmpBody = Context.Request.Body;
            try
            {
                var buffer = new byte [Context.Request.ContentLength ?? 0];
                var read   = await Context.Request.Body.ReadAsync(buffer, 0, buffer.Length);

                sBody = Encoding.UTF8.GetString(buffer, 0, read);

                Context.Request.Body.Seek(0, SeekOrigin.Begin);
            }
            finally
            {
                Context.Request.Body = tmpBody;
            }

            var msg = JsonConvert.DeserializeObject <JWS.JwsMessage>(sBody);

            if (msg == null)
            {
                return(AuthenticateResult.NoResult());
            }

            var para = new TokenValidationParameters
            {
                ValidateTokenReplay   = true,
                RequireExpirationTime = false,
                ValidateAudience      = false,
                ValidateIssuer        = false,
                TokenReader           = (token, p) =>
                {
                    var t = JsonConvert.DeserializeObject <JwsMessage>(token);

                    return(t.ToJwtToken());
                }
                ,
                IssuerSigningKeyResolver = (token, jwtToken, kid, vp) =>
                {
                    //TODO: if Header.kid not null -> lookup serialized key in datastore;
                    //var jwk = JsonConvert.SerializeObject((jwtToken as JwtSecurityToken).Header ["jwk"]);
                    //return new SecurityKey [] { new JsonWebKey(jwk) };

                    return(new SecurityKey [] { msg.Header.Key });
                }
                ,
                TokenReplayValidator = (expirationTime, securityToken, validationParameters) =>
                {
                    var nonce = msg.DecodedProtected.Nonce;

                    //TODO: make check for nonce lifetime
                    var b = _nonceRegistry.VerifyNonceAsync(nonce).Result;
                    _nonceRegistry.SetNonceUsedAsync(nonce).Wait();

                    if (!b)
                    {
                        throw new Exceptions.BadReplayNonceException();
                    }

                    return(b);
                }
            };

            //var validator = Context.Features.Get<JWS.AcmeJwsSecurityTokenHandler>();

            var claimsPrincipal = _tokenValidator.ValidateToken(sBody, para, out var validatedToken);

            if ((validatedToken == null) || (claimsPrincipal == null))
            {
                return(AuthenticateResult.NoResult());
            }

            var ticket = new AuthenticationTicket(claimsPrincipal, AcmeJwsAuthenticationDefaults.AuthenticationScheme);


            return(AuthenticateResult.Success(ticket));
        }
        private ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, ISecurityTokenValidator tokenValidator, ExpectedException expectedException)
        {
            ClaimsPrincipal princiapl = null;
            try
            {
                SecurityToken validatedToken;
                princiapl = tokenValidator.ValidateToken(securityToken, validationParameters, out validatedToken);
                expectedException.ProcessNoException();
            }
            catch (Exception exception)
            {
                expectedException.ProcessException(exception);
            }

            return princiapl;
        }
예제 #17
0
        /// <summary>
        /// Checks that incoming requests have a valid access token, and sets the current user identity using that access token.
        /// </summary>
        /// <param name="request">the current <see cref="HttpRequestMessage"/>.</param>
        /// <param name="cancellationToken">a <see cref="CancellationToken"/> set by application.</param>
        /// <returns>A <see cref="HttpResponseMessage"/>.</returns>
        protected async override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            // Let Bot Message requests go through
            if (request.RequestUri.AbsolutePath.Contains("/api/messages"))
            {
                return(await base.SendAsync(request, cancellationToken));
            }

            // For debugging/development purposes, one can enable additional detail in exceptions by setting IdentityModelEventSource.ShowPII to true.
            Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;

            // check if there is a jwt in the authorization header, return 'Unauthorized' error if the token is null.
            if (request.Headers.Authorization == null || request.Headers.Authorization.Parameter == null)
            {
                return(BuildResponseErrorMessage(HttpStatusCode.Unauthorized));
            }

            // Pull OIDC discovery document from Azure AD. For example, the tenant-independent version of the document is located
            // at https://login.microsoftonline.com/common/.well-known/openid-configuration.
            OpenIdConnectConfiguration config = null;

            try
            {
                config = await _configManager.GetConfigurationAsync(cancellationToken).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
#if DEBUG
                return(BuildResponseErrorMessage(HttpStatusCode.InternalServerError, ex.Message));
#else
                return(new HttpResponseMessage(HttpStatusCode.InternalServerError));
#endif
            }

            // You can get a list of issuers for the various Azure AD deployments (global & sovereign) from the following endpoint
            //https://login.microsoftonline.com/common/discovery/instance?authorization_endpoint=https://login.microsoftonline.com/common/oauth2/v2.0/authorize&api-version=1.1;

            IList <string> validissuers = new List <string>()
            {
                $"https://login.microsoftonline.com/{_tenant}/",
                $"https://login.microsoftonline.com/{_tenant}/v2.0",
                $"https://login.windows.net/{_tenant}/",
                $"https://login.microsoft.com/{_tenant}/",
                $"https://sts.windows.net/{_tenant}/"
            };

            // Initialize the token validation parameters
            TokenValidationParameters validationParameters = new TokenValidationParameters
            {
                // App Id URI and AppId of this service application are both valid audiences.
                ValidAudiences = new[] { _audience, _clientId },

                // Support Azure AD V1 and V2 endpoints.
                ValidIssuers      = validissuers,
                IssuerSigningKeys = config.SigningKeys
            };

            try
            {
                // Validate token.
                SecurityToken securityToken;
                var           claimsPrincipal = _tokenValidator.ValidateToken(request.Headers.Authorization.Parameter, validationParameters, out securityToken);

#pragma warning disable 1998
                // This check is required to ensure that the Web API only accepts tokens from tenants where it has been consented to and provisioned.
//                if (!claimsPrincipal.Claims.Any(x => x.Type == ClaimConstants.ScopeClaimType)
//                   && !claimsPrincipal.Claims.Any(y => y.Type == ClaimConstants.RolesClaimType))
//                {
//#if DEBUG
//                    return BuildResponseErrorMessage(HttpStatusCode.Forbidden, "Neither 'scope' or 'roles' claim was found in the bearer token.");
//#else
//                    return BuildResponseErrorMessage(HttpStatusCode.Forbidden);
//#endif
//                }
#pragma warning restore 1998

                // Set the ClaimsPrincipal on the current thread.
                Thread.CurrentPrincipal = claimsPrincipal;

                // Set the ClaimsPrincipal on HttpContext.Current if the app is running in web hosted environment.
                if (HttpContext.Current != null)
                {
                    HttpContext.Current.User = claimsPrincipal;
                }

                // If the token is scoped, verify that required permission is set in the scope claim. This could be done later at the controller level as well
                //if (ClaimsPrincipal.Current.FindFirst(ClaimConstants.ScopeClaimType).Value != ClaimConstants.ScopeClaimValue)
                //    return BuildResponseErrorMessage(HttpStatusCode.Forbidden);

                return(await base.SendAsync(request, cancellationToken));
            }
            catch (SecurityTokenValidationException stex)
            {
#if DEBUG
                return(BuildResponseErrorMessage(HttpStatusCode.Unauthorized, stex.Message));
#else
                return(BuildResponseErrorMessage(HttpStatusCode.Unauthorized));
#endif
            }
            catch (Exception ex)
            {
#if DEBUG
                return(BuildResponseErrorMessage(HttpStatusCode.InternalServerError, ex.Message));
#else
                return(new HttpResponseMessage(HttpStatusCode.InternalServerError));
#endif
            }
        }
        public Task <IValueProvider> BindAsync(object value, ValueBindingContext context)
        {
            if (((BindingContext)value).BindingData[HttpRequestName] is not HttpRequest request)
            {
                throw new NotSupportedException($"Argument {nameof(HttpRequest)} is null. {nameof(SecurityTokenValidationAttribute)} must work with HttpTrigger.");
            }

            if (_securityTokenValidator == null)
            {
                return(Task.FromResult <IValueProvider>(new SecurityTokenValidationValueProvider(null, "")));
            }

            return(Task.FromResult <IValueProvider>(new SecurityTokenValidationValueProvider(_securityTokenValidator.ValidateToken(request), "")));
        }
예제 #19
0
        public async Task Invoke(HttpContext context,
                                 ISecurityTokenValidator tokenValidator,
                                 IOptions <DelegationOptions> options,
                                 ITokenValidationParametersFactory tokenValidationParametersFactory)
        {
            if (tokenValidator == null)
            {
                throw new ArgumentNullException(nameof(tokenValidator), $"{nameof(tokenValidator)} cannot be null.");
            }
            if (tokenValidationParametersFactory == null)
            {
                throw new ArgumentNullException(nameof(tokenValidationParametersFactory), $"{nameof(tokenValidationParametersFactory)} cannot be null.");
            }

            var validationParameters = tokenValidationParametersFactory.Create();

            // get DelegationUser added as scoped service
            var  delegationUser       = context.RequestServices.GetService(typeof(IDelegationUser)) as DelegationUser;
            bool delegationUserParsed = false;
            var  token = string.Empty;

            try
            {
                token = GetDelegationJwtToken(context, options.Value.DelegationHeader);

                if (!string.IsNullOrWhiteSpace(token))
                {
                    if (tokenValidator.CanReadToken(token))
                    {
                        ClaimsPrincipal principal      = null;
                        SecurityToken   validatedToken = null;

                        try
                        {
                            principal = tokenValidator.ValidateToken(token, validationParameters, out validatedToken);
                            _logger.LogInformation($"Jwt delegation token validation succeeded");
                        }
                        catch (Exception ex)
                        {
                            _logger.LogInformation($"Jwt delegation token validation failed. Exception: {ex.ToString()}");
                            throw;
                        }

                        ClaimsIdentity claimsIdentity = principal.Identities?.FirstOrDefault();

                        if (claimsIdentity != null && delegationUser.TrySetValues(claimsIdentity, token))
                        {
                            delegationUserParsed = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogInformation($"Processing delegation user failed. Exception: {ex.ToString()}");
                throw;
            }

            if (delegationUserParsed)
            {
                delegationUser.SetValid(true);
                _logger.LogInformation($"Request for delegated user: { delegationUser.Sub} ({delegationUser.GivenName} {delegationUser.SurName})");
            }
            else
            {
                delegationUser.SetValid(false);
                var info = $"No delegated user detected for request { (string.IsNullOrWhiteSpace(token) ? "(no delegation token found)" : $"(delegation token: {token})") }.";
                _logger.LogInformation(info);
            }

            await _next.Invoke(context);
        }
        public async Task <ClaimsPrincipal> GetClaimsPrincipalAsync(AzureAdTokenAttribute azureAdData)
        {
            if (!_httpContextAccessor.HttpContext.Request.Headers.TryGetValue(Authorization, out var headerData))
            {
                return(null);
            }

            var headerValue = headerData.FirstOrDefault();

            if (headerValue == null)
            {
                return(null);
            }

            if (!headerValue.Contains(Bearer, StringComparison.OrdinalIgnoreCase))
            {
                return(null);
            }

            var token = headerValue.Substring($"{Bearer} ".Length);

            if (string.IsNullOrEmpty(token))
            {
                return(null);
            }

            try
            {
                var openIdConfigurationManager = new ConfigurationManager <OpenIdConnectConfiguration>(azureAdData.AuthorizeUrl, new OpenIdConnectConfigurationRetriever());
                var openIdConnectConfigData    = await openIdConfigurationManager.GetConfigurationAsync();

                var validationParameters = new TokenValidationParameters
                {
                    ValidateAudience         = true,
                    ValidateIssuer           = true,
                    ValidateIssuerSigningKey = true,
                    ValidateLifetime         = true,
                    RequireSignedTokens      = true,
                    ClockSkew = TimeSpan.Zero,

                    ValidAudience = azureAdData.Audience,

                    IssuerSigningKeys = openIdConnectConfigData.SigningKeys,
                    ValidIssuer       = openIdConnectConfigData.Issuer
                };

                var principal = _securityTokenValidator.ValidateToken(token, validationParameters, out var securityToken);

                var requiredScopes = azureAdData.Scopes?.Replace(" ", string.Empty)?.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)?.ToList();
                var requiredRoles  = azureAdData.Roles?.Replace(" ", string.Empty)?.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)?.ToList();

                var isValid = IsValid(principal, requiredScopes, requiredRoles);

                return(isValid ? principal : null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error when validating the user token");
            }

            return(null);
        }
        public static ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, ISecurityTokenValidator tokenValidator, ExpectedException expectedException)
        {
            ClaimsPrincipal retVal = null;
            try
            {
                SecurityToken validatedToken;
                retVal = tokenValidator.ValidateToken(securityToken, validationParameters, out validatedToken);
                expectedException.ProcessNoException();
            }
            catch (Exception ex)
            {
                expectedException.ProcessException(ex);
            }

            return retVal;
        }