Ç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
- HTTP Basic Authentication
- Default Login Form; Bunu Spring Security default olarak sağlar.
- Custom Login Form; Bu bizim oluşturduğumuz login formudur.
Basic Configuration ve Custom Login Page'miz
@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();
}
}@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
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