5

휴대 기기 및 웹 클라이언트에서 소비되는 ASP.NET 웹 API 프로젝트에서 인증/승인을 수행하기 위해 우수한 Thinktecture.IdentityModel 라이브러리를 사용하고 있습니다. 나는 기본 인증을 사용하여 모바일 클라이언트를 인증하여 웹 API에 액세스하고 Thinktecture.IdentityModel이 제공하는 내장 된 SessionToken 세대를 활용합니다. 그러나 나는 여기 ClaimsIdentity를 만료/갱신하는 방법 웹 API에 저장된 클레임 SessionToken

내가 지금까지 무엇을 가지고 ... (내 생각)을 SessionToken가 클라이언트에 제공으로 인코딩 한 후됩니다 ClaimsIdentity 주장 컬렉션에 추가 청구를 취소하는 방법에 관한 몇 가지 문제가 :

IdentityModel 샘플 프로젝트의 예에 따라

, 정말

SecurityConfig.ConfigureGlobal(GlobalConfiguration.Configuration); 
0123처럼 내 Global.asax에 클래스에서 호출 된 다음 클래스

public static class SecurityConfig 
{ 
    public static void ConfigureGlobal(HttpConfiguration globalConfig) 
    { 
     globalConfig.MessageHandlers.Add(new AuthenticationHandler(CreateConfiguration())); 
    } 

    public static AuthenticationConfiguration CreateConfiguration() 
    { 
     var authentication = new AuthenticationConfiguration() 
      { 
       ClaimsAuthenticationManager = new MyClaimsTransformer(), 
       RequireSsl = false, //TODO:TESTING only 
       EnableSessionToken = true, 
       SessionToken = new SessionTokenConfiguration() 
       { 
        EndpointAddress = "/Authenticate" 
       } 
      }; 
     authentication.AddBasicAuthentication(Membership.ValidateUser); 

     return authentication; 
    } 
} 

을 만들었습니다모바일 장치는 개인의 사용자 이름과 암호를 수집하고 인증 헤더를 올바르게 설정하고 필요한 웹 엔드 포인트에 자격 증명을 제공합니다.

서버에서 내 Membership.ValidatUser가 사용자 이름/암호로 호출되고 유효성을 검사하면 MyClaimsTransformer의 Authenticate 메서드가 호출됩니다.

public class ClaimsTransformer : ClaimsAuthenticationManager 
{ 
    public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal) 
    { 
    if (!incomingPrincipal.Identity.IsAuthenticated) 
    { 
     return base.Authenticate(resourceName, incomingPrincipal); 
    } 
    return incomingPrincipal; 
    } 
} 

모바일 클라이언트는 토큰을 수신하여 모든 후속 요청의 인증 헤더에서 전달할 수 있습니다.

모두 훌륭한 작품입니다.

이제 내가하고 싶은 것은 ClaimsTransformer에 다음 의사 코드와 같은 코드를 추가하는 것입니다.

var nameClaim = incomingPrincipal.Claims.First(c => c.Type == ClaimTypes.Name); 

//Using value in nameClaim lookup roles or permissions for this user. 
var someListofRoles = SomeMethodToGetRoles(nameClaim.Value); 

//Add user roles to the Claims collection of the ClaimsPrincipal. 
foreach(var role in someListOfRoles) 
{ 
    incomingPrincipal.Identities.First().AddClaim(new Claim("Role", role.Name)); 
} 

내 희망은 내가 데이터베이스에서 특정 사용자 역할 또는 권한의 목록을 요청뿐만 아니라 AuthorizeAttribute 사용자 정의에서 이러한 역할/권한을 확인하는 것이 편리해야하는 횟수를 제한했다 .

그러나이 기능을 추가하기 시작하면서 사용자가 로그인하여이 토큰을 받았을 시나리오를 생각하기 시작했지만 시스템의 다른 사용자가 수행 한 작업에 따라 역할이 변경되거나 취소됨. 초기 사용자는 여전히 만료 된 역할/권한 목록이있는이 토큰을 가지며 토큰이 만료 될 때까지 액세스 할 수 있습니다. 또는 새로운 액세스 권한이 주어졌지만 어떻게 든 로그 아웃 될 때까지 실제로 액세스를받지 못합니다.

이렇게 만든 SessionToken을 무효화하는 메커니즘이 있습니까? 또는 사용자 역할/권한에 변경 사항이 있음을 알 수있는 방법을 발견 한 경우 클레임을 수정하고 끊김없이 SessionToken을 재발급하려면 어떻게해야합니까?

또한 SessionToken을 완전히 취소하는 방법, 즉 사용자를 '로그 아웃'하려면 어떻게 작동합니까?

답변

4

세션 토큰 기능에는 해당 기능이 없습니다. 우리는 "모든 응용 프로그램 시작시 암호 입력"문제를 간단하게 해결하고 싶었습니다. 철회는 완벽한 데이터 스토리지 백엔드 없이는 달성하기 어렵습니다 (웹 팜에서 작동 할 것입니다.).

세션 토큰에 세션 시간 동안 변경 될 수있는 데이터를 저장하지 마십시오.

0

데이터베이스 변경 알림 디자인은 실제로 당신까지입니다. 내가 제안하는 것은 timestamp/rowversion을 사용하여 데이터 (사용자/역할)가 오래된 것인지 확인하는 것과 같습니다. 사용자 세션과 같은 서버에이 데이터 타임 스탬프/rowversion을 저장할 수 있으며 클라이언트 측에서 쿠키/헤더를 저장할 수 있습니다. 나는 이전의 접근법을 추천한다.

오래된 경우, 토큰과 관련된 최신 데이터 변경 내용을 반영하여 필요한 모든 정보를 다시 작성해야하는 CreateConfiguration() 메서드를 다시 실행할 수 있습니다.

+0

응답 해 주셔서 감사합니다. 특정 사용자에 대해 역할이나 권한이 업데이트/제거/추가 된 경우 데이터베이스 조회를 통해 확실히 감지 할 수 있습니다. 우리는 이미 이러한 개체의 타임 스탬프를 지정하고 있습니다. CreateConfiguration을 다시 실행하라는 제안이 올바르지 않은 것 같습니다. 내가 이해할 수 있듯이 이것은 한 번 '설정'과정으로 thinktecture 객체를 로컬 클레임 변압기와 멤버쉽 인증 방법에 연결합니다. 다시 실행하면 인증 된 모든 사용자 SessionToken이 무효화 될 가능성이 있습니다. – thornhill