정구리의 우주정복

[Keycloak] Springboot 와 keycloak 연결하기 (keycloak 24.0.3, spring 3, java 21) keycloak spring boot starter deprecated, csrf deprecated 해결 본문

JAVA/PROJECT

[Keycloak] Springboot 와 keycloak 연결하기 (keycloak 24.0.3, spring 3, java 21) keycloak spring boot starter deprecated, csrf deprecated 해결

Jungry_ 2024. 5. 14. 12:12
반응형

저번에 띄운 keyclaok 과 나의 spring 프로젝트 녀석을 연동하려 해본다

 

기록용이라 엉망진창일수도 있음 .. ㅜㅜ

 

https://keycloak.org/docs/latest/securing_apps/#_spring_boot_adapter

 

Securing Applications and Services Guide

In order for an application or service to utilize Keycloak it has to register a client in Keycloak. An admin can do this through the admin console (or admin REST endpoints), but clients can also register themselves through the Keycloak client registration

www.keycloak.org

 

이거 보고 따라하려고 함 ! 되면 좋고 안되면 망한거지 뭐 ..

 

 

이라고 하자마자

 

This adapter is deprecated and will be removed in a future release of Keycloak. No further enhancements or new features will be added to this adapter.We recommend that you leverage the OAuth2/OpenID Connect support from Spring Security.For more details about how to integrate Keycloak with Spring Boot applications, consider looking at the Keycloak Quickstart GitHub Repository.

 

deprecate 되니까 쓰지 말라고 한다 .. 대신 Spring security 의 OAuth2/OpenId 녀석을 쓰라는데 벌써부터 눈앞이 깜깜

 

https://developers.redhat.com/articles/2023/07/24/how-integrate-spring-boot-3-spring-security-and-keycloak#

 

How to integrate Spring Boot 3, Spring Security, and Keycloak | Red Hat Developer

Learn how to create a sample Java application on top of Spring Boot 3 and protect it by using Spring Security and Keycloak.

developers.redhat.com

도와줘요 외국아저씨

 

 

우선 저번에 설치해둔 keycloak 에 로그인을 하고 

 

 

realm 하나 생성해주자

 

 

이름은 멋있게 JungryRealm 으로 지어줌 => 소문자로 수정했음 jungryrealm 이렇게

 

클라이언트도 생성해주자

 

 

 

 

 

 

 

 

일단 이렇게 해줬다 ... 언제든 수정 되니까 일단 이렇게 가본다

 

 

 

죄송 client authentication 을 on 으로 바꿔야한다 그래야지 credential 탭이 생김 

 

 

client secret 녀석 복사해두고 유저를 만들러 가자 !!!!

 

 

 

비밀번호도 설치해주자 (Temporary 는 끄도록 !!! 켜놓으면 나중에 비밀번호 바꿔야지 유저 사용가능해서 귀찮아져요 ..)

 

 

여기까지 하면 keycloak 세팅은 끝 !

 

 

postman 에서 로그인 잘 되는지 확인도 해보자 ! access_token 이 나오면 정상적으로 로그인이 되는것이다

 

https://jwt.io/

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

 

여기 들어가서 해당 access token에 어떤 내용이 들어가있는지 확인해보는것도 재밌당

 

 

이제 spring boot 세팅으로 가보자 

 

참고로 나는 spring 3 에 java 21 사용했다

 

build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.5'
    id 'io.spring.dependency-management' version '1.1.4'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
    sourceCompatibility = '21'
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'org.postgresql:postgresql'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security
    implementation 'org.springframework.boot:spring-boot-starter-security'
    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-oauth2-resource-server
    implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'


}

tasks.named('test') {
    useJUnitPlatform()
}

 

test 를 위한 demo controller 를 만들어준다 (이후 role test 를 위해 두개를 만든거고 실제론 hello() 만 있어도 문제없음)

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/v1/demo")
public class DemoController {

    @GetMapping
    public String hello() {
        return "Hello from Spring boot & Keycloak";
    }

    @GetMapping("/hello-2")
    public String hello2() {
        return "Hello from Spring boot & Keycloak - ADMIN";
    }
}

 

 

이후 spring security 설정을 해준다

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests((authorization) -> authorization.anyRequest().authenticated());

        http
                .oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));

        http
                .sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));

        return http.build();
    }
}

 

여기서 기존과 차이점이 있는데 

 

기존엔

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf()
                    .disable()
                .authorizeHttpRequests()
                    .anyRequest()
                        .authenticated();

        http
                .oauth2ResourceServer()
                    .jwt();

        http
                .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

 

이런식으로 체이닝을 해서 사용했다면 현재는 모두

deprecated 가 되어버렸기 때문에 위와 같이 함수형을 사용하는 방식으로 바꿔서 사용해주었다

가독성이 왕 좋아져서 개인적으로는 마음에 든다 !

 

application.yaml (application.properties)

spring:
  application:
    name: toygry
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://keycloak주소/realms/realm주소
          jwk-set-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/protocol/openid-connect/certs

server:
  port: 8081

 

이렇게 작성해주면 된다

 

이후 서버를 실행해주고 login 할때 받은 access token 을 넣고 api 를 실행해주면

 

정상적으로 200이 나오는걸 볼 수 있다 

 

 

인증을 하지 않으면 401 이 나온다 !!

이렇게 keycloak 에서 발급받은 token 을 사용해서 spring boot 와 연결해 api 를 실행할 때 keycloak 토큰이 유효한지 확인 후 실행하도록 만들어보았다 ! 야호

반응형
Comments