korean IT student

Keycloak 17.0.1 Spring boot 연동 - 2 본문

Service/Keycloak

Keycloak 17.0.1 Spring boot 연동 - 2

현창이 2022. 4. 21. 14:43

앞서 keycloak설치 및 DB 연동을 마쳐서 keycloak 테스트 및 Spring boot 연동을 알아보자.

 

목차

1. keycloak realm, Clients, Users 생성 및 PostMan을 통한 Access Token With keycloakAPI 테스트

2. keycloak Spring Security 연동

 

1. keycloak realm, Clients, Users 생성 및 PostMan을 통한 Access Token With keycloakAPI 테스트

먼저 admin console을 통하여 realm, client, user를 생성해보자

 

 - Add realm을 이용하여 생성할 수 있다.

 

- Add Cient를 통해 client 생성

- client 생성 후 Settings 탭에 있는 위의 그림과 같이 세팅하였습니다.

- Access Type : client secret키로 접근하기 위해 confidental로 선택

- Service Accounts Enabled : spring boot에서 client id 및 client secret키로 접근하기 위해 on

- Valid Redirect URls : login or logout 성공 시 redirect 할 url 세팅, 저는 8090 포트를 사용하여 스프링 부트 진행

 

- Access Type의confidental로 선택 후 위와 같이 탭이 생기는데 Secret키는 서버 연동할 때 필요하다.

 

- Roles 탭에 있는 add Role 버튼을 이용하여 사용자 권한을 추가하였습니다.

 

- Users 메뉴에서 Add user를 통하여 사용자 생성 및 비밀번호 세팅을 하였습니다.

- Role Mappings 탭에서 생성한 Client의 Role의 user권한으로 세팅하였습니다.

http://localhost:5010/auth/realms/생성한 realm 이름/protocol/openid-connect/token


client_id: hello-client
client_secret: 클라이언트 시크릿 키 입력 
grant_type: password
username: 생성한 유저 이름
password: 생성한 유저 비밀번호

- 위의 이미지와 같이 입력 후 통신을 보내면 access_token, refresh_token, 토큰 시간 등 정보 값을 확인할 수 있다. 정상 작동함을 알 수 있다.

 

2. keycloak Spring Security 연동

이제 스프링 시큐리티 연동을 확인해보자.

    implementation 'org.springframework.boot:spring-boot-starter-security'
    // Keycloak
    implementation 'org.keycloak:keycloak-spring-boot-starter:17.0.1'
    implementation 'org.keycloak.bom:keycloak-adapter-bom:17.0.1'

- 먼저 build.gradle > dependencies에 키 클락을 사용하기 위해 위와 같이 추가합니다.

keycloak:
  enabled: true
  realm: 생성한 realm명
  auth-server-url: 인증서버 주소
  ssl-required: external // 기본값은 외부 요청에 HTTPS가 기본적으로 필요하다는 외부 의미 유효한 값은 'all', 'external', 'none' 
  resource: 생성한 client명
  credentials:
    secret: 클라이언트 시크릿 키
  use-resource-role-mappings: true
  bearer-only: true

- application.yml 파일에 keycloak 설정 정보들을 입력합니다.

@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");
  }

  @PreAuthorize("hasAnyRole('USER')")
  @RequestMapping(value = "/user", method = RequestMethod.GET)
  public ResponseEntity<String> user() {
    return ResponseEntity.ok("user 가능합니다.\n");
  }

  @PreAuthorize("hasAnyRole('ADMIN')")
  @RequestMapping(value = "/admin", method = RequestMethod.GET)
  public ResponseEntity<String> admin(@RequestHeader String Authorization) {
    log.debug(Authorization);
    return ResponseEntity.ok("admin 가능합니다.\n");
  }

}

- 권한 테스트를 위하여 Api 생성

- PreAuthorize를 통하여 권한 확인

@KeycloakConfiguration // @EnableWebSecurity 포함
@EnableGlobalMethodSecurity(jsr250Enabled = true, prePostEnabled = true)
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    super.configure(http);

    http
        .authorizeRequests()
        .antMatchers("/test/permitAll").permitAll()
        .anyRequest().authenticated();
    http.csrf().disable();
  }
  /*
   *  roles 앞에 ROLE_ 와 같이 접두사를 붙이지 않도록 도와준다.
   * */
  @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());
  }
}

- Spring Security에 의해 보호되는 모든 애플리케이션에 WebSecurityConfigurerAdapter를 확장하는 구성 클래스

- permitAll 제외하고 인증 요청

@Configuration
public class KeycloakConfiguration {


  /*
  *  keycloak.json 대신에 Spring Boot yml 파일을 이용하도록 돕는다.
  * */
  @Bean
  public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
    return new KeycloakSpringBootConfigResolver();
  }
}

위와 같이 테스트를 위하여 코드를 작성하였습니다.

이제 postman을 통하여 토큰 인증 테스트를 진행해보겠습니다.

 

위에 작성된 토큰 발급을 통하여 access_token을 발급받습니다.

(http://localhost:5010/auth/realms/생성한 realm 이름/protocol/openid-connect/token)

 

- Authorization : bearer {{access_token}} 위에서 발급한 값을 headers에 넣습니다. (default 5분 토큰 유효시간 > 테스트하다가 시간이 지나면 다시 발급받고 테스트 진행!! )

- authenticated를 접속하여 로그인하면 접속 가능한지 확인합니다.

 

- user로 접속하여 접속가능한지 확인합니다.

- admin에는 접속이 불가한지 확인합니다.

 

이상 스프링 시큐리티 연동 방법이었습니다.

다음 시간에는 스프링 부트에 admin-console을 연동하여 회원가입 및 로그인을 구현해보겠습니다. 

 

[참조]

https://www.baeldung.com/spring-boot-keycloak

Comments