JWTs 클라이언트 사용을 중지합니다.

9244 단어
이 블로그의 업데이트된 버전은 다음과 같습니다.
https://sedkodes.com/blog/lets-stop-using-jwts
토큰 흐름 분할: JWT 보안 문제 해결 방안
OAuth2, OIDC 및 그 기금회인 JWT는 여러 해 동안 업계 표준이었고 완화될 기미가 보이지 않았다.
JWT의 문제는 고유의 누출이다.지역 사회에서 대규모 논쟁이 벌어지고 있다. 어떤 사람들은 JWT for auth가 안전하지 않다고 생각한다. 왜냐하면 정보가 유출되기 때문이다. (b64를 통해 몸을 디코딩하기 때문에) 다른 사람들은 민감한 정보를 거기에 두어서는 안 된다고 생각한다.
이것이 바로 영패 흐름을 분할하는 작용이다.이 절차는 클라이언트에서만 JWT 액세스 영패의 서명을 사용하고 JWT 서버 측의 헤더와 성명을 저장하는 것을 권장합니다.따라서 분할 영패 흐름은 이 두 진영을 만족시켰다. 우리는 JWT 성명에 세션 정보를 저장함으로써 JWTs의 유연성을 얻었고, 불투명 방문 영패의 안전성을 얻었다. 왜냐하면 우리는 사실상 전체 영패를 공개하지 않고 서명만 공개하기 때문이다.
API 게이트웨이를 통해 이러한 작업을 수행하려면 어떻게 해야 합니까?
완전히 공개합니다. 저는 텍의 직원입니다.다음 설명서에는 Tyk Pro 제품의 화면 캡처가 포함되어 있습니다.그러나 OSS 게이트웨이를 사용해도 모든 기능을 무료로 이용할 수 있다.사실, 당신은 this repository를 조회할 수 있습니다. 이것은 OSS Tyk Gateway를 사용하여 남은 작업을 완성하는 방법을 안내하는 단계적인 안내서를 제공할 것입니다.
먼저 클라이언트 자격 증명 흐름의 예를 들어 클라이언트 ID와 비밀번호를 JWT 액세스 토큰으로 교환하고 이 토큰을 사용하여 API에 액세스할 수 있습니다.
$ curl -X POST -H 'Content-Type: application/x-www-form-urlencoded' https://keycloak-host/auth/realms/tyk/protocol/openid-connect/token \
-d grant_type=client_credentials \
-d client_id=efd952c8-df3a-4cf5-98e6-868133839433 \
-d client_secret=0ede3532-f042-4120-bece-225e55a4a2d6 \
> -s | jq
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJlbWFpbCI6ImhlbGxvQHdvcmxkLmNvbSJ9.EwIaRgq4go4R2M2z7AADywZ2ToxG4gDMoG4SQ1X3GJ0",
  "expires_in": 300,
  "token_type": "bearer",
  "not-before-policy": 0,
  "scope": "email profile"
그래서 우리는 JWT 방문 영패를 받았다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJlbWFpbCI6ImhlbGxvQHdvcmxkLmNvbSJ9.EwIaRgq4go4R2M2z7AADywZ2ToxG4gDMoG4SQ1X3GJ0
타이틀
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
몸뚱이
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJlbWFpbCI6ImhlbGxvQHdvcmxkLmNvbSJ9
서명하다.
EwIaRgq4go4R2M2z7AADywZ2ToxG4gDMoG4SQ1X3GJ0
우리는 그것을 jwt에 삽입할 수 있다.io 및 디코딩된 유효 로드를 보려면 다음과 같이 하십시오.

분명히 방문 영패에는 우리가 누설하고 싶지 않은 민감한 정보가 포함되어 있을 것이다.
API 게이트웨이는 클라이언트와 공인 서버 간의 에이전트로 완벽하게 포지셔닝됩니다.
이것은 클라이언트로부터 요청을 차단하고 클라이언트 id와 비밀번호를 수신하며 권한 수여 서버와 방문 영패로 교환할 수 있다.이 프록시 위치에서 API 게이트웨이는 JWT를 분할하고 실제 JWT 액세스 토큰의 서명 부분만 클라이언트에게 되돌려줍니다.그런 다음 JWT의 나머지 부분을 메타데이터로 저장합니다.
설정
Tyk 내부에서 가상 노드나 API를 만들고 경로 '/auth/token' 을 감청합니다.
가상 엔드포인트의 몇 가지 예제 코드를 살펴보겠습니다.
function login(request, session, config) {
    var credentials = request.Body.split("&")
        .map(function(item, index) {
            return item.split("=");
      }).reduce(function(p, c) {
             p[c[0]] = c[1];
             return p;
      }, {});

    var newRequest = {
      "Headers": {"Content-Type": "application/x-www-form-urlencoded"},
      "Method": "POST",
      "FormData": {
          grant_type: credentials.grant_type,
          client_id: credentials.client_id,
          client_secret: credentials.client_secret
      },
      "Domain": "https://keycloak-host",
      "resource": "/auth/realms/tyk/protocol/openid-connect/token",
    };

    var response = TykMakeHttpRequest(JSON.stringify(newRequest));
    var usableResponse = JSON.parse(response);

    if (usableResponse.Code !== 200) {
      return TykJsResponse({
        Body: usableResponse.Body,
        Code: usableResponse.Code
      }, session.meta_data)
    }

    var bodyObj = JSON.parse(usableResponse.Body);
    var accessTokenComplete = bodyObj.access_token;
    var signature = accessTokenComplete.split(".")[2];

    log("completeAccessToken: " + accessTokenComplete);

    // create key inside Tyk
    createKeyInsideTyk(signature, bodyObj)

    // override signature
    bodyObj.access_token = signature;
    delete bodyObj.refresh_expires_in;
    delete bodyObj.refresh_token;
    delete bodyObj.foo;

  var responseObject = {
    Body: JSON.stringify(bodyObj),
    Code: usableResponse.Code
  }
  return TykJsResponse(responseObject, session.meta_data)
}

