2017-12-21 9 views
0

.net 코어 2.0에 액세스 할 수 있도록 클라이언트 응용 프로그램에 JSON 웹 토큰을 보내는 데 사용하려는 인증 시스템이 PHP에 설치되어 있습니다. api. 따라서 인증 서버는 사용자 자격 증명을 사용하고 자격 증명이 통과되면 openssl을 사용하여 만든 공용/개인 키 쌍을 사용하여 토큰을 생성합니다. 여기에 절차를 사용하여 토큰을 생성하고 있습니다 : http://www.phpbuilder.com/articles/application-architecture/security/using-a-json-web-token-in-php.html.net core 2.0의 무기명 오류 = "invalid_token"

jwt.io를 사용하여 결과 토큰을 디코드 할 수 있습니다.

{ 
    "typ": "JWT", 
    "alg": "HS256" 
} 

{ 
    "iss": "https://crm.advtis.com", 
    "exp": "2017-12-21 18:14:42", 
    "aud": "https://localhost:44354", 
    "data": { 
    "username": "[email protected]", 
    "role": 1 
    } 
} 

내가 토큰을 인코딩하는 데 사용 된 내 개인 키 파일에서 문자열을 입력 할 수 있으며 jwt.io는 서명이 유효 말한다 : 디코딩 된 버전은 다음과 같습니다.

이제 토큰을 내 API로 보내서 해당 리소스에 액세스하려고합니다. 로컬 서버에서 디버깅하는 동안 해당 리소스에 액세스 할 수 있습니다.

public void ConfigureServices(IServiceCollection services) 
     { 
      services.AddDbContext<SmartRxDBContext>(); 

      services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) 
      .AddJwtBearer(options => 
      { 
       options.Audience = "https://localhost:44354/"; 
       options.TokenValidationParameters = new TokenValidationParameters { 
        ValidateIssuerSigningKey = true, 
        ValidateIssuer = true, 
        ValidIssuer = "https://crm.advtis.com/", 
        IssuerSigningKey = new X509SecurityKey(new X509Certificate2("C:\\Path\\To\\webOrders-cert-AspNetPubkey.cert")) 
       }; 
      }); 
      services.AddMvc(); 
     } 

참조하는 경로가 나는 또한 JWT를 인코딩하는 데 사용되는 개인 키에서하려면 openssl을 사용하여 생성 된 PEM 형식의 공개 키에 있습니다 : 여기에 관련된 .NET 2.0 시작 코드입니다. .NET 코어 조각 인 JWT Validation and Authorization in ASP.NET Core 에 대해이 예제를 따르려고했지만 물론 모든 인증 미들웨어 구성이 2.0에서 ConfigureServices 메소드로 옮겨졌으며 더 이상 자동 인증 옵션이 없습니다.

모든 것이 잘되는 것처럼 보이지만 헤더가있는 요청을 할 때 Unauthorized Bearer 오류 = "invalid_token"오류가 발생합니다. Authorization: Bearer TOKEN 어쨌든 누군가가 나에게 내가 할 수있는 조언을 줄 수 있기를 바랍니다. 잘못 될 수 있으며 어떻게 문제를 해결할 수 있습니까?

답변

0

그래서이 동일한 유형의 시나리오를 실행하려는 사람을 위해 알아 냈습니다.

첫 번째 문제는 HMAC를 사용하여 PHP 측에서 토큰을 생성한다는 것입니다. HMAC는 공용/개인 쌍 알고리즘이 아닙니다. 나는 작곡가와 firebase/php-jwt 라이브러리를 설치하고,이 같은 내 토큰을 생성하는 것을 사용 : 키 파일이 OpenSSL을 사용하여 명령 행에서 생성 된

use \Firebase\JWT\JWT; 
$token = array(  
"iss" => "https://crm.advtis.com", 
"exp" => time()+10000, 
"aud" => "https://localhost:44354", 
"data" => array(
    "username" => "[email protected]", 
    "role" => 1 
) 
); 

$jwt = JWT::encode($token, file_get_contents("../path/to/private.key"), 'RS256'); 

합니다. 필자는 동일한 유틸리티를 사용하여 개인 키로 공개 키를 생성했습니다. 두 파일 모두 PEM 형식입니다.

다음으로해야 할 일은 .NET에 공개 키를 가져 오는 것입니다. 내가 찾은 가장 쉬운 방법은 일종의 같이, RSACryptoServiceProvider를 사용 할 수 있습니다 :

에서 매개 변수를 가져 오거나 설정 .NET 2.0 방법이 없기 때문에 JwtHelper.FromXml() 메소드는, here에서 적응했다
private static RSACryptoServiceProvider myRSA = new RSACryptoServiceProvider(); 
public void ConfigureServices(IServiceCollection services) 
    { 
     JwtHelper.FromXmlString(myRSA, "C:\\Users\\Path\\To\\xmlPubKey.xml"); 
     services.AddDbContext<SmartRxDBContext>(); 

     services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) 
     .AddJwtBearer(options => 
     { 
      options.TokenValidationParameters = new TokenValidationParameters { 
       ValidateIssuerSigningKey = true, 
       ValidateIssuer = true, 
       ValidIssuer = "https://crm.advtis.com", 
       ValidateAudience = true, 
       ValidAudience = "https://localhost:44354", 
       IssuerSigningKey = new RsaSecurityKey(myRSA.ExportParameters(false)) 
      }; 
     }); 
     services.AddMvc(); 

    } 

RSA는 제공자 내에서 XML, 그래서 그 방법은 XML을 구문 분석과 같이 매개 변수를 설정합니다

public static void FromXml(this RSA rsa, string filepath) 
    { 
     RSAParameters parameters = new RSAParameters(); 

     XmlDocument xmlDoc = new XmlDocument(); 
     xmlDoc.Load(filepath); 

     if (xmlDoc.DocumentElement.Name.Equals("RSAKeyValue")) 
     { 
      foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes) 
      { 
       switch (node.Name) 
       { 
        case "Modulus": parameters.Modulus = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; 
        case "Exponent": parameters.Exponent = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; 
        case "P": parameters.P = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; 
        case "Q": parameters.Q = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; 
        case "DP": parameters.DP = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; 
        case "DQ": parameters.DQ = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; 
        case "InverseQ": parameters.InverseQ = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; 
        case "D": parameters.D = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; 
       } 
      } 
     } 
     else 
     { 
      throw new Exception("Invalid XML RSA key."); 
     } 

     rsa.ImportParameters(parameters); 
    } 

은 그래서 그것의 요점입니다. 이제 PHP 서버에서 클라이언트 애플리케이션으로 JWT를 발행 할 수있다. 그런 다음 JWT를 .NET Core 2.0 API로 보내어 [Authorize] 속성으로 보호되는 끝점에 액세스 할 수 있습니다.