[Keycloak] Keycloak과 Spring Boot 연동

Posted by 김성철

Keycloak과 Spring Boot 연동

프로젝트 생성

* maven 사용  
name : keycloak  
  
아래의 디펜던시 선택 후 생성  
	Spring boot DevTool  
	Lombok  
	Spring Web  

application.properties 변경

application.properties  ->  application.yml 로 확장자 변경  

Spring security 추가

※ 처음에 추가해도 되는데 추가를 안해서 지금 추가했	음  
  
pom.xml 파일에 아래의 내용 추가  
=================================================================================================================  
    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-security</artifactId>  
    </dependency>  
=================================================================================================================  
  
* 그래들의 경우 아래의 내용추가  
=================================================================================================================  
implementation 'org.springframework.boot:spring-boot-starter-security'  
=================================================================================================================  

keycolak.version 추가

pom.xml 파일을 열어서 <keycloak.version>9.0.2</keycloak.version> 추가  
=================================================================================================================  
<properties>  
    <java.version>1.8</java.version>  
    <keycloak.version>9.0.2</keycloak.version>  
</properties>  
  
=================================================================================================================  

keycolak 라이브러리 추가

pom.xml 파일을 열어서 keycolak 라이브러리 추가  
=================================================================================================================  
  
<dependency>  
	<groupId>org.keycloak</groupId>  
	<artifactId>keycloak-spring-boot-starter</artifactId>  
	<version>${keycloak.version}</version>  
</dependency>  
=================================================================================================================  
  
* 그래들의 경우 아래의 내용 추가  
=================================================================================================================  
implementation group: 'org.keycloak', name: 'keycloak-spring-boot-starter', version: '9.0.2'  
=================================================================================================================  

KeycloakSecurityConfig 클래스 생성

경로 : keycloak\src\main\java\com\sungchul\keycloak\config  
파일명 : KeycloakSecurityConfig.java  
=================================================================================================================  
package com.sungchul.keycloak.config;  
  
import org.keycloak.adapters.KeycloakConfigResolver;  
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;  
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;  
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;  
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;  
import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;  
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;  
import org.springframework.security.core.session.SessionRegistryImpl;  
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;  
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;  
  
@Configuration  
@EnableWebSecurity  
@EnableGlobalMethodSecurity(jsr250Enabled = true)  
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {  
  
	@Override  
	protected void configure(HttpSecurity http) throws Exception {  
		super.configure(http);  
		http  
				.authorizeRequests()  
				.antMatchers("/test/permitAll").permitAll()  
				.antMatchers("/test/authenticated").authenticated()  
				.antMatchers("/test/user").hasAnyRole("USER")  
				.antMatchers("/test/admin").hasAnyRole("ADMIN")  
				.anyRequest()  
				.permitAll();  
		http.csrf().disable();  
	}  
  
	@Autowired  
	public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {  
		KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();  
		keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());  
		auth.authenticationProvider(keycloakAuthenticationProvider);  
	}  
  
	@Bean  
	@Override  
	protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {  
		return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());  
	}  
  
	@Bean  
	public KeycloakConfigResolver KeycloakConfigResolver() {  
		return new KeycloakSpringBootConfigResolver();  
	}  
}  
  
=================================================================================================================  

TestController 클래스 생성

경로 : C:\IntellijProject\keycloak\src\main\java\com\sungchul\keycloak\controller\  
파일명 : TestController.java  
=================================================================================================================  
package com.sungchul.keycloak.controller;  
  
import lombok.extern.slf4j.Slf4j;  
import org.springframework.http.ResponseEntity;  
import org.springframework.web.bind.annotation.RequestHeader;  
import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.bind.annotation.RequestMethod;  
import org.springframework.web.bind.annotation.RestController;  
  
@Slf4j  
@RestController  
@RequestMapping("/test")  
public class TestController {  
  
	@RequestMapping(value = "/permitAll", method = RequestMethod.GET)  
	public ResponseEntity<String> permitAll() {  
		return ResponseEntity.ok("누구나 접근이 가능합니다.\n");  
	}  
  
