keycloak access token 발급받기

뿌이·2022년 3월 11일
0

스프링 클라우드

목록 보기
25/32

spring security + keycloak 좀 더 효율적인 방법
나중에 공부를 더 하며 알아낸 방법이다.
현재 페이지의 글 보다는 링크의 글이 조금 더 효율적임을 밝힌다.

키클락을 사용하는 사람 중 블로그를 쓰는 사람은 얼마없을텐데
우리나라사람은 정말없어서 영어 문서를 정말정말 많이봤다......
그래서 내가 정리하고자한다
앞으로 나아가야하기 때문에........

일단 실습이고 프로젝트에 적용하려면 다시 해야함
필자는 일단 이해해보기 위해 하나의 서비스에서 진행했다.

전제

MSA구조의 프로젝트에서 진행
gateway에 keycloak 연동되어있는 상태임
그리고 keycloak에 redirect_url이라던지, 회원가입 및 회원에 role 설정 다 해둔 상황임

필자는 usercontroller에서 진행하고자함.
gateway에 키클락 연동해놓았으나 현재 블로그 글에서는
gateway 포트로 접근하지 않을것임
(실습을 하며 이해할 것이기 때문에)

user controller

user service의 port번호는 64412이다.

package com.dream.userservice.controller;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
	
	@RequestMapping(value="/", method = RequestMethod.GET)
	public String home() {
		System.out.println("controller stasrt");
		
		return "index";
	}
	
   @GetMapping(path = "/service")//service로 접근하면 일단 무조건 로그인으로 보내줌
   public void user_service(HttpServletRequest request, HttpServletResponse response) 
   throws ServletException, IOException {
   
      String id_token = "";
      String access_token = "";
      System.out.println("들어와지나 userServiced입니다");
//      if (id_token == null || id_token == "") {
//         login(request, response);
//         //response.sendRedirect("http://localhost:8480/login");
//         
//      }
      
      //할 일 : access_token 존재확인 (id token과 access token 둘다 null , "" 인지 검증해야함 
      if (access_token == null || id_token == "") {
         login(request, response);
         //response.sendRedirect("http://localhost:8480/login");
      }
 
   }

   @GetMapping(path = "/login") //로그인에서는 keycloak 로그인창 url로 보내줌
   public void login(HttpServletRequest request, HttpServletResponse response) 
   throws ServletException, IOException {
	   //todo make keycloak login url
      try {
         response.sendRedirect("http://localhost:8080/auth/realms/MSA/protocol/
         openid-connect/auth?response_type=code&client_id=memberService&
         redirect_uri=http://localhost:64412/auth&scope=openid&nonce=asb3");
      }
      catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
      
      return;
   }
  
   @GetMapping(path = "/auth") //로그인 성공시 받을 수 있는 url : keycloak에서 설정한 redirect url
   public String auth(HttpServletRequest request, HttpServletResponse response,Model model) 
   throws ServletException, IOException {
      //to do token save
	  //String id_token = request.getParameter("id_token");
      String code = request.getParameter("code");
      String query = "code=" + URLEncoder.encode(code,"UTF-8");
      query += "&client_id=" + "memberService";
      query += "&client_secret=" + "클라이언트 시크릿 쓰면됨";
      query += "&redirect_uri=" + "http://localhost:64412/auth";
      query += "&grant_type=authorization_code";
      
      String tokenJson = getHttpConnection("http://localhost:8080/auth/realms/MSA/protocol/openid-connect/token",
      query);

      return tokenJson;

   }
   
   private String getHttpConnection(String uri, String param) throws ServletException, IOException {
	      URL url = new URL(uri);
	      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
	      conn.setRequestMethod("POST");
	      conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
	      conn.setDoOutput(true);
	      try (OutputStream stream = conn.getOutputStream()) {
	      try (BufferedWriter wd = new BufferedWriter(new OutputStreamWriter(stream))) {
	      wd.write(param);
	      }
	      }
	      int responseCode = conn.getResponseCode();
	      System.out.println(responseCode);
	      String line;
	      StringBuffer buffer = new StringBuffer();
	      try (InputStream stream = conn.getInputStream()) {
	      try (BufferedReader rd = new BufferedReader(new InputStreamReader(stream))) {
	      while ((line = rd.readLine()) != null) {
	      buffer.append(line);
	      buffer.append('\r');
	      }
	      }
	      } catch (Throwable e) {
	      e.printStackTrace();
	      }
	      return buffer.toString();
	      }
   
}

설명

먼저 url에서 localhost:64412/service 로 접근시
access token과 id token이 null인지 확인해주고,
null일 시 keycloak의 로그인 url로 가게 설정 해두었음

로그인 완료 되면

json방식으로 받게된다.

todo

이제 할 일은
1. access token과 id_token 둘 중 하나라도 null 이나 ""일시 로그인창 이동시키기. (조건 정확하게)
2. access token 값을 json 파싱해서 값 저장하고 jwt 형식으로 되어있기 때문에 decode한다
3. decode하면 url_id나 scope같은 여러 유저정보가 들어있을 것이다

이런식으로 말이다.
4. id_token, access_token 을 어떻게 사용할지, 공유할지 생각하고 고민해보기

나아가자!!!

profile
기록이 쌓이면 지식이 된다.

0개의 댓글