Keycloak Kullanarak Güvenli Java Spring Boot REST API Uygulaması

1
1207
Keycloak Kullanarak Güvenli Java Spring Boot REST API Uygulaması
Keycloak Kullanarak Güvenli Java Spring Boot REST API Uygulaması

Herkese merhabalar, bu yazımızda Keycloak’u Docker üzerinde kurup, Spring Boot-Keycloak entegrasyonunu yapıp, oluşturduğumuz REST API üzerinde url isteği yaparak Keycloak login sayfasından giriş yapıp kullanıcı bilgilerine erişiyor olacağız. İlk olarak Keycloak Nedir diyerek başlayalım.

Keycloak Nedir?

Keycloak, açık kaynaklı bir kimlik ve erişim yönetimi çözümüdür. Daha fazla bilgi için keycloak web sitesini ziyaret edebilirsiniz.

Keycloak Docker kurulumu

Terminali açın ve aşağıdaki komutu çalıştırın.

docker run -p 8085:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin quay.io/keycloak/keycloak:15.0.2

Keycloak Konfigürasyonu

1- Keycloak admin paneline http://localhost:8085/ adresinden erişiniz. Administration console tıklayarak admin olarak giriş yapınız.

Keycloak Ayarları
Keycloak Ayarları

2- demo isminde yeni bir realm oluşturun.

Keycloak Ayarları
Keycloak Ayarları

 

3- Şimdiyse demo-app isminde yeni bir client oluşturacağız. Access type olarak public, Valid Redirect URI olarakta * veriniz. Ve ayarları kaydediniz.

Keycloak Ayarları
Keycloak Ayarları
Keycloak Ayarları
Keycloak Ayarları

4- Kullanıcı oluşturalım.

Keycloak Ayarları
Keycloak Ayarları
Keycloak Ayarları
Keycloak Ayarları

Keycloak ayarlarımızı tamamladık. Şimdiyse Spring Boot projesi kısmına geçelim.

Spring Boot Projesi Oluşturalım

1- IntelliJ IDEA üzerinden New Project diyerek açılan pencereden Spring Initializr tabını seçelim ve projemizi SpringBootKeycloak şeklinde isimlendirelim.

IntelliJ IDEA Spring Initializr Keycloak
IntelliJ IDEA Spring Initializr Keycloak

2- Spring Web ve Spring Security bağımlılıklarını projemize dahil edelim.

IntelliJ IDEA Spring Initializr Keycloak
IntelliJ IDEA Spring Initializr Keycloak

3- Pom.xml’e aşağıdaki kodları ekleyelim.

<dependencies>
    <dependency>
        <groupId>org.keycloak</groupId>
        <artifactId>keycloak-spring-boot-starter</artifactId>
        <version>15.0.2</version>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.keycloak.bom</groupId>
            <artifactId>keycloak-adapter-bom</artifactId>
            <version>15.0.2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Pom.xml’in son hali aşağıdaki gibi olmalıdır:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>SpringBootKeycloak</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringBootKeycloak</name>
    <description>SpringBootKeycloak</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-spring-boot-starter</artifactId>
            <version>15.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.keycloak.bom</groupId>
                <artifactId>keycloak-adapter-bom</artifactId>
                <version>15.0.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

 

5- Son olarak application.properties dosyasına aşağıdaki parametreleri ekleyelim.

keycloak.auth-server-url=http://localhost:8085/auth
keycloak.realm=demo
keycloak.resource=demo-app
keycloak.public-client=true

keycloak.auth-server-url -> Keycloak url adresi

keycloak.realm -> Oluşturduğumuz Realm adı

keycloak.resource -> Oluşturduğumuz client ID

keycloak.public-client -> Oluşturduğumuz client Public olduğu için bunu true olarak belirledik. Bu kısım client’ın access type alanına göre değiştirilebilir. Biz demo uygulama yaptığımız için şimdilik public.

6- GloabalSecurityConfiguration adında bir sınıf oluşturalım ve KeycloakWebSecurityConfigurerAdapter sınıfını extend edelim.

package com.example.springbootkeycloak;

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.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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;

@EnableWebSecurity
public class GloabalSecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }

    @Bean
    public KeycloakConfigResolver KeycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .anyRequest().authenticated();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakAuthenticationProvider);
    }
}

 

7- Son olarak REST endpointi tanımlayalım. hello adresine bir istek gittiğinde kullanıcı login sayfasına yönlenecek ve logout sayfasına gidildiğinde oluşturulan oturum silinecek ve tekrardan login sayfasına yönlenmiş olacak. getName() metodu ile kullanıcı giriş yaptıktan sonra ismini ekrana basmış olduk.

package com.example.springbootkeycloak;

import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.representations.AccessToken;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@RestController
public class HelloController {


    @GetMapping("/hello")
    public ResponseEntity<String> hello(Authentication authentication){

        if (authentication.getPrincipal() instanceof KeycloakPrincipal) {
            KeycloakPrincipal<KeycloakSecurityContext> kp = (KeycloakPrincipal<KeycloakSecurityContext>) authentication.getPrincipal();
            AccessToken token = kp.getKeycloakSecurityContext().getToken();
            final String body = "Hi,  " + token.getName();
            return ResponseEntity.ok(body);
        }
        return new ResponseEntity<>("Unauthorized", HttpStatus.UNAUTHORIZED);
    }

    @GetMapping(path = "/logout")
    public void logout(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException {
        request.logout();
        httpServletResponse.setHeader("Location", "/hello");
        httpServletResponse.setStatus(302);
    }
}

 

Tüm aşamaları tamamlamış olduk. Şimdiyse test edelim.

Uygulama Testi

Spring projemizi run edelim ve http://localhost:8080/hello/ adresine istek atalım. Karşımıza login sayfası gelecek. Oluşturduğumuz kullanıcı ile login olalım. Giriş yaptıktan sonra http://localhost:8080/logout adresine giderek çıkış yapabilirsiniz.

Keycloak Spring Boot Login
Keycloak Spring Boot Login
Keycloak Spring Boot Login
Keycloak Spring Boot Login
Postman üzerinden de test edebilirsiniz:

http://localhost:8085/auth/realms/demo/protocol/openid-connect/token adresine istek atarken body kısmından x-www-form-urlencoded seçerek client_id, grant_type, username, password alanları gönderiniz.

Keycloak Spring Boot Postman Test
Keycloak Spring Boot Postman Test

Üretilen access_token JWT token olarak üretilmiştir. https://jwt.io/ adresine bu access token’ı yapıştırarak token içerisindeki bilgilere erişebilirsiniz.

Keycloak Spring Boot JWT.IO Data Test
Keycloak Spring Boot JWT.IO Data Test

 

 

1 Yorum

CEVAP VER

Lütfen yorumunuzu giriniz!
Lütfen isminizi buraya giriniz