3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Spring Cloud Gateway / KeyCloakを試してみた

Last updated at Posted at 2021-07-08

以下の記事の内容を試してみました。

試す内容

以下のフローの⑦だけスキップしてそれ以外を実装しました。
言語はkotlinで実装しております。

image.png

Keycloakの設定

DockerでKeycloakを起動

以下のコマンドで自動でDockerイメージがダウンロードされる

docker run -d --name keycloak -p 8888:8080 \
   -e KEYCLOAK_USER=spring \
   -e KEYCLOAK_PASSWORD=spring123 \
   jboss/keycloak

Clientの作成

以下のURLにアクセスする
http://localhost:8888/auth/admin/
Keycloak_Admin_Console.png
image.png

Client Secretを取得

Keycloak_Admin_Console.png

keycloak-without-test-scopeも同様に作成する。

Spring Bootのダウンロード

Spring InitializrからSpring Bootをダウンロードする
https://start.spring.io/
image.png

build.gradle.ktsの設定

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
	id("org.springframework.boot") version "2.5.2"
	id("io.spring.dependency-management") version "1.0.11.RELEASE"
	kotlin("jvm") version "1.5.20"
	kotlin("plugin.spring") version "1.5.20"
}

group = "phoneappli.people"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8

repositories {
	mavenCentral()
}

dependencyManagement {
	imports {
		mavenBom("org.springframework.cloud:spring-cloud-dependencies:2020.0.3")
	}
}

dependencies {
	implementation("org.jetbrains.kotlin:kotlin-reflect")
	implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
	implementation("org.springframework.cloud:spring-cloud-starter-gateway")
	implementation("org.springframework.boot:spring-boot-starter-web")
	implementation("org.springframework.boot:spring-boot-starter-security")
	implementation("org.springframework.security:spring-security-test")
	implementation("org.springframework.security:spring-security-oauth2-resource-server")
	implementation("org.springframework.security:spring-security-oauth2-jose")
	implementation("org.springframework.security:spring-security-oauth2-client")

	testImplementation("org.springframework.boot:spring-boot-starter-test")

}

tasks.withType<KotlinCompile> {
	kotlinOptions {
		freeCompilerArgs = listOf("-Xjsr305=strict")
		jvmTarget = "1.8"
	}
}

tasks.withType<Test> {
	useJUnitPlatform()
}

application.ymlの設定

server.port: 8090

