2017-09-20 11 views
5

(편집 - 적절한 수정을 찾을 수 아래 참조!)닷넷 코어 2.0 웹 API는 - 추가 ID는 JWT 인증을 나누기

OK -하지만,이 닷넷 코어 2.0 및 인증에 내 첫 번째 시도는 저는 과거에 Web API 2.0을 사용 해왔고 지난 몇 년 동안 다양한 MVC 및 Webforms ASP 프로젝트에서 상당히 광범위하게 작업했습니다.

.Net Core를 사용하여 웹 API 전용 프로젝트를 만들려고합니다. 이것은 몇 가지 보고서를 작성하는 멀티 테넌트 애플리케이션의 백 엔드를 형성 할 것이므로 사용자를 인증 할 수 있어야합니다. 일반적인 접근 방법은 JWT를 사용하는 것입니다. 먼저 사용자를 인증하여 토큰을 생성 한 다음이를 클라이언트에 전달하여 모든 API 요청에 사용합니다. 데이터는 EF 코어를 사용하여 저장되고 검색됩니다.

나는이 설정을 얻는 기본적인 방법으로 this post을 따라 갔다. 나는 이걸 제대로 작동하도록 만들었다. 나는 유효한 사용자 이름/패스워드를 받아들이고 토큰을 반환하는 컨트롤러를 가지고있다. 클레임에 따라

다음으로 필요한 것은 실제로 사용자/비밀번호/등을 관리하는 것입니다. 나는 내가 사용하는 줄 알았는데. NET 코어 ID는 사용자/역할, 패스워드 등등에 대해 걱정할 준비가 된 많은 코드를 가지고있다. 나는 User 커스텀 클래스와 클래스에서 파생 된 UserRole 클래스를 사용했다. 그리고 IdentityRole 클래스들 이었지만 지금은 표준 클래스로 되돌아 왔습니다.

내가 가진 문제는 ID를 추가하는 방법을 알아낼 수 없다는 것입니다. & 인증을 깨지 않고 모든 다양한 서비스 (rolemanager, usermanager 등)를 등록합니다. 기본적으로이 줄을 내 Startup.ConfigureServices 클래스 :

services.AddIdentity<IdentityUser, IdentityRole>() 
    .AddEntityFrameworkStores<MyContext>(); 

그것은 모든 잘못되면, 내가 요청을받을 때 나는 더 이상 주장을 볼 수 없습니다, 그래서 모든 정책은 잠그고 당신은 아무것도 얻을 수 없습니다.

그 줄이 없다면 UserManager, RoleManager, UserStore 등과 관련된 오류가 DI에 등록되지 않은 상태로 끝납니다.

그래서 ... (가능한 경우) ID를 등록하고 컨텍스트에 올바르게 연결하지만 실제 인증 메커니즘에 대한 변경을 피하거나 제거 할 수 있습니까?

나는 온라인에서 공정한 비트를 살펴 봤지만 .Net Core 1.x 이후로 많은 변화가 있었으므로 많은 튜토리얼 등은 더 이상 유효하지 않습니다.

프런트 엔드 코드가있는이 API 응용 프로그램을 의도하지 않으므로 양식이나 기타 지금은 쿠키 인증이 필요하지 않습니다.

편집
좋아, 내가 지금이 코드에서 Startup.ConfigureServices() 방법에 JWT 인증을 설정하는 것으로 나타났습니다 : "나는 통해 (표시된 줄에 중단 점을 넣으면

services.AddAuthentication(
      JwtBearerDefaults.AuthenticationScheme) 
       .AddJwtBearer(options => 
       { 
       >>breakpoint>>> options.TokenValidationParameters = 
         new TokenValidationParameters 
         { 
          ValidateIssuer = true, 
          ValidateAudience = true, 
          ValidateLifetime = true, 
          ValidateIssuerSigningKey = true, 

          ValidIssuer = "Blah.Blah.Bearer", 
          ValidAudience = "Blah.Blah.Bearer", 
          IssuerSigningKey = 
          JwtSecurityKey.Create("verylongsecretkey") 

         }; 
       }); 

> > breakpoint >>> ") 그러면 이 안되면 아이덴티티 서비스를 추가하기위한 라인을 추가합니다.하지만 그 라인을 추가하면 결코이 발생합니다. 이는 내가 메서드에서 어디에 services.AddIdentity() 호출을했는지에 상관없이 사실입니다.나는 이것이 나중에 람다 (lambda)가되어 나중에 실행될 것이지만, AddIdentity 물건을 인증을 설정하지 못하게하거나 코드를 즉시 제거 할 수있는 방법이 있습니까? 당신이 :)

