Пользовательская аутентификация ASP Web API. Всегда получаю 401 несанкционированный ответ - PullRequest
2 голосов
/ 01 июля 2019

Я пытаюсь реализовать процесс аутентификации / авторизации, который при входе пользователя генерирует JWT и помещает его в файл cookie (при реализации я в основном использовал эту статью - думал, что это для .NET Core, а я использую .NET4.6: https://stormpath.com/blog/token-authentication-asp-net-core).Пока что этот процесс работает нормально, но когда я пытаюсь сделать запрос к защищенной конечной точке (украшенной атрибутом [Authorize]) с JWT в файле cookie, я всегда получаю 401 несанкционированный ответ.Несмотря на то, что JWT швы для проверки, и AuthenticationTicket возвращается из метода Unprotect класса CustomJwtDataFormat.

Как рекомендуется в ответе на этот вопрос Почему мой ClaimsIdentity IsAuthenticated всегда ложный (для веб-сайтовapi Authorize filter)? Я добавил параметр AuthenticationType при создании ClaimsIdentity.Но все тот же ответ 401.

Вот мой метод ConfigureAuth:

public void ConfigureAuth(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                Provider = new CookieAuthenticationProvider(),

                CookieName = "access_token",
                AuthenticationMode = 
                Microsoft.Owin.Security.AuthenticationMode.Active,
                AuthenticationType = AuthenticationTypes.Password,
                TicketDataFormat = new CustomJwtDataFormat(
                SecurityAlgorithms.HmacSha256,
                SettingsConfig.TokenValidationParameters)
            });
         }

Метод Unprotect класса CustomJwtDataFormat:

        public AuthenticationTicket Unprotect(string protectedText)
        {
            var handler = new JwtSecurityTokenHandler();
            ClaimsPrincipal principal = null;
            SecurityToken validToken = null;

            try
            {
                principal = handler.ValidateToken(protectedText, this.validationParameters, out validToken);

                var validJwt = validToken as JwtSecurityToken;

                if (validJwt == null)
                {
                    throw new ArgumentException("Invalid JWT");
                }

                if (!validJwt.Header.Alg.Equals(algorithm, StringComparison.Ordinal))
                {
                    throw new ArgumentException($"Algorithm must be '{algorithm}'");
                }

            }
            catch (SecurityTokenValidationException e)
            {
                var ex = e;
                return null;
            }
            catch (ArgumentException e)
            {
                var ex = e;
                return null;
            }
            var identity = new ClaimsIdentity(principal.Identities.FirstOrDefault().Claims, AuthenticationTypes.Password);

            // Validation passed. Return a valid AuthenticationTicket:
            var authTicket = new AuthenticationTicket(identity, new AuthenticationProperties());

            return authTicket;

My TokenValidationParameters:

 public static TokenValidationParameters TokenValidationParameters = new TokenValidationParameters
        {
            // The signing key must match!
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = signingKey,

            // Validate the JWT Issuer (iss) claim
            ValidateIssuer = true,
            ValidIssuer = "ExampleIssuer",

            // Validate the JWT Audience (aud) claim
            ValidateAudience = true, 
            ValidAudience = "ExampleAudience",

            // Validate the token expiry
            ValidateLifetime = true,

            ClockSkew = TimeSpan.FromMinutes(5)
        };

Метод GenerateToken:

        public static string GenerateToken(MetadataForToken tokenContentAndMetadata)
        {
            var symmetricKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(tokenContentAndMetadata.SecretKey));


            var tokenHandler = new JwtSecurityTokenHandler();
            var now = DateTime.UtcNow;

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(tokenContentAndMetadata.Claims),
                Expires = now.AddMinutes(Convert.ToInt32(tokenContentAndMetadata.ExpireMinutes)),
                SigningCredentials = new SigningCredentials(symmetricKey, tokenContentAndMetadata.SecurityAlgorithm),
                Issuer = "ExampleIssuer",
                Audience = "ExampleAudience"
            };
            var sToken = tokenHandler.CreateToken(tokenDescriptor);
            var token = tokenHandler.WriteToken(sToken);

            return token;
        }

Что я делаю не так?

...