public override void OnException(ExceptionContext context)
        {
            LocalizationService localizationService = context.HttpContext.RequestServices.GetService <LocalizationService>();
            CultureInfo         culture             = context.HttpContext.GetRequestCulture();
            ApiError            apiError            = null;

            if (context.Exception is SecurityTokenExpiredException)
            {
                SecurityTokenExpiredException securityTokenExpiredException = context.Exception as SecurityTokenExpiredException;

                context.HttpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;

                apiError = new ApiError(localizationService.GetLocalizedStatusCode(ResponseCode.SecurityTokenExpired));
            }
            else if (context.Exception is SecurityTokenException)
            {
                apiError = new ApiError(localizationService.GetLocalizedStatusCode(ResponseCode.InvalidSecurityToken));

                context.HttpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
            }
            else if (context.Exception is UnauthorizedAccessException)
            {
                apiError = new ApiError(localizationService.GetLocalizedStatusCode(ResponseCode.UnauthorizedAccess));

                context.HttpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
            }
            else
            {
                string message = string.Empty;
                string stack   = null;
#if DEBUG
                message = context.Exception.GetBaseException().Message;
                stack   = context.Exception.StackTrace;
#endif

                apiError = new ApiError(message, stack);

                context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
            }

            context.Result = new JsonResult(apiError);

            base.OnException(context);
        }
示例#2
0
        public void ValidateToken_ThrowsSecurityTokenValidationException_WhenTokenExpired()
        {
            // Arrange
            TimeSpan lifetime          = new TimeSpan(0, 0, 1);
            DateTime tokenCreationDate = DateTime.UtcNow + new TimeSpan(-1, 0, 0);
            DateTime tokenExpiryDate   = tokenCreationDate + lifetime;

            SecurityTokenDescriptor tokenDescriptor = this.GetTestSecurityTokenDescriptor(tokenCreationDate, tokenExpiryDate);

            JwtSecurityTokenHandler securityTokenHandler = new JwtSecurityTokenHandler();
            JwtSecurityToken        token = securityTokenHandler.CreateToken(tokenDescriptor) as JwtSecurityToken;

            // Act
            System.Threading.Thread.Sleep(1000);
            SecurityTokenExpiredException ex = Assert.Throws <SecurityTokenExpiredException>(() =>
                                                                                             MobileAppTokenHandler.ValidateToken(token.RawData, TestSecretKey));

            // Assert
            Assert.Contains("IDX10223: Lifetime validation failed. The token is expired", ex.Message, StringComparison.Ordinal);
        }
示例#3
0
        /// <summary>
        ///     Predefined setup of the first-party authentication middleware
        /// </summary>
        /// <param name="services">The service collection the validator attaches to</param>
        public static void AddAuthentication(this IServiceCollection services)
        {
            var tokenService = services.BuildServiceProvider()
                               .GetRequiredService <ITokenService>();

            var authenticationScheme = JwtBearerDefaults.AuthenticationScheme;

            var authentication = services.AddAuthentication(options =>
            {
                options.DefaultChallengeScheme    = authenticationScheme;
                options.DefaultAuthenticateScheme = authenticationScheme;
            });

            authentication.AddJwtBearer(authenticationScheme, async options =>
            {
                options.SaveToken = true;
                options.Events    = new JwtBearerEvents
                {
                    OnChallenge = context =>
                    {
                        var message = context.AuthenticateFailure switch
                        {
                            SecurityTokenExpiredException ex => $"Provided JWT bearer has expired on '{ex.Expires}'.",
                            _ => "Missing, or invalid 'Authorization' header not following the JWT bearer scheme."
                        };
                        throw new StatusException(StatusCodes.Status401Unauthorized, message);
                    }
                };

                var validationParameters          = await tokenService.RetrieveTokenValidationParametersAsync();
                options.TokenValidationParameters = validationParameters;
            });

            // Generate a valid token in development mode
            Task.Run(async() => await tokenService
                     .GenerateDevelopmentTokenAsync().ConfigureAwait(false));
        }
