52

웹 API 프로젝트에서 토큰을 확인하기 위해 일반 인증 프로세스를 무시하고 있습니다. 코드는이 같은 외모 : 나는 컨트롤러에 [Authorize] 속성을 적용 할 때 다음 나중에왜 ClaimsIdentity IsAuthenticated가 항상 false입니까 (웹 API 권한 필터의 경우)?

if (true) // validate the token or whatever here 
{ 
    var claims = new List<Claim>(); 
    claims.Add(new Claim(ClaimTypes.Name, "MyUser")); 
    claims.Add(new Claim(ClaimTypes.NameIdentifier, "MyUserID")); 
    claims.Add(new Claim(ClaimTypes.Role, "MyRole")); 

    var claimsIdentity = new ClaimsIdentity(claims); 

    var principal = new ClaimsPrincipal(new[] { claimsIdentity }); 
    Thread.CurrentPrincipal = principal; 
    HttpContext.Current.User = principal; 
} 

과, 그것을 승인 실패합니다.

디버그 코드는 동일한 동작을 확인 :

// ALWAYS FALSE! 
if (HttpContext.Current.User.Identity.IsAuthenticated) { 
    // do something 
} 

왜 내가 유효한 ClaimsIdentity 건설 및 스레드에 할당 한 경우에도 사용자가 인증되지 않은 생각합니까?

답변

109

.Net 4.5의 변경으로 인해 문제가 발생했습니다. this article으로 설명했듯이 간단하게 클레임 ID를 구성하면 더 이상 IsAuthenticated가 true를 반환하지 않습니다. 대신 생성자에 문자열을 전달해야합니다 (상관 없습니다).

그래서 위의 코드에서이 라인 :

// exact string doesn't matter 
var claimsIdentity = new ClaimsIdentity(claims, "CustomApiKeyAuth"); 

을 그리고 문제는 해결된다 :

var claimsIdentity = new ClaimsIdentity(claims); 

이된다. 업데이트 : 레오에서 다른 답변을 참조하십시오. 정확한 AuthenticationType 값은 인증 파이프 라인에있는 다른 항목에 따라 중요 할 수도 있고 아닐 수도 있습니다.

업데이트 2 : 의견에서 Robin van der Knaap이 제안한대로 System.Security.Claims.AuthenticationTypes 값 중 하나가 적합 할 수 있습니다.

var claimsIdentity = new ClaimsIdentity(claims, AuthenticationTypes.Password); 

// and elsewhere in your application... 
if (User.Identity.AuthenticationType == AuthenticationTypes.Password) { 
    // ... 
} 
+8

MSDN에 따르면 모든 문자열을 추가 할 수 있지만 일반적으로 AuthenticationTypes 클래스에 정의 된 값 중 하나 여야합니다. http://msdn.microsoft.com/en-us/library/system.security.claims.claimsidentity.authenticationtype(v=vs.110).aspx –

+1

예 : var claimsIdentity = new ClaimsIdentity (claims, AuthenticationTypes.Password); –

+2

문자열의 값이 User.Identity.AuthenticationType에 표시됩니다. –

10

제공된 대답은 그 안에 몇 가지 유효성이 있지만 완전히 정확하지는 않습니다. 어떤 문자열을 추가하는 것만으로도 마술처럼 작동 할 것이라고 추측 할 수는 없습니다. 주석 중 하나에 명시된 바와 같이,이 문자열은, 그러나 결과적으로, 예를 들어 .... OWIN 인증/권한 부여 미들웨어에 지정된 일치해야합니다 AuthenticationTypes 열거 한 ...

public void ConfigureOAuth(IAppBuilder app) 
     { 
      app.UseCors(CorsOptions.AllowAll); 

      OAuthAuthorizationServerOptions serverOptions = new OAuthAuthorizationServerOptions() 
      { 
       AllowInsecureHttp = true, 
       TokenEndpointPath = new Microsoft.Owin.PathString("/token"), 
       AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), 
       AuthenticationType = AuthenticationTypes.Password, 
       AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active, 
       Provider = new AppAuthServerProvider() 
      }; 


      app.UseOAuthAuthorizationServer(serverOptions); 
      app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions() 
       { 
        AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active, 
        AuthenticationType = AuthenticationTypes.Password 
       });    
     } 

일치해야합니다 위의 시나리오에서는별로 중요하지 않습니다. 당신이 주장은 같은 AuthenticationType 일치 하나에 연결됩니다 이상의 인증/권한 부여 레벨을 사용하는 경우 쿠키 인증을 사용할 때, ... 또 다른 예는 ... AuthenticationType이 이름을 설명

public void Configuration(IAppBuilder app) 
     { 
      app.UseCookieAuthentication(new CookieAuthenticationOptions 
      { 
       AuthenticationType = "ApplicationCookie", 
       LoginPath = new PathString("/auth/login") 
      }); 
     } 

입니다 쿠키가 다른 공급자의 다른 쿠키를 얻을 수 있으므로 올바른 쿠키와 연결하기 위해 클레임을 인스턴스화 할 때 AuthenticationType을 설정하는 것이 중요합니다.

+0

.NET Core에서는 상수를 'AuthenticationType'으로 사용할 수 있습니다.[CookieAuthenticationDefaults.AuthenticationScheme] (https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authentication.cookies.cookieauthenticationdefaults.authenticationscheme) 또는 [JwtBearerDefaults.AuthenticationScheme] (https://docs.microsoft. .com/en-us/dotnet/api/microsoft.aspnetcore.authentication.jwtbearer.jwtbearerdefaults.authenticationscheme). –