	@RequestMapping(value = "/authenticated", method = RequestMethod.GET)  
	public ResponseEntity<String> authenticated(@RequestHeader String Authorization) {  
		log.debug(Authorization);  
		return ResponseEntity.ok("로그인한 사람 누구나 가능합니다.\n");  
	}  
  
	@RequestMapping(value = "/user", method = RequestMethod.GET)  
	public ResponseEntity<String> user(@RequestHeader String Authorization) {  
		log.debug(Authorization);  
		return ResponseEntity.ok("user 가능합니다.\n");  
	}  
  
	@RequestMapping(value = "/admin", method = RequestMethod.GET)  
	public ResponseEntity<String> admin(@RequestHeader String Authorization) {  
		log.debug(Authorization);  
		return ResponseEntity.ok("admin 가능합니다.\n");  
	}  
  
}  
  
=================================================================================================================  

application.yml 파일 수정

아래 작성하는 내용에 대한 정보는  
keycloak 에서 생성한 clien 의 installation  탭에서 확인이 가능함  
  
※아래의 부분은 오류가 발생해서 추가한 내용  
참고링크 : https://stackoverflow.com/questions/70207564/spring-boot-2-6-regression-how-can-i-fix-keycloak-circular-dependency-in-adapte  
spring:  
  main:  
	allow-circular-references : true  
  
=================================================================================================================  
  
server:  
  port: 9999  
  
keycloak:  
  realm: demo  
  auth-server-url: http://localhost:8080/auth  
  ssl-required: external  
  resource: my_client  
  credentials:  
	secret: XafEZWyEQDgd0rmn86rO4H7K674l5zM9  
  use-resource-role-mappings: true  
  bearer-only: true  
  
logging:  
  level:  
	root: INFO  
	com.sumgchul.keycloak: DEBUG  
  
spring:  
  main:  
	allow-circular-references : true  
  
=================================================================================================================  

테스트

1. curl -X GET "http://localhost:9999/test/permitAll"  
	누구나 접근 가능  
	-성공  
  
