Аутентификация JWT .NET Core 2.2 не обновляет HttpContext - PullRequest
1 голос
/ 21 марта 2019

Я искал несколько похожих вопросов, но никто не помог мне.У меня следующая ситуация:

Базовая аутентификация JWT в .NET Core 2.2, Startup.cs имеет следующие настройки:

Startup.cs

            public void ConfigureServices(IServiceCollection services)
            {
                ...

                var signingConfigurations = new SigningConfigurations();
                services.AddSingleton(signingConfigurations);
                var tokenConfigurations = new TokenConfigurations();
                new ConfigureFromConfigurationOptions<TokenConfigurations>(
                    Configuration.GetSection("TokenConfigurations"))
                        .Configure(tokenConfigurations);
                services.AddSingleton(tokenConfigurations);

                services.AddAuthentication(authOptions =>
                {
                    authOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    authOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                }).AddJwtBearer(bearerOptions =>
                {
                    var paramsValidation = bearerOptions.TokenValidationParameters;
                    paramsValidation.IssuerSigningKey = signingConfigurations.Key;
                    paramsValidation.ValidAudience = tokenConfigurations.Audience;
                    paramsValidation.ValidIssuer = tokenConfigurations.Issuer;

                    // Validates a received token signature
                    paramsValidation.ValidateIssuerSigningKey = true;

                    // Verifies if a received token is still valid
                    paramsValidation.ValidateLifetime = true;

                    // Tolerance time for token expiration (used if there are timezone differences)
                    paramsValidation.ClockSkew = TimeSpan.Zero;
                });

                // Activates token usage on this project
                services.AddAuthorization(auth =>
                {
                    auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
                        .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
                        .RequireAuthenticatedUser().Build());
                });

Затем для создания токена:

LoginController.cs

        if (validCredentials)
        {
            ClaimsIdentity declarations = new ClaimsIdentity(
                new GenericIdentity(userInDB.UserName, "Login"),
                new[] {
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString("N")),
                    new Claim(JwtRegisteredClaimNames.UniqueName, userInDB.UserName),
                    new Claim("userid", userInDB.Id, ClaimValueTypes.String),
                    new Claim("username", userInDB.UserName, ClaimValueTypes.String),
                }
            );

            DateTime creationDate = DateTime.Now;
            DateTime expirationDate = creationDate +
                TimeSpan.FromSeconds(tokenConfigurations.Seconds);

            var handler = new JwtSecurityTokenHandler();
            var securityToken = handler.CreateToken(new SecurityTokenDescriptor
            {
                Issuer = tokenConfigurations.Issuer,
                Audience = tokenConfigurations.Audience,
                SigningCredentials = signingConfigurations.SigningCredentials,
                Subject = declarations,
                NotBefore = creationDate,
                Expires = expirationDate
            });
            var token = handler.WriteToken(securityToken);

            return new
            {
                authenticated = true,
                created = creationDate.ToString("yyyy-MM-dd HH:mm:ss"),
                expiration = expirationDate.ToString("yyyy-MM-dd HH:mm:ss"),
                accessToken = token,
                message = "OK"
            };
        }

Все, что я до сих пор делал, основано на этом пошаговом руководстве.

Пока все хорошо.Если я добавлю [Authorize("Bearer")] на контроллере, к нему можно будет получить доступ, только если у меня есть носитель в заголовке запроса.

Но так как я реализовывал структуру UserSession, для перехвата любого запроса, пройдите черезHttpContext и заполнить объект UserSession, он просто не работает.Ответственный метод таков:

ApplicationBuilderExtensions.cs

        public static IApplicationBuilder UseSessionConfiguration(
            this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<SessionConfigurationMiddleware>();
        }

        public class SessionConfigurationMiddleware
        {
            private readonly RequestDelegate _next;

            public SessionConfigurationMiddleware(RequestDelegate next)
            {
                _next = next;
            }

            public async Task InvokeAsync(HttpContext context, IUserSession sessao)
            {
                if (context.User.Identities.Any(id => id.IsAuthenticated))
                {
                    sessao.UserId = context.User.Claims.FirstOrDefault(x => x.Type == "userid").Value;
                    sessao.Roles = context.User.Claims.Where(x => x.Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/role").Select(x => x.Value).ToList();
                    sessao.UserName = context.User.Claims.FirstOrDefault(x => x.Type == "username").Value;
                }

                // Call the next delegate/middleware in the pipeline
                await _next.Invoke(context);
            }
        }

Но, когда я отлаживаю эту часть кода (который правильно вызывается после любого запроса)свойство IsAuthenticated в HttpContext всегда ложно, на самом деле в context.User все равно нулю или пусто, и я понятия не имею, почему.

Я неправильно настраиваю jwt?
промежуточное программное обеспечение неверно?
Правильно ли я заполняю заявки на jwt?
Почему [Authorize("Bearer")] работает правильно, если HttpContext заполнен неправильно?
Мы одни во вселенной?

Заранее спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...