spring:
  security:
    oauth2:
      client:
        provider:
          keycloak:
            token-uri: http://127.0.0.1:8888/auth/realms/master/protocol/openid-connect/token
            authorization-uri: http://127.0.0.1:8888/auth/realms/master/protocol/openid-connect/auth
            userinfo-uri: http://127.0.0.1:8888/auth/realms/master/protocol/openid-connect/userinfo
            user-name-attribute: preferred_username
        registration:
          keycloak-with-test-scope:
            provider: keycloak
            client-id: spring-with-test-scope
            client-secret: f7fab54d-b766-4fc3-b3a2-fbcaf826e816
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/login/oauth2/code/keycloak"
  application:
    name: callme
    security:
      oauth2:
        resourceserver:
          jwt:
            issuer-uri: http://127.0.0.1:8888/auth/realms/master
  cloud:
    gateway:
      default-filters: TokenRelay
      routes:
        - id: callme-service
          uri: http://127.0.0.1:5000 #callmeサービスのURL
          predicates:
            - Path=/callme/**
          filters:
            - RemoveRequestHeader=Cookie #callmeサービスへ転送する時にCookieを削除
  main:
    web-application-type: reactive
    allow-bean-definition-overriding: true

logging:
  level:
    org.springframework.security: DEBUG

Spring Securityの設定

import org.springframework.context.annotation.Configuration
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.config.annotation.web.configuration.WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
class SecurityConfig: WebSecurityConfigurerAdapter() {
    override fun configure(http: HttpSecurity) {
        http.authorizeHttpRequests {
            authorize -> authorize.anyRequest().authenticated()
        }.oauth2ResourceServer().jwt()
    }
}

動作確認

callmeサービスはPython Flaskで文字列を返すだけのサービスを実装。

ブラウザで以下のURLにアクセス。
http://127.0.0.1:8090/callme/ping
以下の画面に自動でリダイレクトする。
Please_sign_in.png

「keycloak-with-test-scope」「keycloak-without-test-scope」のどちらかを選択するとログイン画面が表示されるので、ログインする。
認証URLはこのようになっている。(http://127.0.0.1:8888/auth/realms/master/protocol/openid-connect/auth?response_type=code&client_id=spring-with-test-scope&state=AnB-Pc1Mi6Uv3caMM59g5Sfs6ASz7wu4oMPN6aXpsvM%3D&redirect_uri=http://127.0.0.1:8090/login/oauth2/code/keycloak)
Sign_in_to_Keycloak.png

認証に成功するとcallmeサービスが返した内容が表示される。
http://127.0.0.1:8090/callme/ping
127_0_0_1_8090_callme_ping.png

callmeサービスへ転送されたリクエストではcookieは削除されており、また以下の内容がheaderに付与されています。

Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJaSlZqWmlHUzgybmVETVlpVUZaRW1QQjBJM0ItOXJSTmhzQWJMWnhnbmtjIn0.eyJleHAiOjE2MjU3MjQ4NDgsImlhdCI6MTYyNTcyNDc4OCwiYXV0aF90aW1lIjoxNjI1NzIzODUxLCJqdGkiOiI5MTU3YWE4Zi0xZGQ1LTQxYTMtYmJkYi0wMTIxNTgwNmZlM2YiLCJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjg4ODgvYXV0aC9yZWFsbXMvbWFzdGVyIiwiYXVkIjpbIm1hc3Rlci1yZWFsbSIsImFjY291bnQiXSwic3ViIjoiY2M1MWIxNTQtMGQ2Mi00YjRhLWI5YWYtMWZkN2FjMmFmNDdhIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoic3ByaW5nLXdpdGgtdGVzdC1zY29wZSIsInNlc3Npb25fc3RhdGUiOiJjMGQxMWNmMi0wODllLTQzZWItYmYzMi1kNDVkYzM1N2EzNzQiLCJhY3IiOiIxIiwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImNyZWF0ZS1yZWFsbSIsImRlZmF1bHQtcm9sZXMtbWFzdGVyIiwiU0NPUEVfVEVTVCIsIm9mZmxpbmVfYWNjZXNzIiwiYWRtaW4iLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7Im1hc3Rlci1yZWFsbSI6eyJyb2xlcyI6WyJ2aWV3LWlkZW50aXR5LXByb3ZpZGVycyIsInZpZXctcmVhbG0iLCJtYW5hZ2UtaWRlbnRpdHktcHJvdmlkZXJzIiwiaW1wZXJzb25hdGlvbiIsImNyZWF0ZS1jbGllbnQiLCJtYW5hZ2UtdXNlcnMiLCJxdWVyeS1yZWFsbXMiLCJ2aWV3LWF1dGhvcml6YXRpb24iLCJxdWVyeS1jbGllbnRzIiwicXVlcnktdXNlcnMiLCJtYW5hZ2UtZXZlbnRzIiwibWFuYWdlLXJlYWxtIiwidmlldy1ldmVudHMiLCJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwibWFuYWdlLWF1dGhvcml6YXRpb24iLCJtYW5hZ2UtY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJlbWFpbCBURVNUIHByb2ZpbGUiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6InNwcmluZyJ9.CRKt9rGPsv-et1bWlLcVdgj46PSGRKSMmZmxzBusHxORjJK2OeyzSYRqFNlGWW_hZDtTp3zB4DU3VYnFSDo_zxAaBJnjA4efr3SnKhUKjdSa6Oiv95PVkU_xzStKKOeqC7VUB8WZpXWgh4GfcC7VFMnUhWJyjCUsE3kfUZA3z7WxuAhrU_9nz3elDIgtQt6Rj9CePk_a4HDfMrjhWLqYi1qjlnyWsMatHav44Iz0ygTpOQyd4k0awd-f7FEp916zfAxLOKFIo7tqsS8DEf46II_GBThTkTtmCNlOJoBHHTqL9VHaN1kWHUbm6BxTfoaqooLaIxTc7BIbkJPVp8Hhag

こちらはjwtになっており分解するとroleなどの情報が入っております。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?