Çalışma methodu tamamıyla

Spring Boot REST Security ile aynıdır sadece custom form login ve giriş-çıkp yaparken yönlendireceğimiz endpointler önemlidir.

pom.xml


<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
 
<dependency>
  <groupId>org.thymeleaf.extras</groupId>
  <artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>


Birkaç login metodu var

  1. HTTP Basic Authentication
  2. Default Login Form; Bunu Spring Security default olarak sağlar.
  3. Custom Login Form; Bu bizim oluşturduğumuz login formudur.


Basic Configuration ve Custom Login Page'miz

AppSec.java


@Configuration
public class AppSec {
    
    @Bean
    public InMemoryUserDetailsManager userDetailsManager(){
        UserDetails userDetail = User
                .builder()
                .username("minter")
                .password("{noop}coder123")
                .roles("ADMIN")
                .build();
        return new InMemoryUserDetailsManager(userDetail);
    }
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
        http.authorizeHttpRequests(configurer -> 
                configurer.anyRequest().authenticated()
        ).formLogin(form -> 
                form.loginPage("/showMyLoginPage")
                .loginProcessingUrl("/authenticateTheUser")
                .permitAll()
        );
        return http.build();
    }
    
}


LoginController.java


@Controller
public class LoginController {
    @RequestMapping(method=RequestMethod.GET,path="/showMyLoginPage")
    public String showMyLoginPage(){
        return "plain-login";
    }
}


plain-login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>Login Page</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <form action="#" th:action="@{/authenticateTheUser}" method="post">
            <div th:if="${param.error}">Yanlış kullanıcı adı ve parola</div>
            Username <br> <input type="text" name="username" /><br/>
            Password<br/><input type="password" name="password" /><br/>
            <input type="submit" value="Giriş Yap" />
        </form>
    </body>
</html>



Spring Boot Logout

Bu süreçte tek yapmamız gereken logout'u filterChain methoduna eklemektir. Çıkış yaparken isteği post bir şekilde /logout urline atmak zorundayız.

AppSec.java'yı günceleyelim.


@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
    http.authorizeHttpRequests(configurer -> 
            configurer.anyRequest().authenticated()
    ).formLogin(form -> 
            form.loginPage("/showMyLoginPage")
            .loginProcessingUrl("/authenticateTheUser")
            .permitAll()
    ).logout(logout -> logout.permitAll());
    return http.build();
}


Controllerıda güncelle...

@RequestMapping(method=RequestMethod.GET,path="/")
public String index(){
    return "index";
}

Giriş yapıldıktan sonra;

index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        Giriş yapıldı
        <form action="#" th:action="@{/logout}" method="post">
            <input type="submit" value="Çıkış yap"/>
        </form>
    </body>
</html>


Eğer ki çıkış yaparsa otomatikman bizleri "login" sayfasına tekrardan yönlendirecektir ve çıkış başarılı oldu dememiz için de plain-login.html dosyasına şunu ekleyebiliriz.

<div th:if="${param.logout}">Çıkış başarılı</div>



Giriş yapan kullanıcın User ID ve Roles görüntüleme

Extra olarak bunun da pom.xml'ye ekli olması gereklidir...


<dependency>
  <groupId>org.thymeleaf.extras</groupId>
  <artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>


index.html'ye ekleme yapalım.

<span sec:authentication="principal.username"></span>
<span sec:authentication="principal.authorities"></span>


URL'leri kısıtlama

Spring Boot REST Security

burdakiyle her şey aynıdır.


Özel Access Denied Page

Eğer ki 403'lü bir yerlere gidilmek istenirse bunu da kısıtlayabiliriz.


AppSec.java 'yı güncelleyelim.


@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
    http.authorizeHttpRequests(configurer -> 
            configurer.anyRequest().authenticated()
    ).formLogin(form -> 
            form.loginPage("/showMyLoginPage")
            .loginProcessingUrl("/authenticateTheUser")
            .permitAll()
    ).logout(logout -> logout.permitAll()
    ).exceptionHandling(configurer -> configurer.accessDeniedPage("/access-denied"));
    return http.build();
}


Controllerımızı da güncelleyelim.


@RequestMapping(method=RequestMethod.GET,path="/access-denied")
public String accessDenied(){
    return "access-denied";
}


access-denied.html

<!DOCTYPE html>
<html>
    <head>
        <title>Access Denied</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <div>Giriş Yasak!</div>
    </body>
</html>


HTML İçerisindeki İçerikleri Role'lere Göre Görüntüleme

Eğer ki biz MANAGER rolüne sahip olanlara bir şey göstermek istersek ve ADMIN olanlara da farklı bir şey göstermek istersek şöyle yapabiliriz.


<div sec:authorize="hasRole('MANAGER')">Burası MANAGER Rolesine Sahip olanlarda gözükecek.</div>
<div sec:authorize="hasRole('ADMIN')">Burası ADMIN Rolesine Sahip olanlarda gözükecek.</div>
<div sec:authorize="hasRole('EMPLOYEE')">Burası EMPLOYEE Rolesine Sahip olanlarda gözükecek.</div>


JDBC Authentication

Spring Boot REST Security