2015-01-04 13 views
0

를 조회하기 위해 로그인 이메일 주소를 제공 위의 작품과 아니 확실히 생산에 사용되지 않지만 사실 반환 나는 사용자 이름과 주장을 포함 토큰을 얻을 것이다.인증합니다 내 API에 토큰에 서명 엔드 포인트를 제공하기 위해 Thinktecture AuthenticationConfiguration를 사용하고 사용자 ID를

내 시나리오에서 변경할 수없는 사용자 ID (정수)가 있으며이를 내 주장에 포함하고자합니다. 따라서 사용자는 기본 인증으로 헤더의 서비스 엔드 포인트에 전자 메일 주소를 전달한 다음 유효한 경우 ID로 요청을 처리합니다 (클레임과 같은 전자 메일 주소는 제외).

public class CredentialsService 
{ 
    public bool Validate(string emailAddress, string password) 
    { 
     // map from the provided name, to the user id 
     var details = MySqlDb.ReadBy(emailAddress); 

     var id = details.Id; // this is the actual identity of the user 
     var email = details.EmailAddress; 
     var hash = details.Hash; 

     return PasswordHash.ValidatePassword(password,hash);   
    } 
} 

emailAddress를 userId로 변환하기 위해 SQL Server 데이터베이스에 대한 두 번째 조회가 필요하다는 점에 감사드립니다. CredentialsService가 호출되기 전에이 쿼리를 파이프 라인 플로우에 삽입 할 수있는 방법이 있습니까?

아니면 잘못된 방법으로 가고, 사용자 이름을 그대로 사용하여 로그인 한 다음 사용자 이름을 기반으로 클레임 변환을 사용하여 정수 ID를 풍부하게 만드십시오. 그런 다음 사용자 이름을 변경하면 어떻게됩니까? ?

public class BasicAuthSecurityTokenHandlerWithClaimsOutput : BasicAuthenticationSecurityTokenHandler 
{  
    public BasicAuthSecurityTokenHandlerWithClaimsOutput(ValidateUserNameCredentialDelegate validateUserNameCredential, GetClaimsForAuthenticatedUser getClaimsForAuthenticatedUser) 
     : base() 
    { 
     if (validateUserNameCredential == null) 
     { 
      throw new ArgumentNullException("ValidateUserNameCredential"); 
     } 

     if (getClaimsForAuthenticatedUser== null) 
     { 
      throw new ArgumentNullException("GetClaimsForAuthenticatedUser"); 
     } 

     base.ValidateUserNameCredential = validateUserNameCredential; 
     _getClaimsForAuthenticatedUser = getClaimsForAuthenticatedUser; 
    } 

    public delegate Claim[] GetClaimsForAuthenticatedUser(string username); 
    private readonly GetClaimsForAuthenticatedUser _getClaimsForAuthenticatedUser; 

    public override ReadOnlyCollection<ClaimsIdentity> ValidateToken(SecurityToken token) 
    { 
     if (token == null) 
     { 
      throw new ArgumentNullException("token"); 
     } 

     if (base.Configuration == null) 
     { 
      throw new InvalidOperationException("No Configuration set"); 
     } 

     UserNameSecurityToken unToken = token as UserNameSecurityToken; 
     if (unToken == null) 
     { 
      throw new ArgumentException("SecurityToken is not a UserNameSecurityToken"); 
     } 

     if (!ValidateUserNameCredentialCore(unToken.UserName, unToken.Password)) 
     { 
      throw new SecurityTokenValidationException(unToken.UserName); 
     } 

     var claims = new List<Claim> 
     { 
      new Claim(ClaimTypes.Name, unToken.UserName), 
      new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.Password), 
      AuthenticationInstantClaim.Now 
     }; 

     var lookedUpClaims = _getClaimsForAuthenticatedUser(unToken.UserName); 

     claims.AddRange(lookedUpClaims); 

     if (RetainPassword) 
     { 
      claims.Add(new Claim("password", unToken.Password)); 
     } 

     var identity = new ClaimsIdentity(claims, "Basic"); 

     if (Configuration.SaveBootstrapContext) 
     { 
      if (this.RetainPassword) 
      { 
       identity.BootstrapContext = new BootstrapContext(unToken, this); 
      } 
      else 
      { 
       var bootstrapToken = new UserNameSecurityToken(unToken.UserName, null); 
       identity.BootstrapContext = new BootstrapContext(bootstrapToken, this); 
      } 
     } 

     return new List<ClaimsIdentity> {identity}.AsReadOnly(); 
    } 
} 

:

답변

0

좋아, 내가 서명 []를 준비 청구를 돌려 두 번째 대리자를 가지고 파생 클래스를 제공하는 멋진 thinktecture 소스의 모양과 최우선 BasicAuthenticationSecurityTokenHandler을 취함으로써이 문제를 해결하기 위해 관리 그때 쉽게 묶을 수 있도록 두 번째 도우미 메서드를 추가 :이 다른 사람을 도움이

public static class BasicAuthHandlerExtensionWithClaimsOutput 
{ 
    public static void AddBasicAuthenticationWithClaimsOutput(
     this AuthenticationConfiguration configuration, 
     BasicAuthenticationSecurityTokenHandler.ValidateUserNameCredentialDelegate validationDelegate, 
     BasicAuthSecurityTokenHandlerWithClaimsOutput.GetClaimsForAuthenticatedUser getClaimsForAuthenticatedUserDelegate, 
     string realm = "localhost", bool retainPassword = false) 
    { 
     var handler = new BasicAuthSecurityTokenHandlerWithClaimsOutput(validationDelegate, getClaimsForAuthenticatedUserDelegate); 
     handler.RetainPassword = retainPassword; 

     configuration.AddMapping(new AuthenticationOptionMapping 
     { 
      TokenHandler = new SecurityTokenHandlerCollection { handler }, 
      Options = AuthenticationOptions.ForAuthorizationHeader(scheme: "Basic"), 
      Scheme = AuthenticationScheme.SchemeAndRealm("Basic", realm) 
     }); 
    } 
} 

희망, 난 끔찍한 짓을 한 경우 알려 주시기 바랍니다!