2014-12-08 2 views
17

클레임 인증을 사용하여 ASP.NET WebApi 2를 사용하여 웹 API를 작성 중이며 사용자가 매우 많은 클레임을 가질 수 있습니다. 클레임 수가 많으면 무기명 토큰이 빠르게 커지므로 훨씬 짧은 무기 토큰을 반환하는 방법을 찾으려고합니다.대리 토큰을 제공하여 webapi에서 긴 무기명 토큰을 처리합니다.

는 지금까지 내가 OAuth를 옵션에 IAuthenticationTokenProvider에게 OAuthAuthorizationServerOptions.AccessTokenProvider 속성을 제공 할 수있는 것을 발견했다 :

OAuthOptions = new OAuthAuthorizationServerOptions 
{ 
    TokenEndpointPath = new PathString("/Token"), 
    Provider = new ApplicationOAuthProvider(PublicClientId), 
    AccessTokenExpireTimeSpan = TimeSpan.FromHours(12), 
    AccessTokenProvider = new GuidProvider() // <-- here 
}; 

그리고 이것은 나에게 AuthenticationTicket을 차단하고 간단한 무언가로 대체, 멀리 숨길 수있는 기회를 제공합니다 - 아래 예제에서 해시 된 guid. (참고 : 현재이 클래스는 단순히 내 세션과 ConcurrentDictionary<string,AuthenticationTicket>는 보유 - 실제 예제에서 나는 약간의 영구 저장소에서 세션을 저장하려는)

public class GuidProvider : IAuthenticationTokenProvider 
{ 
    private static ConcurrentDictionary<string, AuthenticationTicket> tokens 
     = new ConcurrentDictionary<string, AuthenticationTicket>(); 

    public void Create(AuthenticationTokenCreateContext context) 
    { 
     throw new NotImplementedException(); 
    } 

    public async System.Threading.Tasks.Task CreateAsync(AuthenticationTokenCreateContext context) 
    { 
     var guid = Guid.NewGuid().ToString(); 

     var ticket = Crypto.Hash(guid); 

     tokens.TryAdd(ticket, context.Ticket); 

     context.SetToken(ticket); 
    } 

    public void Receive(AuthenticationTokenReceiveContext context) 
    { 
     throw new NotImplementedException(); 
    } 

    public async System.Threading.Tasks.Task ReceiveAsync(AuthenticationTokenReceiveContext context) 
    { 
     AuthenticationTicket ticket; 

     if (tokens.TryGetValue(context.Token, out ticket)) 
     { 
      if (ticket.Properties.ExpiresUtc.Value < DateTime.UtcNow) 
      { 
       tokens.TryRemove(context.Token, out ticket); 
      } 
      context.SetTicket(ticket); 
     } 
    } 
} 

그래서 내 질문 :

  • 을 이것은 오랫동안 소유권 주장 생성 토큰 대신 대리 키를 제공하는 적절한 (안전한!) 방법입니까?
  • 아마도 webAPI/OAuth 스택에서이 작업을 수행해야하는 더 좋고/더 쉬운 곳이 있을까요? 새로 고침 토큰을 제외하고는 그들이 한 것으로 보인다 -

주목해야 할 또 다른 것은 내가 새로 고침 토큰을 지원하고자, 사실의 예는 위의 새로 고침 토큰 메커니즘 이런 종류의 사용 예에서 당겨졌다이다 -use, 따라서 ReceiveAsync 메서드는 대개 항상 ConcurrentDictionary에서 제공되는 새로 고침 토큰을 제거하므로 완전히 이해할 수없는 이유는 무엇입니까?

+0

클라이언트가이 권한을 다시 보내면이 접근 방법이 좋을 것입니다. 액세스 토큰을 처리 할 때 액세스 토큰을 처리하려면 액세스 토큰을 다시 가져 오십시오. 액세스 토큰을 처리하려면 OAuth2가 제트 될 것입니다. 올바른 선택이되지 않습니다. – Saravanan

+0

권한을 격리 할 수 ​​있기 때문에 클라이언트 응용 프로그램 및 대리 토큰에서 클레임을 유추 할 수 없습니다. – Saravanan

+0

@ jamiec JWT를 사용하여 저의 답이 클레임으로 가득 찬 액세스 토큰을 줄이는 데 도움이 되었습니까? –

답변

7