function createKeyInsideTyk(customKey, meta) {
    // TODO: this needs to be a bit more dynamic. e.g. work out the policy id & API ID etc... based on the metadata
    var accessRights = {
        "c399587af48441d17bc5700339aa34fa": {
            "api_name": "Test API",
            "api_id": "c399587af48441d17bc5700339aa34fa",
            "versions": [
                "Default"
            ]
        }
    }

    log("meta: " + JSON.stringify(meta));

    var keyRequestBody = keyRequestTemplate;
    keyRequestBody.access_rights = accessRights;

    var newRequest = {
      "Headers": {"Content-Type": "application/json", "Authorization": "Bearer a4fcbde85a3c477d424922990eb16e01"},
      "Method": "POST",
      "Body": JSON.stringify(keyRequestBody),
      "Domain": "http://localhost:3000",
      "resource": "/api/keys/" + customKey,
    };

    var response = TykMakeHttpRequest(JSON.stringify(newRequest));
    log("createkeyintykres: " + response);
}

var keyRequestTemplate = {
    "apply_policies": [],
    "org_id" : "5d67b96d767e02015ea84a6f",
    "expires": 0,
    "allowance": 0,
    "per": 0,
    "quota_max": 0,
    "rate": 0,
    "access_rights": {}
}
이 코드는 다음을 수행합니다.
  • 가상 엔드포인트에서 클라이언트 ID+ 암호가 포함된 요청을 수신
  • 라이센스 서버로 요청을 전송하고 JWT 액세스 토큰
  • 을 받습니다.
  • 액세스 영패를 분리하여 Tyk에 불투명 키를 만듭니다. 이것은 JWT 액세스 영패
  • 의 서명입니다.
  • 방문 영패의 헤더와 주체를 메타데이터로 불투명 키에 추가하여 후속 요청에서 찾을 수 있도록 합니다
  • 불투명 키(서명)를 클라이언트에게 반환하고 클라이언트가 API
  • 에 액세스할 수 있음
    처음에는 고객 관점에서
    $ curl http://tyk-gw:8080/auth/token -X POST -H 'Content-Type: application/x-www-form-urlencoded' -d client_id=efd952c8-df3a-4cf5-98e6-868133839433 -d client_secret=0ede3532-f042-4120-bece-225e55a4a2d6 -d grant_type=client_credentials
    
    {"access_token":"MEwIaRgq4go4R2M2z7AADywZ2ToxG4gDMoG4SQ1X3GJ0","expires_in":300,"not-before-policy":0,"scope":"email profile","session_state":"fb8754d1-d518-40e8-a84f-85347a0639c8","token_type":"bearer"}
    
    불투명한 표시를 찾아보겠습니다.

    키의 메타데이터

    Create key payload에 추가된 액세스 권한에 따라 API 키를 테스트합니다.
    $ curl localhost:8080/basic-protected-api/get -H "Authorization: MEw….GJ0"
    {
      "args": {},
      "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip",
        "Authorization": "MEwIaRgq4go4R2M2z7AADywZ2ToxG4gDMoG4SQ1X3GJ0",
        "Host": "httpbin",
        "User-Agent": "curl/7.64.1"
      },
      "origin": "192.168.80.1",
      "url": "http://httpbin/get"
    }
    
    Tyk에서 불투명 토큰을 확인하고 API에 액세스할 수 있습니다.
    Tyk에서 전체 JWT를 재구성하여 업스트림 API에 안전하게 전달합니다.
    이전 단계에서, 우리는 완전한 JWT를 Tyk의 세션 영패의 메타데이터에 저장할 것이다.요청한 세션 메타데이터에서 JWT를 추출하여 요청 헤더에 주입할 수 있습니다.
    다음과 같이 API를 글로벌 헤더에 주입하도록 구성합니다.

    API 호출을 다시 시도해 보겠습니다.
    $ curl localhost:8080/basic-protected-api/get -H "Authorization: MEw….GJ0"
    {
      "args": {},
      "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip",
        "Authorization": "Bearer eyJh...1X3GJ0",
        "Host": "httpbin",
        "User-Agent": "curl/7.64.1"
      },
      "origin": "192.168.80.1",
      "url": "http://httpbin/get"
    }
    
    타다!
    보시다시피, 저희는 요청에 불투명한 영패만 보냈지만, Tyk는 JWT의 나머지 부분을 주입했습니다. Google 상위권은 업무 논리를 수행할 수 있습니다.
    질문이 있거나 대화를 시작하고 싶으시면 이메일[email protected]로 질문해 주시기 바랍니다.

    좋은 웹페이지 즐겨찾기