2. curl -X GET "http://localhost:9999/test/authenticated"  
  
	2-1.  
		curl -X POST "http://localhost:8080/auth/realms/demo/protocol/openid-connect/token" ^  
		--header "Content-Type:application/x-www-form-urlencoded" ^  
		--data-urlencode "grant_type=password" ^  
		--data-urlencode "client_id=my_client" ^  
		--data-urlencode "client_secret=XafEZWyEQDgd0rmn86rO4H7K674l5zM9" ^  
		--data-urlencode "username=sungchul" ^  
		--data-urlencode "password=admin"  
  
	2-2.  
		액세스토큰 : eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJPdGViQldzSmdhRWozeXVaMGZlbTVWclFmbkZpcDlLczE5aVN6anBybGw0In0.eyJleHAiOjE2NDQ0MjkxMjQsImlhdCI6MTY0NDM5MzEyNCwianRpIjoiZTE5MjA0YjgtZGFjMi00ZTlhLTkwNjgtMjU1MTRhZTNiZmY5IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL2RlbW8iLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNzNkNWYwOWUtZTY2Ny00YjA2LTgwZDctMTk3ZDM1NzQyNmQ0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibXlfY2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6IjgzNjI3NmM1LTAxMDgtNDUxZS05OTdiLWNkMjcyMjRjYTJiMiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDo4MDgwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIiwiZGVmYXVsdC1yb2xlcy1kZW1vIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsibXlfY2xpZW50Ijp7InJvbGVzIjpbIlJPTEVfVVNFUiJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJwcm9maWxlIGVtYWlsIiwic2lkIjoiODM2Mjc2YzUtMDEwOC00NTFlLTk5N2ItY2QyNzIyNGNhMmIyIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoia2ltIHN1bmdjaHVsIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic3VuZ2NodWwiLCJnaXZlbl9uYW1lIjoia2ltIiwiZmFtaWx5X25hbWUiOiJzdW5nY2h1bCIsImVtYWlsIjoia2ltc2MxMjE4QGdtYWlsLmNvbSJ9.jx6pdr87_wjURnbcq9fAqmwB7k0lq3nODwBieTqtkk6QVoSCU5yXqlKaajFSUShb_jh0jq3yVL5NVmqiRaqLmHb_Y55wrs4dCUbbjKdJXTBLP7W4xSOEwlm81PtZYfoCMcU5pmKAkbEUllDJxjSsbkM2SPkWl9Y7DMTT1SgTlBMHsxabwLI_O-6rUzkEVyL2v7ALX1MqTAsuyLVlF8ckgEIWzFHh1f325oJFlnStoAvw_bcTa5z1rIUgDN7quPLGwsnj6Y1M-5Ezfm7I932L4nWYQIbWvJRtpVkD7x8eOhDtyfmE_UG80LhiYyqbgJwWxzgeM9Q_jUmG3DGMIB_xFw  
  
	2-3.  
		curl -X GET "http://localhost:9999/test/authenticated" ^  
		--header "Authorization : Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJPdGViQldzSmdhRWozeXVaMGZlbTVWclFmbkZpcDlLczE5aVN6anBybGw0In0.eyJleHAiOjE2NDQ0MjkxMjQsImlhdCI6MTY0NDM5MzEyNCwianRpIjoiZTE5MjA0YjgtZGFjMi00ZTlhLTkwNjgtMjU1MTRhZTNiZmY5IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL2RlbW8iLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNzNkNWYwOWUtZTY2Ny00YjA2LTgwZDctMTk3ZDM1NzQyNmQ0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibXlfY2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6IjgzNjI3NmM1LTAxMDgtNDUxZS05OTdiLWNkMjcyMjRjYTJiMiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDo4MDgwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIiwiZGVmYXVsdC1yb2xlcy1kZW1vIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsibXlfY2xpZW50Ijp7InJvbGVzIjpbIlJPTEVfVVNFUiJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJwcm9maWxlIGVtYWlsIiwic2lkIjoiODM2Mjc2YzUtMDEwOC00NTFlLTk5N2ItY2QyNzIyNGNhMmIyIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoia2ltIHN1bmdjaHVsIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic3VuZ2NodWwiLCJnaXZlbl9uYW1lIjoia2ltIiwiZmFtaWx5X25hbWUiOiJzdW5nY2h1bCIsImVtYWlsIjoia2ltc2MxMjE4QGdtYWlsLmNvbSJ9.jx6pdr87_wjURnbcq9fAqmwB7k0lq3nODwBieTqtkk6QVoSCU5yXqlKaajFSUShb_jh0jq3yVL5NVmqiRaqLmHb_Y55wrs4dCUbbjKdJXTBLP7W4xSOEwlm81PtZYfoCMcU5pmKAkbEUllDJxjSsbkM2SPkWl9Y7DMTT1SgTlBMHsxabwLI_O-6rUzkEVyL2v7ALX1MqTAsuyLVlF8ckgEIWzFHh1f325oJFlnStoAvw_bcTa5z1rIUgDN7quPLGwsnj6Y1M-5Ezfm7I932L4nWYQIbWvJRtpVkD7x8eOhDtyfmE_UG80LhiYyqbgJwWxzgeM9Q_jUmG3DGMIB_xFw"  
  
	2-4. 실패  
		※ curl 로 테스트 불가,  
		https://stackoverflow.com/questions/58593645/tomcat-9-header-line-does-not-conform-to-rfc-7230?rq=1  
		rfc-7230 관련 오류가 발생함 이부분은 cmd 에서 실행하지 말고 postman 으로 실행  
  
	2-5. postman 으로 실행  
		Get : http://localhost:9999/test/authenticated  
		Headers  
			key : Authorization  
			value : bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJPdGViQldzSmdhRWozeXVaMGZlbTVWclFmbkZpcDlLczE5aVN6anBybGw0In0.eyJleHAiOjE2NDQ0MjkxMjQsImlhdCI6MTY0NDM5MzEyNCwianRpIjoiZTE5MjA0YjgtZGFjMi00ZTlhLTkwNjgtMjU1MTRhZTNiZmY5IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL2RlbW8iLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNzNkNWYwOWUtZTY2Ny00YjA2LTgwZDctMTk3ZDM1NzQyNmQ0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibXlfY2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6IjgzNjI3NmM1LTAxMDgtNDUxZS05OTdiLWNkMjcyMjRjYTJiMiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDo4MDgwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIiwiZGVmYXVsdC1yb2xlcy1kZW1vIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsibXlfY2xpZW50Ijp7InJvbGVzIjpbIlJPTEVfVVNFUiJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJwcm9maWxlIGVtYWlsIiwic2lkIjoiODM2Mjc2YzUtMDEwOC00NTFlLTk5N2ItY2QyNzIyNGNhMmIyIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoia2ltIHN1bmdjaHVsIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic3VuZ2NodWwiLCJnaXZlbl9uYW1lIjoia2ltIiwiZmFtaWx5X25hbWUiOiJzdW5nY2h1bCIsImVtYWlsIjoia2ltc2MxMjE4QGdtYWlsLmNvbSJ9.jx6pdr87_wjURnbcq9fAqmwB7k0lq3nODwBieTqtkk6QVoSCU5yXqlKaajFSUShb_jh0jq3yVL5NVmqiRaqLmHb_Y55wrs4dCUbbjKdJXTBLP7W4xSOEwlm81PtZYfoCMcU5pmKAkbEUllDJxjSsbkM2SPkWl9Y7DMTT1SgTlBMHsxabwLI_O-6rUzkEVyL2v7ALX1MqTAsuyLVlF8ckgEIWzFHh1f325oJFlnStoAvw_bcTa5z1rIUgDN7quPLGwsnj6Y1M-5Ezfm7I932L4nWYQIbWvJRtpVkD7x8eOhDtyfmE_UG80LhiYyqbgJwWxzgeM9Q_jUmG3DGMIB_xFw  
  
		로그인한 사람 누구나 가능합니다.  
		- 성공  
  