이 있다면 나는 ... 설정은 Identity 물건이 이미 설정 한대로 내가 거기에 설정 한의 람다를 실행하지 선출 일부 코드가있어 어느 시점에서 모든 것을 읽을 수

감사를 가정 기본적으로 https://github.com/aspnet/Identity/issues/1376

내가해야 할 일을했을 두 가지 무엇 : -

편집을 찾을 수
확인 대답은, 나는 결국 기본적으로 정확히이 문제가이 GH 문제를 발견

ENS

services.AddAuthentication(
      JwtBearerDefaults.AuthenticationScheme) 
       .AddJwtBearer(options => 
... 

에 : services.AddIdentity<IdentityUser, IdentityContext()에 대한 호출에서 인증을 추가 할 수 첫번째

변경 호출 만들어 졌다고 URE

services.AddAuthentication(options => 
     { 
      options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; 
      options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; 
     }) 
      .AddJwtBearer(options => 
... 

이것은 성가 시게 쿠키 사고로 이어질 생성되는, 그러나 이것은 내가 인증 할 수있는 범위 내에서 사용되지 않는다. 적어도 순전히 컨트롤러/요청에 대한 베어러 토큰을 사용하여 [Authorize(Policy = "Administrator")] 또는 비슷한 세트를 가지고있다.

더 많은 테스트가 필요하며, 어떤 식 으로든 작동하지 않는다면이 업데이트를 다시 시도하려고합니다.

(편집 - 지금 답변으로에 적절한 솔루션을 넣어)

내 게시물을 편집 한 나는 실제로이에두고있어 사용자 alwayslearning의 제안에 그래서 결국, 함께 해결책을 넣어
+0

나를 구해 줬습니다. 덕분에 –

+0

당신은 이것을 질문으로 분해 한 다음 스스로를 적절한 대답으로 대답하는 것을 고려해야합니다. – alwayslearning

+0

@alwayslearning은 나쁜 생각이 아닙니다 ... 그래서 그렇게했습니다. – GPW

답변

3

대답.

좋습니다. 제대로 수행 할 수 있습니다. 먼저 위의 편집에서 지적한 인증 옵션을 사용해야합니다. 괜찮습니다. services.AddIdentity<TUser>() 대신 services.AddIdentityCore<TUser>()을 사용해야합니다. 그러나 이것은 역할 관리를위한 모든 것을 추가하지는 않으며 사용하려는 역할의 유형을 부여하는 적절한 생성자가 부족한 것 같습니다. 다음 것은 (이전 토큰을 전송하는) 사용자 로그인의 유효성을 검사 할 때, 당신은을 사용해야합니다 있는지 확인하는 것입니다

IdentityBuilder builder = services.AddIdentityCore<IdentityUser>(opt => 
     { 
      opt.Password.RequireDigit = true; 
      opt.Password.RequiredLength = 8; 
      opt.Password.RequireNonAlphanumeric = false; 
      opt.Password.RequireUppercase = true; 
      opt.Password.RequireLowercase = true; 
     } 
     ); 
     builder = new IdentityBuilder(builder.UserType, typeof(IdentityRole), builder.Services); 
     builder 
      .AddEntityFrameworkStores<MyContext>(); 
     //.AddDefaultTokenProviders(); 

     builder.AddRoleValidator<RoleValidator<IdentityRole>>(); 
     builder.AddRoleManager<RoleManager<IdentityRole>>(); 
     builder.AddSignInManager<SignInManager<IdentityUser>>(); 

가 다 끝나면 : 이것은 내 경우에는 내가이 일을 한 것을 의미한다 SignInManager 방법 CheckPasswordSignInAsync하지PasswordSignInAsync : 당신이 PasswordSignInAsync 방법을 사용하는 경우

public async Task<IdentityUser> GetUserForLogin(string userName, string password) 
    { 
     //find user first... 
     var user = await _userManager.FindByNameAsync(userName); 

     if (user == null) 
     { 
      return null; 
     } 

     //validate password... 
     var signInResult = await _signInManager.CheckPasswordSignInAsync(user, password, false); 

     //if password was ok, return this user. 
     if (signInResult.Succeeded) 
     { 
      return user; 
     } 

     return null; 
    } 

는 다음 런타임 오류 재를 얻을 수 있습니다. IAuthenticationSignInHandler가 구성되어 있지 않습니다.

누군가가 도움이되기를 바랍니다.

+0

당신은 확실히 나를 도왔습니다. 고마워. JWT 또는 ID에 대한 경험이 없으므로 해결책을 찾기가 어려울 때 인터넷에 구식 튜터리얼이 많이 있습니다. –