결국 데이터베이스 또는 Redis 서버에 인증 티켓을 저장하려고하기 때문에이 작업을 수행하지 않는 것이 좋습니다. 여기서 베어러 토큰을 포함하는 요청마다이 영구 저장소를 확인하려고합니다. Guid를 해결하고 티켓을 다시 만들어 주문하십시오.

OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() 
     { 
      //For Dev enviroment only (on production should be AllowInsecureHttp = false) 
      AllowInsecureHttp = true, 
      TokenEndpointPath = new PathString("/oauth2/token"), 
      AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30), 
      Provider = new CustomOAuthProvider(), 
      AccessTokenFormat = new CustomJwtFormat("http://jwtauthzsrv.azurewebsites.net") 
     }; 
:

난 당신이 아래의 코드로 OAuthAuthorizationServerOptions 재산 Provider에서 사용자 정의 액세스 토큰 형식 CustomOAuthProvider을 구현해야 할이 작업을 수행하기 위해, JSON 웹 토큰 JWT 대신 액세스 토큰 형식 베어러 기본으로 사용하는 것이 좋습니다

JWT 토큰에 더 많은 클레임을 추가해도 기본 액세스 토큰 형식의 경우와 같이 클레임이 크게 증가하지 않습니다.

두 개의 JWT가 서로 다른 클레임이 들어있는 샘플 아래에는 두 번째 JWT가 첫 번째 것보다 50 자만큼 큽니다.

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6InRhaXNlZXIiLCJzdWIiOiJ0YWlzZWVyIiwicm9sZSI6WyJNYW5hZ2VyIiwiU3VwZXJ2aXNvciJdLCJpc3MiOiJodHRwOi8vand0YXV0aHpzcnYuYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOiIwOTkxNTNjMjYyNTE0OWJjOGVjYjNlODVlMDNmMDAyMiIsImV4cCI6MTQxODY0NzMyNywibmJmIjoxNDE4NjQ1NTI3fQ.vH9XPtjtAv2-6SwlyX4fKNJfm5ZTVHd_9a3bRgkA_LI 

둘째 JWT (더 주장) : 나는 당신이 jwt.io 먼저 JWT를 사용하여 각각의 인코딩 된 내용을 확인하는 것이 좋습니다

JWT 형식은 OAuth를 발행하는 표준 방법이되고있다
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6InRhaXNlZXIiLCJzdWIiOiJ0YWlzZWVyIiwicm9sZSI6WyJNYW5hZ2VyIiwiU3VwZXJ2aXNvciIsIlN1cGVydmlzb3IxIiwiU3VwZXJ2aXNvcjIiLCJTdXBlcnZpc29yMyJdLCJpc3MiOiJodHRwOi8vand0YXV0aHpzcnYuYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOiIwOTkxNTNjMjYyNTE0OWJjOGVjYjNlODVlMDNmMDAyMiIsImV4cCI6MTQxODY0NzQ1NiwibmJmIjoxNDE4NjQ1NjU2fQ.TFEGDtz1RN8VmCQu7JH4Iug0B8UlWDLVrIlvc-7IK3E 

2.0 베어러 토큰뿐만 아니라 새로 고침 토큰 부여와 함께 작동합니다. 그러나 JWT는 서명 된 토큰에만 해당되며 기본 액세스 토큰 형식의 경우 암호화되지 않으므로 기밀 데이터를 저장하지 마십시오.

liveoft demo API 및 source code on GIthub과 함께 ASP.NET 웹 API에서 JWT 토큰을 사용하는 방법에 대해 bitoftech.net에 detailed blog post을 작성했습니다. 더 많은 도움이 필요하면 언제든지 알려주십시오.

행운을 빈다.

+0

JWT의 refresh_tokens 작업에 대해 언급했습니다. 당신은 정교 할 수 있습니까? 바로 지금, 나는 내 access_token으로서 JWT를 줄 구현을 가지고 있으며, 동일한 응답에서, 나의 refresh_token 인 훨씬 더 작은 토큰 (guid)을 포함한다. 그게 올바른 프로세스인가, 아니면 refresh_token이 더 긴 수명을 가진 JWT가되어야 하는가? –

+0

새로 고침 토큰은 데이터베이스에 저장된 보호 된 티켓의 식별자 일뿐입니다.이 식별자를 grant_type = refresh_token으로 나타내면 유효하며 (DB에서 삭제되지 않고 만료되지는 않음) 새 JWT 액세스 토큰을 받게됩니다. 명확한. –

+0

그건 의미가 있습니다. 감사. –

관련 문제