3. curl -X GET "http://localhost:9999/test/admin"  
  
	3-1.  
		curl -X POST "http://localhost:8080/auth/realms/demo/protocol/openid-connect/token" ^  
		--header "Content-Type:application/x-www-form-urlencoded" ^  
		--data-urlencode "grant_type=password" ^  
		--data-urlencode "client_id=my_client" ^  
		--data-urlencode "client_secret=XafEZWyEQDgd0rmn86rO4H7K674l5zM9" ^  
		--data-urlencode "username=sungchul" ^  
		--data-urlencode "password=admin"  
  
		액세스토큰 : eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJPdGViQldzSmdhRWozeXVaMGZlbTVWclFmbkZpcDlLczE5aVN6anBybGw0In0.eyJleHAiOjE2NDQ0MjkxMjQsImlhdCI6MTY0NDM5MzEyNCwianRpIjoiZTE5MjA0YjgtZGFjMi00ZTlhLTkwNjgtMjU1MTRhZTNiZmY5IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL2RlbW8iLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNzNkNWYwOWUtZTY2Ny00YjA2LTgwZDctMTk3ZDM1NzQyNmQ0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibXlfY2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6IjgzNjI3NmM1LTAxMDgtNDUxZS05OTdiLWNkMjcyMjRjYTJiMiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDo4MDgwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIiwiZGVmYXVsdC1yb2xlcy1kZW1vIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsibXlfY2xpZW50Ijp7InJvbGVzIjpbIlJPTEVfVVNFUiJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJwcm9maWxlIGVtYWlsIiwic2lkIjoiODM2Mjc2YzUtMDEwOC00NTFlLTk5N2ItY2QyNzIyNGNhMmIyIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoia2ltIHN1bmdjaHVsIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic3VuZ2NodWwiLCJnaXZlbl9uYW1lIjoia2ltIiwiZmFtaWx5X25hbWUiOiJzdW5nY2h1bCIsImVtYWlsIjoia2ltc2MxMjE4QGdtYWlsLmNvbSJ9.jx6pdr87_wjURnbcq9fAqmwB7k0lq3nODwBieTqtkk6QVoSCU5yXqlKaajFSUShb_jh0jq3yVL5NVmqiRaqLmHb_Y55wrs4dCUbbjKdJXTBLP7W4xSOEwlm81PtZYfoCMcU5pmKAkbEUllDJxjSsbkM2SPkWl9Y7DMTT1SgTlBMHsxabwLI_O-6rUzkEVyL2v7ALX1MqTAsuyLVlF8ckgEIWzFHh1f325oJFlnStoAvw_bcTa5z1rIUgDN7quPLGwsnj6Y1M-5Ezfm7I932L4nWYQIbWvJRtpVkD7x8eOhDtyfmE_UG80LhiYyqbgJwWxzgeM9Q_jUmG3DGMIB_xFw  
  
	3-2. postman 으로 실행  
		Get : http://localhost:9999/test/admin  
		Headers  
			key : Authorization  
			value : bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJPdGViQldzSmdhRWozeXVaMGZlbTVWclFmbkZpcDlLczE5aVN6anBybGw0In0.eyJleHAiOjE2NDQ0MjkxMjQsImlhdCI6MTY0NDM5MzEyNCwianRpIjoiZTE5MjA0YjgtZGFjMi00ZTlhLTkwNjgtMjU1MTRhZTNiZmY5IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL2RlbW8iLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNzNkNWYwOWUtZTY2Ny00YjA2LTgwZDctMTk3ZDM1NzQyNmQ0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibXlfY2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6IjgzNjI3NmM1LTAxMDgtNDUxZS05OTdiLWNkMjcyMjRjYTJiMiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDo4MDgwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIiwiZGVmYXVsdC1yb2xlcy1kZW1vIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsibXlfY2xpZW50Ijp7InJvbGVzIjpbIlJPTEVfVVNFUiJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJwcm9maWxlIGVtYWlsIiwic2lkIjoiODM2Mjc2YzUtMDEwOC00NTFlLTk5N2ItY2QyNzIyNGNhMmIyIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoia2ltIHN1bmdjaHVsIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic3VuZ2NodWwiLCJnaXZlbl9uYW1lIjoia2ltIiwiZmFtaWx5X25hbWUiOiJzdW5nY2h1bCIsImVtYWlsIjoia2ltc2MxMjE4QGdtYWlsLmNvbSJ9.jx6pdr87_wjURnbcq9fAqmwB7k0lq3nODwBieTqtkk6QVoSCU5yXqlKaajFSUShb_jh0jq3yVL5NVmqiRaqLmHb_Y55wrs4dCUbbjKdJXTBLP7W4xSOEwlm81PtZYfoCMcU5pmKAkbEUllDJxjSsbkM2SPkWl9Y7DMTT1SgTlBMHsxabwLI_O-6rUzkEVyL2v7ALX1MqTAsuyLVlF8ckgEIWzFHh1f325oJFlnStoAvw_bcTa5z1rIUgDN7quPLGwsnj6Y1M-5Ezfm7I932L4nWYQIbWvJRtpVkD7x8eOhDtyfmE_UG80LhiYyqbgJwWxzgeM9Q_jUmG3DGMIB_xFw  
  
		- 실패 권한이 없음  
  
		{  
			"timestamp": "2022-02-09T08:07:04.421+00:00",  
			"status": 403,  
			"error": "Forbidden",  
			"message": "Forbidden",  
			"path": "/test/admin"  
		}  
  
	3-3. sungchul 계정이 아닌 admin 계정으로 실행  
		curl -X POST "http://localhost:8080/auth/realms/demo/protocol/openid-connect/token" ^  
		--header "Content-Type:application/x-www-form-urlencoded" ^  
		--data-urlencode "grant_type=password" ^  
		--data-urlencode "client_id=my_client" ^  
		--data-urlencode "client_secret=XafEZWyEQDgd0rmn86rO4H7K674l5zM9" ^  
		--data-urlencode "username=admin" ^  
		--data-urlencode "password=admin"  
  
		액세스 토큰 : eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJPdGViQldzSmdhRWozeXVaMGZlbTVWclFmbkZpcDlLczE5aVN6anBybGw0In0.eyJleHAiOjE2NDQ0MzAxMTMsImlhdCI6MTY0NDM5NDExMywianRpIjoiNjAxMTIyYWQtOTBmMi00ODcxLThkZTYtYWMxMjY1YmIyNTlmIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL2RlbW8iLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiZDNhY2E5NDktODk1My00OGM5LTgxMDgtNzBhNTYxMjVmZjJkIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibXlfY2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6IjMyYzFmMTQ3LTIyMTgtNGU1Ni1iNWVlLWVkZjg4NGVkZGQyYiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDo4MDgwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIiwiZGVmYXVsdC1yb2xlcy1kZW1vIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsibXlfY2xpZW50Ijp7InJvbGVzIjpbIlJPTEVfVVNFUiIsIlJPTEVfQURNSU4iXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsInNpZCI6IjMyYzFmMTQ3LTIyMTgtNGU1Ni1iNWVlLWVkZjg4NGVkZGQyYiIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW4ifQ.XnyBmkXtVUjaRUaOd4xRZXwMXS2iPHOzTnCefF7qJoDZ595wMgZ3ae4ZTcEl6OFau0_qcSHoiSwoDNklvflURUE1aZ0voJImLPkXYbTkjYnepjlYVmve5PTHwclpDBvRHQhNsbn-yV9wLpA9uqlamKgu3PlYK8iRhSpLYjBvTTEIxCm1a4IKqRJIp4Z9Xg7k6YTqqt-I0d39BpUQ8Y8vdcaVwcHxkFmPYU6-TuRm8qolumnKR2k4znCvn145cucKyPc5dH2ExO4o2Rc0AL2ttS9O7lQeMJwpL330h04CDlIQAOTYgWoQWj6lFEG1fnXh9eaUmpdndYhrxF2XlCguYA  
  
	3-4. postman 으로 실행  
		Get : http://localhost:9999/test/admin  
		Headers  
			key : Authorization  
			value : bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJPdGViQldzSmdhRWozeXVaMGZlbTVWclFmbkZpcDlLczE5aVN6anBybGw0In0.eyJleHAiOjE2NDQ0MzAxMTMsImlhdCI6MTY0NDM5NDExMywianRpIjoiNjAxMTIyYWQtOTBmMi00ODcxLThkZTYtYWMxMjY1YmIyNTlmIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL2RlbW8iLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiZDNhY2E5NDktODk1My00OGM5LTgxMDgtNzBhNTYxMjVmZjJkIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibXlfY2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6IjMyYzFmMTQ3LTIyMTgtNGU1Ni1iNWVlLWVkZjg4NGVkZGQyYiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDo4MDgwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIiwiZGVmYXVsdC1yb2xlcy1kZW1vIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsibXlfY2xpZW50Ijp7InJvbGVzIjpbIlJPTEVfVVNFUiIsIlJPTEVfQURNSU4iXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsInNpZCI6IjMyYzFmMTQ3LTIyMTgtNGU1Ni1iNWVlLWVkZjg4NGVkZGQyYiIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW4ifQ.XnyBmkXtVUjaRUaOd4xRZXwMXS2iPHOzTnCefF7qJoDZ595wMgZ3ae4ZTcEl6OFau0_qcSHoiSwoDNklvflURUE1aZ0voJImLPkXYbTkjYnepjlYVmve5PTHwclpDBvRHQhNsbn-yV9wLpA9uqlamKgu3PlYK8iRhSpLYjBvTTEIxCm1a4IKqRJIp4Z9Xg7k6YTqqt-I0d39BpUQ8Y8vdcaVwcHxkFmPYU6-TuRm8qolumnKR2k4znCvn145cucKyPc5dH2ExO4o2Rc0AL2ttS9O7lQeMJwpL330h04CDlIQAOTYgWoQWj6lFEG1fnXh9eaUmpdndYhrxF2XlCguYA  
  
		- 성공  
  
4. curl -X GET "http://localhost:9999/test/user"  
	-성공  
		3번 항목에서 발급받은 토큰을 사용하여 테스트  

토큰 요청

curl -X POST “http://localhost:8080/auth/realms/demo/protocol/openid-connect/token” ^
–header “Content-Type:application/x-www-form-urlencoded” ^
–data-urlencode “grant_type=password” ^
–data-urlencode “client_id=my_client” ^
–data-urlencode “client_secret=JBFLaz1mgZKPwYNqE9Tfyf0c3b2mnkOl” ^
–data-urlencode “username=sungchul” ^
–data-urlencode “password=admin”