2017-10-18 5 views
1

인증 중에 JWT 토큰의 유효성을 검사 한 후에 발생하는 OnTokenValidated 이벤트를 사용자 지정 메서드에서 처리하도록하려면 ASP.NET Core 2.0에서 DI를 제대로 사용하고 싶습니다. 아래의 솔루션은 을 제외하고는 처리기에서 컨트롤러의 다른 곳에 추가 된 캐시 된 항목을 확인하기 위해 MemoryCache을 치는 주입 서비스를 사용한다는 점에 유의하십시오 (추가 및 지속됨을 확인했습니다). 캐시는 항상 비어 있습니다. 내 사용자 지정 처리기 개체를 다른 컨테이너 (초기 BuildServiceProvider() 호출로 인해 생성되는 때문에?) MemoryCache (또는 비슷한) 별도의 인스턴스를 활용하기 때문에이 의심됩니다.OnTokenValidated with startup.cs에 할당 된 대리자가있는

그렇다면 제대로 입력하고 내 클래스 및 메서드를startup.cs에 추가하고 참조하는 방법이 명확하지 않아서 의도 한대로 작동합니다. 여기에 내가 가지고있는 것 :

public void ConfigureServices(IServiceCollection services) 
    { 
    services.AddMemoryCache(); 
    ... 
    services.AddScoped<IJwtTokenValidatedHandler, JwtTokenValidatedHandler>(); 
    // add other services 
    ... 
    var sp = services.BuildServiceProvider(); 
    services.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, bOptions => 
     { 
      // Configure JwtBearerOptions 
      bOptions.Events = new JwtBearerEvents 
      { 
       OnTokenValidated = sp.GetService<JwtTokenValidatedHandler>().JwtTokenValidated 
      }; 
     } 

내 사용자 지정 처리기 클래스는 아래와 같습니다. 사용자 정의 OnTokenValidated 방법은 간단한 로직을 포함하고 나는 익명 함수와 인라인 것입니다 주입 된 서비스를 필요로하지 않았다

public class JwtTokenValidatedHandler : IJwtTokenValidatedHandler 
{ 
    AppSessionService _session; 
    public JwtTokenValidatedHandler(AppSessionService session) 
    { 
     _session = session; 
    } 
    public async Task JwtTokenValidated(TokenValidatedContext context) 
    { 
     // Add the access_token as a claim, as we may actually need it 
     var accessToken = context.SecurityToken as JwtSecurityToken; 
     if (Guid.TryParse(accessToken.Id, out Guid sessionId)) 
     { 
      if (await _session.ValidateSessionAsync(sessionId)) 
      { 
       return; 
      } 
     } 
     throw new SecurityTokenValidationException("Session not valid for provided token."); 
    } 
} 

경우 : ValidateSessionAsync() 호출은 MemoryCache 개체에 액세스하고 캐시 엔트리가 존재 확인하기 위해 주입 된 AppSessionService를 사용 또는 startup.cs에서 개인적으로 선언하십시오. 가능한 경우이 방법을 수정하는 것이 좋지만 다른 것들은 열어 놓을 수 있습니다.

답변

1

대신 정적/싱글 이벤트를 사용하는 JwtBearerEvents를 서브 클래스와 JwtBearerOptions.EventsType 옵션을 사용하여 고려하십시오

public class CustomJwtBearerEvents : JwtBearerEvents 
{ 
    AppSessionService _session; 
    public CustomJwtBearerEvents(AppSessionService session) 
    { 
     _session = session; 
    } 

    public override async Task TokenValidated(TokenValidatedContext context) 
    { 
     // Add the access_token as a claim, as we may actually need it 
     var accessToken = context.SecurityToken as JwtSecurityToken; 
     if (Guid.TryParse(accessToken.Id, out Guid sessionId)) 
     { 
      if (await _session.ValidateSessionAsync(sessionId)) 
      { 
       return; 
      } 
     } 
     throw new SecurityTokenValidationException("Session not valid for provided token."); 
    } 
} 

public class Startup 
{ 
    public void ConfigureServices(IServiceCollection services) 
    { 
     services.AddScoped<CustomJwtBearerEvents>(); 

     services.AddAuthentication() 
      .AddJwtBearer(options => 
      { 
       options.EventsType = typeof(CustomJwtBearerEvents); 
      }); 
    } 
} 
+0

네를. 그 트릭을 했어! – coryseaman