반응형

몇년전까지만해도(?) 타행기관 아이디로 로그인하는게 지금만큼 자유롭지 않았던 것 같은데,

이제는 개인정보보호법 등등... 플랫폼 기업의 아이디를 이용하는게 당연하게 느껴진다.

이제는 누구나 쉽게 google, kakao, naver, facebook 의 계정을 연동해서 자기만의 서비스를 연동할 수 있는 세상.

 

인증방식 중 Authorization Code 를 포스팅하려한다.

필자는 rhsso를 사용하고 있기 때문에 아래 표와 같이 테스트한다.

Authorzation Code 방식

1. 클라이언트가 rhsso 서버에 인증을 요청한다.

2. rhsso서버는 callback서버에 인가코드를 전달한다.

3. 인가코드를 받은 callback서버는 rhsso에 인가코드로 접근토큰 발급을 요청한다.

4. rhsso서버는 인가코드로 접근토큰을 발행한다.

 

기본적으로 위의 FLOW 대로 인증이 진행된다.

 

RHSSO 설정

1. client id 설정

- Authorization Code 허용

- redirect uri : http://localhost/callback

2. user 생성

3. end-point url 확인

4. 인가코드 유효시간 변경

- realm > token > client login timeout

 

콜백서버 설정

필자는 openresty 를 설치하여 로컬서버를 기동시켰고,

콜백url로 날라온 인가코드를 access log로 떨어뜨리는 lua script 설정을 하였다.

        location /callback {
            header_filter_by_lua_block {
                local h = ngx.req.get_headers()
                for k, v in pairs(h) do
                    ngx.log(ngx.ERR, "Got header "..k..": "..v..";")
                end
            }
            return 200 'good';
        }

실제호출시 log

더보기

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header sec-fetch-site: cross-site;, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header cookie: _ga=GA1.1.454948640.1649345810; sidebar_collapsed=false; diff_view=parallel;, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header sec-fetch-mode: navigate;, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header accept-language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7;, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header host: localhost;, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header accept-encoding: gzip, deflate, br;, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header connection: keep-alive;, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header sec-ch-ua-platform: "Windows";, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header cache-control: max-age=0;, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header sec-ch-ua-mobile: ?0;, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header upgrade-insecure-requests: 1;, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header sec-ch-ua: ".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103";, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36;, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header sec-fetch-dest: document;, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9;, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

2022/06/28 17:10:11 [error] 2116#23752: *13 [lua] header_filter_by_lua:4: Got header sec-fetch-user: ?1;, client: 127.0.0.1, server: localhost, request: "GET /callback?state=fj8o3n7bdy1op5&session_state=8613d3f9-103d-47d4-9808-cc4a9b719e1c&code=b361b8a6-5734-401e-b776-2572c2bf4ead.8613d3f9-103d-47d4-9808-cc4a9b719e1c.a2687358-0cc8-4907-8eff-8befb417b8bf HTTP/1.1", host: "localhost"

테스트1. Postman

postman에서 테스트를 해보면 자연스레 접근토큰까지 발행되는 것을 확인할 수 있다.

Get New Access Token 버튼을 누르면 로그인창이 뜨고 위에서 생성한 user를 입력하면 토큰이 발행된다.

인가코드가 날라가는 액션이 없었는데?

라고 생각되어 콘솔을 보면 302 redirect가 찍힌 뒤 200 응답이 온걸 확인할 수 있다.

테스트2. form.html

필자는 인가코드의 만료시간을 테스트하기 위해 딜레이가 필요하다.

그래서 인가코드를 가로챈 뒤, 유효시간 테스트를 진행하려고 step을 나누었다.

 

먼저 postman form을 통한게 아닌 별도의 form을 만들어 사용하였다.

<html>
  <head></head>
  <body>
    <form
      method="post"
      action="https://sso-rhsso.apps.mem5iy8b.australiaeast.aroapp.io/auth/realms/master/protocol/openid-connect/auth"
    >
      <input type="text" name="grant_type" value="authorization_code" />
      <input
        type="text"
        name="redirect_uri"
        value="http://localhost/callback"
      />
      <input
        type="text"
        name="auth_url"
        value="https://sso-rhsso.apps.mem5iy8b.australiaeast.aroapp.io/auth/realms/master/protocol/openid-connect/auth"
      />
      <input
        type="text"
        name="token_url"
        value="https://sso-rhsso.apps.mem5iy8b.australiaeast.aroapp.io/auth/realms/master/protocol/openid-connect/token"
      />
      <input type="text" name="client_id" value="b2b4dfac" />
      <input
        type="text"
        name="client_secret"
        value="2a528f4d-c4fc-40a3-a359-c1091fde12e8"
      />
      <input type="text" name="scope" value="profile" />
      <input type="text" name="response_type" value="code" />
      <input type="text" name="state" value="fj8o3n7bdy1op5" />
      <input type="submit" value="전송" />
    </form>
  </body>
</html>

 

그리고 openresty에 main.html 으로 저장한 뒤 웹에서 데이터를 입력하였다.

입력시 필요한 데이터

- grant_type/redirect_uriauth_url/token_url
- client_id/client_secret/scope
- response_type/state

 

이제 send 버튼을 누르면 openresty access log에 인가코드를 확인할 수 있다.

127.0.0.1 -JH- - [28/Jun/2022:16:31:52 +0900] 
	"GET /callback?
    	state=fj8o3n7bdy1op5
        &session_state=3b9199aa-0d2f-4bff-8aea-31ee163ad22c
        &code=5b7b5a42-91c0-4cc8-afe8-9a5583c66392.3b9199aa-0d2f-4bff-8aea-31ee163ad22c.a2687358-0cc8-4907-8eff-8befb417b8bf 
        HTTP/1.1" 200 4 "-" 123 "PostmanRuntime/7.29.0" "-"

이제 이 데이터로 접근토큰을 요청하면 끝이다.

 

반응형
복사했습니다!