예제 #1
0
        private void ConfigureAuthentication(IServiceCollection services)
        {
            var authSettings = Configuration.GetSection("AuthenticationSettings").Get <AuthenticationSettings>();

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                // Set token validation options. These will be used when validating all tokens.
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ClockSkew = TimeSpan.Zero,
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey         = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(authSettings.APISecrect)),
                    RequireSignedTokens      = true,
                    ValidateIssuer           = true,
                    ValidateAudience         = true,
                    RequireExpirationTime    = true,
                    ValidateLifetime         = true,
                    ValidAudience            = authSettings.TokenAudience,
                    ValidIssuers             = new string[] { authSettings.TokenIssuer }
                };

                options.Events = new JwtBearerEvents
                {
                    // Add custom responses when token validation fails.
                    OnChallenge = context =>
                    {
                        // Skip the default logic.
                        context.HandleResponse();
                        context.Response.StatusCode  = 401;
                        context.Response.ContentType = "application/json";

                        string errorMessage = string.IsNullOrWhiteSpace(context.ErrorDescription) ? context.Error : $"{context.Error}. {context.ErrorDescription}.";

                        var problem = new ProblemDetailsWithErrors(errorMessage ?? "Invalid token", 401, context.Request);

                        var settings = new JsonSerializerSettings
                        {
                            ContractResolver = new CamelCasePropertyNamesContractResolver()
                        };

                        return(context.Response.WriteAsync(JsonConvert.SerializeObject(problem, settings)));
                    },
                    OnAuthenticationFailed = context =>
                    {
                        if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                        {
                            context.Response.Headers.Add("X-Token-Expired", "true");
                        }

                        return(Task.CompletedTask);
                    }
                };
            });
        }
예제 #2
0
        public async Task InvokeAsync(HttpContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var error = context.Features.Get <IExceptionHandlerFeature>();

            if (error != null)
            {
                var sourceName      = GetSourceName();
                var thrownException = error.Error;
                var correlationId   = context.Request.Headers.GetOrGenerateCorrelationId();
                var statusCode      = StatusCodes.Status500InternalServerError;

                switch (thrownException)
                {
                case TimeoutRejectedException:
                case TimeoutException:
                    statusCode = StatusCodes.Status504GatewayTimeout;
                    break;

                default:
                    break;
                }

                context.Response.ContentType = "application/json";
                context.Response.StatusCode  = statusCode;

                var problemDetails = new ProblemDetailsWithErrors(thrownException, context.Response.StatusCode, context.Request);

                if (statusCode >= StatusCodes.Status500InternalServerError)
                {
                    this.logger.LogError(sourceName, correlationId, thrownException.Message);
                }
                else
                {
                    this.logger.LogWarning(sourceName, correlationId, thrownException.Message);
                }

                var jsonSettings = new JsonSerializerSettings
                {
                    ContractResolver = new DefaultContractResolver
                    {
                        NamingStrategy = new CamelCaseNamingStrategy()
                    }
                };

                await context.Response.WriteAsync(JsonConvert.SerializeObject(problemDetails, jsonSettings));
            }
        }
예제 #3
0
        public async Task InvokeAsync(HttpContext context)
        {
            logger.LogDebug(next.Method.Name);

            var error = context.Features.Get <IExceptionHandlerFeature>();

            if (error != null)
            {
                Exception thrownException = error.Error;

                context.Response.ContentType = "application/json";
                context.Response.StatusCode  = (int)HttpStatusCode.InternalServerError;

                var problemDetails = new ProblemDetailsWithErrors(thrownException, context.Response.StatusCode, context.Request);

                var jsonOptions = new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                };

                await context.Response.WriteAsync(JsonSerializer.Serialize(problemDetails, jsonOptions));
            }
        }
예제 #4
0
        public static IServiceCollection AddAuthenticationServices(this IServiceCollection services, IConfiguration config)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            services.Configure <AuthenticationSettings>(config.GetSection(ConfigurationKeys.Authentication));

            var authSettings = config.GetSection(ConfigurationKeys.Authentication).Get <AuthenticationSettings>();

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                // Set token validation options. These will be used when validating all tokens.
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ClockSkew = TimeSpan.Zero,
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey         = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(authSettings.APISecrect)),
                    RequireSignedTokens      = true,
                    ValidateIssuer           = true,
                    ValidateAudience         = true,
                    RequireExpirationTime    = true,
                    ValidateLifetime         = true,
                    ValidAudience            = authSettings.TokenAudience,
                    ValidIssuers             = new string[] { authSettings.TokenIssuer }
                };

                options.Events = new JwtBearerEvents
                {
                    OnChallenge = context =>
                    {
                        context.HandleResponse();
                        context.Response.StatusCode  = StatusCodes.Status401Unauthorized;
                        context.Response.ContentType = "application/json";

                        var errorMessage = string.IsNullOrWhiteSpace(context.ErrorDescription) ? context.Error : $"{context.Error}. {context.ErrorDescription}.";

                        var problem = new ProblemDetailsWithErrors(errorMessage ?? "Invalid token", StatusCodes.Status401Unauthorized, context.Request);

                        var settings = new JsonSerializerSettings
                        {
                            ContractResolver = new CamelCasePropertyNamesContractResolver()
                        };

                        return(context.Response.WriteAsync(JsonConvert.SerializeObject(problem, settings)));
                    },
                    OnForbidden = context =>
                    {
                        context.Response.StatusCode  = StatusCodes.Status403Forbidden;
                        context.Response.ContentType = "application/json";

                        var problem = new ProblemDetailsWithErrors("Forbidden", StatusCodes.Status403Forbidden, context.Request);

                        var settings = new JsonSerializerSettings
                        {
                            ContractResolver = new CamelCasePropertyNamesContractResolver()
                        };

                        return(context.Response.WriteAsync(JsonConvert.SerializeObject(problem, settings)));
                    },
                    OnAuthenticationFailed = context =>
                    {
                        if (context.Exception is SecurityTokenExpiredException)
                        {
                            context.Response.Headers.Add(AppHeaderNames.TokenExpired, "true");
                        }

                        return(Task.CompletedTask);
                    }
                };
            });

            services.AddAuthorization(options =>
            {
                options.AddPolicy(AuthorizationPolicyName.RequireAdminRole, policy => policy.RequireRole(UserRoleName.Admin));
                options.AddPolicy(AuthorizationPolicyName.RequireUserRole, policy => policy.RequireRole(UserRoleName.User));
            });

            return(services);
        }