示例#4
0
        private void ConfigureAuthentication(IServiceCollection services)
        {
            services.AddAuthentication(authOptions =>
            {
                authOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                authOptions.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(jwtOptions =>
            {
                jwtOptions.Authority = Configuration["Authentication:Authority"];
                jwtOptions.Audience  = Configuration["Authentication:Audience"];

                jwtOptions.SaveToken           = false;
                jwtOptions.IncludeErrorDetails = true;

                if (Environment.IsDevelopment())
                {
                    jwtOptions.RequireHttpsMetadata = false;
                }

                jwtOptions.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateAudience         = true,
                    ValidateIssuerSigningKey = true,
                    ValidateIssuer           = true,
                    ValidIssuer      = Configuration["Authentication:Authority"],
                    ValidateLifetime = true,
                };

                jwtOptions.Events = new JwtBearerEvents
                {
                    OnAuthenticationFailed = failedAuthContext =>
                    {
                        failedAuthContext.NoResult();
                        failedAuthContext.Response.StatusCode  = 500;
                        failedAuthContext.Response.ContentType = "text/plain";

                        var errorMessage = failedAuthContext.Exception switch
                        {
                            SecurityTokenExpiredException _ => "Expired token.",
                            SecurityTokenNotYetValidException _ => "Token not yet valid.",
                            SecurityTokenInvalidLifetimeException _ => "Invalid token lifetime.",
                            SecurityTokenNoExpirationException _ => "Missing token expiration.",
                            SecurityTokenSignatureKeyNotFoundException _ => "Invalid token. Key not found.",
                            _ => "An error occured processing your authentication."
                        };

                        return(failedAuthContext.Response.WriteAsync(errorMessage));
                    },

                    // OnMessageReceived = debugContext =>
                    // {
                    //     var response = debugContext.Response;
                    //     return Task.CompletedTask;
                    // }
                };
            });

            // services.AddAuthorization(policyOptions =>
            // {
            //     policyOptions.AddPolicy("Keycloak", new AuthorizationPolicyBuilder()
            //         .RequireAuthenticatedUser()
            //         .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
            //         .Build());
            // });
        }
        private static string CreateErrorDescription(Exception authFailure)
        {
            AggregateException      ex         = authFailure as AggregateException;
            IEnumerable <Exception> enumerable = (IEnumerable <Exception>)((ex == null) ? ((object)new Exception[1]
            {
                authFailure
            }) : ((object)ex.InnerExceptions));
            List <string> list = new List <string>();

            foreach (Exception item in enumerable)
            {
                SecurityTokenInvalidAudienceException ex2 = item as SecurityTokenInvalidAudienceException;
                if (ex2 == null)
                {
                    SecurityTokenInvalidIssuerException ex3 = item as SecurityTokenInvalidIssuerException;
                    if (ex3 == null)
                    {
                        if (!(item is SecurityTokenNoExpirationException))
                        {
                            SecurityTokenInvalidLifetimeException ex4 = item as SecurityTokenInvalidLifetimeException;
                            if (ex4 == null)
                            {
                                SecurityTokenNotYetValidException ex5 = item as SecurityTokenNotYetValidException;
                                if (ex5 == null)
                                {
                                    SecurityTokenExpiredException ex6 = item as SecurityTokenExpiredException;
                                    if (ex6 == null)
                                    {
                                        if (!(item is SecurityTokenSignatureKeyNotFoundException))
                                        {
                                            if (item is SecurityTokenInvalidSignatureException)
                                            {
                                                list.Add("The signature is invalid");
                                            }
                                        }
                                        else
                                        {
                                            list.Add("The signature key was not found");
                                        }
                                    }
                                    else
                                    {
                                        list.Add("The token expired at '" + ex6.Expires.ToString(CultureInfo.InvariantCulture) + "'");
                                    }
                                }
                                else
                                {
                                    list.Add("The token is not valid before '" + ex5.NotBefore.ToString(CultureInfo.InvariantCulture) + "'");
                                }
                            }
                            else
                            {
                                list.Add("The token lifetime is invalid; NotBefore: '" + (ex4.NotBefore?.ToString(CultureInfo.InvariantCulture) ?? "(null)") + "', Expires: '" + (ex4.Expires?.ToString(CultureInfo.InvariantCulture) ?? "(null)") + "'");
                            }
                        }
                        else
                        {
                            list.Add("The token has no expiration");
                        }
                    }
                    else
                    {
                        list.Add("The issuer '" + (ex3.InvalidIssuer ?? "(null)") + "' is invalid");
                    }
                }
                else
                {
                    list.Add("The audience '" + (ex2.InvalidAudience ?? "(null)") + "' is invalid");
                }
            }
            return(string.Join("; ", list));
        }
示例#6
0
        private void ConfigureAuthentication(IServiceCollection services)
        {
            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(bearerOptions =>
            {
                bearerOptions.Authority           = Configuration["Jwt:Authority"];
                bearerOptions.Audience            = Configuration["Jwt:Audience"];
                bearerOptions.SaveToken           = true;
                bearerOptions.IncludeErrorDetails = true;
                if (Environment.IsDevelopment())
                {
                    bearerOptions.RequireHttpsMetadata = false;
                }

                var listAudiences = new List <string>();
                listAudiences.Add(Configuration["Jwt:Audience"]);

                bearerOptions.TokenValidationParameters = new TokenValidationParameters
                {
                    SaveSigninToken          = true,
                    ValidateIssuerSigningKey = true,
                    ValidateIssuer           = true,
                    ValidIssuer      = Configuration["Jwt:Authority"],
                    ValidateAudience = true,
                    ValidAudiences   = listAudiences,
                    ValidateLifetime = true
                };

                bearerOptions.Events = new JwtBearerEvents
                {
                    OnAuthenticationFailed = context =>
                    {
                        context.NoResult();
                        context.Response.StatusCode  = 401;
                        context.Response.ContentType = "text/plain";

                        var errorMessage = context.Exception switch
                        {
                            SecurityTokenExpiredException _ => "Expired token.",
                            SecurityTokenNotYetValidException _ => "Token not yet valid.",
                            SecurityTokenInvalidLifetimeException _ => "Invalid token lifetime.",
                            SecurityTokenNoExpirationException _ => "Missing token expiration.",
                            SecurityTokenSignatureKeyNotFoundException _ => "Invalid token. Key not found.",
                            _ => "An error occured processing your authentication."
                        };

                        if (Environment.IsDevelopment())
                        {
                            errorMessage += " - " + context.Exception.ToString();
                        }

                        return(context.Response.WriteAsync(errorMessage));
                    },

                    OnTokenValidated = context =>
                    {
                        var resourceAccess = JObject.Parse(context.Principal.FindFirstValue("resource_access"));
                        var clientRoles    = resourceAccess[Configuration["Jwt:Audience"]]["roles"];
                        var claimsIdentity = context.Principal.Identity as ClaimsIdentity;
                        if (claimsIdentity != null)
                        {
                            foreach (var clientRole in clientRoles)
                            {
                                claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, clientRole.ToString()));
                            }
                        }
                        return(Task.CompletedTask);
                    }
                };
            });
        }