ASP.NET 4.5 Web API 2.0, обработчик сообщений JWT возвращает статус от 0 до угловых 7 перехватчиков HTTP - PullRequest
0 голосов
/ 21 мая 2019

Заранее спасибо.На самом деле, я хочу реализовать токен обновления JWT в приложении Angular 7 с использованием HTTP Interceptor.Я реализовал JWT, используя HTTP-обработчик сообщений (DelegatingHandler).По неавторизованному запросу я получаю HttpErrorResponse Status = 0 вместо 401 для обновления токена.

Окно браузера: 2: 50191 / api / test / testget: 1 GET http://localhost:50191/api/test/testget 401 (неавторизовано): 4200 / # / login: 1 Доступ к XMLHttpRequest в «http://localhost:50191/api/test/testget' из источника» http://localhost:4200' заблокирован политикой CORS: нет «Access-Control-Allow-Origin»заголовок присутствует в запрошенном ресурсе.

.NET 4.5 Web API 2.0: добавлен CORS.

Угловой: Перехват перехватчика HTTP (req:HttpRequest, следующий: HttpHandler): наблюдаемый> {*

    return next.handle(this.attachTokenToRequest(req)).pipe(
        tap((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
                console.log("Success");
            }
        }), catchError((err): Observable<any> => {
            if (err instanceof HttpErrorResponse) {
                switch ((<HttpErrorResponse>err).status) {
                    case 401:
                        console.log("Token Expire,,, attempting 
refresh");
                        return this.handleHttpResponseError(req, next);
                    case 400:
                        return <any>this.authService.logout();
                }
            } else {
                return throwError(this.handleError);
            }
        })
    )
}

API:

WebApiConfig:

public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        var cors = new EnableCorsAttribute("*", "*", "*", "*");
        config.EnableCors(cors);
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.MessageHandlers.Add(new TokenValidationHandler());

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }

TokenValidationHandler:

protected override async Task<HttpResponseMessage> 
SendAsync(HttpRequestMessage request, CancellationToken 
cancellationToken)
    {
        HttpStatusCode statusCode;
        string token;
        //determine whether a jwt exists or not
        if (!TryRetrieveToken(request, out token))
        {
            statusCode = HttpStatusCode.Unauthorized;
            //allow requests with no token - whether a action method 
needs an authentication can be set with the claimsauthorization attribute
            var response = await base.SendAsync(request, 
cancellationToken);
            //response.Headers.Add("Access-Control-Allow-Origin", "*");
            return response;
        }

        try
        {
            const string sec = "5a65ed1";
            var now = DateTime.UtcNow;
            var securityKey = new 
SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));


            SecurityToken securityToken;
            JwtSecurityTokenHandler handler = new 
JwtSecurityTokenHandler();
            TokenValidationParameters validationParameters = new 
 TokenValidationParameters()
            {
                ValidAudience = "http://localhost:50191",
                ValidIssuer = "http://localhost:50191",
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                LifetimeValidator = this.LifetimeValidator,
                IssuerSigningKey = securityKey
            };
            //extract and assign the user of the jwt
            Thread.CurrentPrincipal = handler.ValidateToken(token, 
validationParameters, out securityToken);
            HttpContext.Current.User = handler.ValidateToken(token, 
 validationParameters, out securityToken);

            return await base.SendAsync(request, cancellationToken);
        }
        catch (SecurityTokenValidationException e)
        {
            statusCode = HttpStatusCode.Unauthorized;
        }
        catch (Exception)
        {
            statusCode = HttpStatusCode.InternalServerError;
        }
        return await Task<HttpResponseMessage>.Factory.StartNew(() => new 
  HttpResponseMessage(statusCode) { });
    }

Я ожидаю, что код состояния http 401 обновит токен jwt.

1 Ответ

0 голосов
/ 23 мая 2019

Вы можете использовать небольшие вспомогательные библиотеки для локальной проверки истечения срока действия токена, а затем для повторной аутентификации или получения токена обновления, если срок его действия истек. Это может быть немного более чистым решением.

Я успешно использовал JwtHelper из angular2-jwt в моей службе авторизации.

import { JwtHelper } from 'angular2-jwt';
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private jwtHelper: JwtHelper, private router: Router) {
  }
  canActivate() {
    var token = localStorage.getItem("jwt");

    if (token && !this.jwtHelper.isTokenExpired(token)){
      console.log(this.jwtHelper.decodeToken(token));
      return true;
    }
    this.router.navigate(["login"]);
    return false;
  }
}
...