Bu yazıda, keycloak kullanarak bir spring-boot 2 uygulamasının nasıl güvence altına alınacağını göreceğiz.Kütüphane olarak keycloak-spring-boot-2-adapter` (sürüm: 7.0.0) ‘i kullanacağım.Şu an itibariyle, bu adapterin devam eden birkaç sorunu var.Spring Boot 2 ile düzgün çalışmasını sağlamak için bazı geçici çözüm yapılandırma gerektirir.

Entegrasyon modelinde, spring context, uygulamanız için request mapping akışını yönetir, yani MVC flow.Keycloak adapter, sunucu tarafında session id oluşturur ve kimlik doğrulama işlemi tamamlandıktan sonra client tarayıcısı tarafında cookkie şeklinde gönderilir.Kullanıcılar kaynaklara erişebilir.Bu entegrasyon türü, keycloak sunsunucu tarafı entegrasyonu olarak bilinir.

Keycloakta Client Yapılandırması

Client yapılandırması için öncelikle Keycloak tarafında keycloak-demo isminde bir realm oluşturun.Daha sonra Clients kısmından spring-boot-mvc-app isminde bir client oluşturun.

Oluşturduğumuz cliente valid redirect uri olarak http://localhost:8081/* ekleyelim.

Son olarak User kısmından kullanıcı adı test ve şifresi test olan bir kullanıcı ekleyelim.Şifre verirken Temporary seçeneğini kapatmayı unutmayın.

Spring Boot Keycloak Örneği

Spring Boot Projesi Oluşturma

Spring initalizr ile projenizi oluşturaruken aşağıdaki seçenekleri seçin.

Web

Security

Keyclokun spring boot adapterini pom.xml dosyamıza ekleyelim.

<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-2-adapter</artifactId>
<version>7.0.0</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-tomcat7-adapter-dist</artifactId>
<version>7.0.0</version>
<type>pom</type>
</dependency>

Şimdi application.properties dosyasında keycloak yapılandırmasını yapalım.

keycloak.realm = keycloak-demo
keycloak.auth-server-url = http://127.0.0.1:8080/auth
keycloak.resource = spring-boot-mvc-app
keycloak.principal-attribute=preferred_username
keycloak.public-client=true
spring.main.allow-bean-definition-overriding=true
server.port=8081

Local keycloak sunucusu: 8080 portunda çalışıyor,o yüzden uygulamayı 8081‘de çalıştırıyorum.

Keycloak spring adapteri ile ilgili bir sorun:

Keycloak spring boot adapteri ilgili şu anki sorunlar nedeniyle bazı geçici çözüm kodları eklenmesi gerekiyor.Keycloak config özelliklerini keycloak.json’dan değil, spring default özelliklerinden okumak için.CustomKeycloakSpringBootResolver sınıfını ekleyelim.Bunun için security isminde bir paket oluşturunve bu paketin içersinde bu sınıfı tanımlayın.

@Configuration
public class CustomKeycloakSpringBootConfigResolver extends KeycloakSpringBootConfigResolver { private final KeycloakDeployment keycloakDeployment; public CustomKeycloakSpringBootConfigResolver(KeycloakSpringBootProperties properties) { keycloakDeployment = KeycloakDeploymentBuilder.build(properties); } @Override public KeycloakDeployment resolve(HttpFacade.Request facade) { return keycloakDeployment; }
}

Güvenlik Yapılandırması

Güvenlik yapılandırması için KeycloakConfigResolver beanı ve güvenlik yapılandırması için SecurityConfig sınıfını.tanımlayın.Security adlı sınıfın içerisinde bu sınıfı tanımlayın

@KeycloakConfiguration
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { /** * Registers the KeycloakAuthenticationProvider with the authentication manager. */ @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider(); auth.authenticationProvider(keycloakAuthenticationProvider); } /** * Provide a session authentication strategy bean which should be of type * RegisterSessionAuthenticationStrategy for public or confidential applications * and NullAuthenticatedSessionStrategy for bearer-only applications. */ @Bean @Override protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); } /** * Use properties in application.properties instead of keycloak.json */ @Bean @Primary public KeycloakConfigResolver keycloakConfigResolver(KeycloakSpringBootProperties properties) { return new CustomKeycloakSpringBootConfigResolver(properties); } /** * Secure appropriate endpoints */ @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); http.authorizeRequests() .antMatchers("/**").authenticated() .anyRequest().authenticated(); }
}

Securitydeki 2 yapılandırma sınıfımızda hazır.Hemen şimdi TokenController sınıfını oluşturalım.Bunun için controllers adlı yeni bir paket oluşturalım ve bu paketin içerisinde bu sınıfı tanımlayalım.

@RestController
public class TokenController { @RequestMapping("/token") public String getToken(){ return JWTUtil.getJWTToken(); }
}

Şimdide kullanıcının tokenini alan JWTUtil sınıfını oluşturalım.Bu classda controllers paketi içersinde olacak.

public class JWTUtil { public static String getJWTToken() { KeycloakAuthenticationToken authentication = (KeycloakAuthenticationToken) SecurityContextHolder.getContext() .getAuthentication(); KeycloakPrincipal<KeycloakSecurityContext> keycloakPrincipal = (KeycloakPrincipal<KeycloakSecurityContext>) authentication .getPrincipal(); return keycloakPrincipal.getKeycloakSecurityContext().getTokenString(); }
}

JWTUtil: jwt tokeni Spring Security Context’ten almak için oluşturduğum bir sınıf.

Resource dizininde static isimli bir klasör oluşturalım.Bu klasör içerisine index.html dosyasını tanımlayalım

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Keycloak Secure App</title>
</head>
<body>
<h1>Secure Spring-Boot MVC with Keycloak</h1>
<a href="secured.html">Secured Page</a>
</body>
</html>

Son olarak da static klasörünün içersine secured.html dosyasını tanımlayalım.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Keycloak</title>
</head>
<body>
<h1>Protected Resource</h1>
<a href="token">Get Token</a>
</body>
</html>

Uygulamamızı Çalıştırma

Uygulamamızı çalıştıralım.Uygulamaya http://127.0.0.1:8081 urlsinden erişebilirsiniz.

index.html

Şimdi secured sayfaya erişmeyi deneyelim.Spring ,keycloak demo realmının varsayılan giriş sayfasına yönlendirilecek:

Kullanıcı adı kısmına test,şifre kısmınınada test girelim.

Artık güvenli sayfaya erişebiliriz.Keycloak_IDENTITY içindeki Keycloak auth session-id ve JWT token’ı içeren bir tanımlama bilgisine sahip olduğumuzu görebilirsiniz.Tarayıcı oturumunu kapattıktan sonra, kullanıcının bu sayfaya erişmesi için kimlik bilgilerini tekrar girmesi gerekecektir.

Şimdi token endpointimizi test edebiliriz.

Springin request mappingi nasıl ele aldığını ve kullanıcının oturumlarını nasıl yönettiğini gördük.Sunucu tarafı entegrasyonunu gördük, sunucu tarafında auth durumunu yönetiyoruz.Keycloak ile bütünleşmek için stateless bir pattern olarak bilinen bütünleşmek için daha iyi bir yaklaşım var.Keycloak Spring boot Adapterinin gelecek sürümünde,oluşturduğumuz ek yapılandırma sınıflarından bazıları gerekli olmayacak.

Projenin Github Linki : https://github.com/susimsek/spring-boot-2-keycloak

Slack Kanalımın Linki;

https://join.slack.com/t/javadevelopercorp58/shared_invite/enQtODM3NzU5NDMzMjA1LWQ1YjFlZGE5MTI0ZDNjZDdlNGE4ZDE4NmM0NTBiODJlMTJiYmZjMjJiZTY3NzI0MTc5ZjJhZmQxN2MyMTlmYjU

Daha fazla konu içeriği ve çeşitliliği istiyorsanız slack kanalımı takip edebilirsiniz.

Responses

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir