Form-Based Authentication হলো স্প্রিং সিকিউরিটির একটি ডিফল্ট অথেন্টিকেশন পদ্ধতি যা ব্যবহারকারীর লগইন তথ্য (ইউজারনেম এবং পাসওয়ার্ড) যাচাই করার জন্য একটি ফর্ম ভিত্তিক লগইন পেজ সরবরাহ করে। এটি সাধারণত ওয়েব অ্যাপ্লিকেশনের জন্য ব্যবহৃত হয়।
HttpSession
-এ সংরক্ষণ করা হয়।/login
এ ফর্ম ডেটা সাবমিট হয়।Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Gradle:
implementation 'org.springframework.boot:spring-boot-starter-security'
নিম্নলিখিত উদাহরণে ডিফল্ট লগইন ফর্ম সক্রিয় করা হয়েছে:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll() // Public URLs
.anyRequest().authenticated() // All other URLs require login
.and()
.formLogin() // Enable default form-based login
.and()
.logout(); // Enable logout functionality
}
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("password")).roles("USER")
.and()
.withUser("admin").password(passwordEncoder().encode("admin")).roles("ADMIN");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // Password encoding mechanism
}
স্প্রিং সিকিউরিটির ডিফল্ট লগইন ফর্মের পরিবর্তে কাস্টম পেজ ব্যবহার করতে চাইলে, formLogin().loginPage()
কনফিগার করা হয়।
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login", "/public/**").permitAll() // Allow login page access
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login") // Custom login page URL
.defaultSuccessUrl("/home", true) // Redirect after successful login
.failureUrl("/login?error=true") // Redirect if login fails
.permitAll()
.and()
.logout()
.logoutUrl("/logout") // Logout URL
.logoutSuccessUrl("/login?logout=true")
.permitAll();
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form method="post" action="/login">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username">
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password">
</div>
<button type="submit">Login</button>
</form>
<div>
<p th:if="${param.error}">Invalid username or password</p>
<p th:if="${param.logout}">You have been logged out</p>
</div>
</body>
</html>
.formLogin()
.loginPage("/login") // Custom login page
.defaultSuccessUrl("/dashboard") // Redirect URL after successful login
.failureUrl("/login?error=true") // Redirect URL after login failure
লগইন করার পর একটি নতুন সেশন তৈরি করতে:
.httpBasic()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
নিজস্ব অথেন্টিকেশন লজিক যোগ করতে:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(new CustomAuthenticationProvider());
}
Spring Security-এর Form-Based Authentication ব্যবহার করা সহজ এবং এটি কাস্টমাইজ করার জন্য ব্যাপক সুযোগ দেয়। ডিফল্ট লগইন ফর্ম ব্যবহার করা গেলেও, প্রায় সব অ্যাপ্লিকেশনই কাস্টম লগইন ফর্ম ব্যবহার করে। Spring Security আপনার অ্যাপ্লিকেশনের নিরাপত্তা বাড়াতে এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে সহায়ক।
Form-Based Authentication হল Spring Security-তে একটি অথেন্টিকেশন পদ্ধতি যেখানে ব্যবহারকারী তাদের পরিচয় (ইউজারনেম এবং পাসওয়ার্ড) একটি কাস্টম HTML ফর্মের মাধ্যমে প্রদান করে। এটি ডিফল্ট HTTP Basic Authentication-এর চেয়ে বেশি ব্যবহারকারী-বান্ধব এবং নিরাপত্তা এবং কাস্টমাইজেশনের সুযোগ প্রদান করে।
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Spring Security-তে Form-Based Authentication সেটআপ করার জন্য SecurityFilterChain
ব্যবহার করা হয়।
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login", "/resources/**").permitAll() // Public URLs
.anyRequest().authenticated() // Other URLs require authentication
)
.formLogin(form -> form
.loginPage("/login") // Custom login page URL
.defaultSuccessUrl("/home", true) // Redirect after successful login
.failureUrl("/login?error=true") // Redirect on login failure
.permitAll()
)
.logout(logout -> logout
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout=true")
.permitAll()
);
return http.build();
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
public class InMemoryUserConfig {
@Bean
public InMemoryUserDetailsManager userDetailsManager() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
UserDetails admin = User.withDefaultPasswordEncoder()
.username("admin")
.password("admin")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
src/main/resources/templates/login.html
ফাইল তৈরি করুন।
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form th:action="@{/login}" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username" />
<br />
<label for="password">Password:</label>
<input type="password" id="password" name="password" />
<br />
<button type="submit">Login</button>
</form>
<p th:if="${param.error}" style="color: red;">Invalid username or password.</p>
<p th:if="${param.logout}" style="color: green;">You have been logged out.</p>
</body>
</html>
src/main/resources/templates/home.html
ফাইল তৈরি করুন।
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Home</title>
</head>
<body>
<h1>Welcome to Home Page</h1>
<p>You are successfully logged in!</p>
<a th:href="@{/logout}">Logout</a>
</body>
</html>
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class AppController {
@GetMapping("/login")
public String loginPage() {
return "login";
}
@GetMapping("/home")
public String homePage() {
return "home";
}
}
অ্যাপ্লিকেশনটি চালু করুন:
mvn spring-boot:run
http://localhost:8080/login
URL-এ যান।user
password
Spring Security-তে Form-Based Authentication একটি ব্যবহারকারী-বান্ধব অথেন্টিকেশন পদ্ধতি। এটি ব্যবহারকারীদের সহজেই অথেন্টিকেশন প্রদান করে এবং ওয়েব অ্যাপ্লিকেশনে উচ্চ সুরক্ষা নিশ্চিত করে।
স্প্রিং সিকিউরিটির ডিফল্ট লগইন এবং লগআউট পেজ খুবই সাধারণ। প্রায়ই এই পেজগুলোকে কাস্টমাইজ করে অ্যাপ্লিকেশনের প্রয়োজন অনুযায়ী ডিজাইন করা হয়। নিচে কাস্টম লগইন এবং লগআউট পেজ কনফিগার করার জন্য ধাপে ধাপে নির্দেশনা দেওয়া হলো।
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login", "/logout", "/css/**", "/js/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/login") // Custom Login Page URL
.loginProcessingUrl("/perform_login") // Form Action URL
.defaultSuccessUrl("/home", true) // Redirect After Login
.failureUrl("/login?error=true") // Redirect on Login Failure
.permitAll()
)
.logout(logout -> logout
.logoutUrl("/perform_logout") // Custom Logout URL
.logoutSuccessUrl("/login?logout=true") // Redirect After Logout
.deleteCookies("JSESSIONID") // Invalidate Session
.permitAll()
);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // Password Encryption
}
}
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class LoginController {
@GetMapping("/login")
public String login() {
return "login";
}
@GetMapping("/home")
public String home() {
return "home";
}
}
login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login</title>
</head>
<body>
<h2>Login</h2>
<form th:action="@{/perform_login}" method="post">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
</div>
<div>
<button type="submit">Login</button>
</div>
<div>
<p th:if="${param.error}" style="color: red;">Invalid username or password</p>
<p th:if="${param.logout}" style="color: green;">You have been logged out successfully</p>
</div>
</form>
</body>
</html>
logout.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Logout</title>
</head>
<body>
<h2>You have been logged out successfully.</h2>
<a th:href="@{/login}">Go to Login Page</a>
</body>
</html>
home.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Home</title>
</head>
<body>
<h2>Welcome to the Home Page</h2>
<a th:href="@{/perform_logout}">Logout</a>
</body>
</html>
/home
পেজে রিডাইরেক্ট করবে।/login?logout=true
পেজে নিয়ে যাবে।কাস্টম লগইন এবং লগআউট পেজ কনফিগার করা স্প্রিং সিকিউরিটির একটি গুরুত্বপূর্ণ বৈশিষ্ট্য। এটি ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে এবং অ্যাপ্লিকেশনকে আরও সুরক্ষিত করতে সাহায্য করে।
Spring Security-র Remember-Me ফিচার ব্যবহারকারীদের দীর্ঘ সময় ধরে লগইন অবস্থায় রাখতে সাহায্য করে, এমনকি ব্রাউজার বন্ধ হওয়ার পরেও। এটি সাধারণত একটি কুকি ব্যবহার করে কাজ করে, যা ব্যবহারকারীর তথ্য সংরক্ষণ করে।
pom.xml
ফাইলে Spring Security ডিপেন্ডেন্সি যোগ করুন:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
একটি Java কনফিগারেশন ক্লাস তৈরি করুন যেখানে Remember-Me কনফিগার করা হবে।
package com.example.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated() // All requests require authentication
.and()
.formLogin() // Enable form-based login
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.rememberMe() // Enable Remember-Me feature
.key("uniqueAndSecret") // Unique key for hashing
.tokenValiditySeconds(1209600); // 14 days (in seconds)
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // Password hashing
}
}
একটি কাস্টম লগইন পৃষ্ঠা যোগ করুন:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class LoginController {
@GetMapping("/login")
public String login() {
return "login";
}
}
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
<form action="/login" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username"><br>
<label for="password">Password:</label>
<input type="password" id="password" name="password"><br>
<label>
<input type="checkbox" name="remember-me"> Remember Me
</label><br>
<button type="submit">Login</button>
</form>
</body>
</html>
Remember-Me ফিচার আরও সুরক্ষিত করতে ডাটাবেসে টোকেন সংরক্ষণ করুন:
Token Table তৈরি করুন: Spring Security টোকেন সংরক্ষণের জন্য একটি টেবিল তৈরি করবে।
CREATE TABLE persistent_logins (
username VARCHAR(64) NOT NULL,
series VARCHAR(64) NOT NULL,
token VARCHAR(64) NOT NULL,
last_used TIMESTAMP NOT NULL,
PRIMARY KEY (series)
);
PersistentTokenRepository কনফিগার করুন:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import javax.sql.DataSource;
@Configuration
public class RememberMeTokenConfig {
@Bean
public PersistentTokenRepository persistentTokenRepository(DataSource dataSource) {
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
return tokenRepository;
}
}
Update Security Configuration:
http
.rememberMe()
.tokenRepository(persistentTokenRepository(dataSource))
.tokenValiditySeconds(1209600) // 14 days
.key("uniqueAndSecret");
.tokenValiditySeconds(604800)
→ 7 দিন (সেকেন্ডে)।.rememberMeCookieName("my-remember-me-cookie")
.key("myUniqueKey")
→ কুকির নিরাপত্তা উন্নত করতে।.key()
এর মান গোপন এবং অনন্য রাখুন।Spring Security-র Remember-Me ফিচার ব্যবহারকারীর অভিজ্ঞতা উন্নত করে এবং দীর্ঘ সময় ধরে সেশন মেইনটেইন করতে সাহায্য করে। সঠিক কনফিগারেশনের মাধ্যমে এটি নিরাপদ এবং কার্যকর করা সম্ভব।
Form-Based Authentication হলো Spring Security-তে একটি জনপ্রিয় Authentication প্রক্রিয়া, যেখানে ব্যবহারকারী একটি কাস্টম লগইন ফর্ম ব্যবহার করে অ্যাপ্লিকেশনে লগইন করতে পারে। এটি REST API এবং Web Applications উভয়ের জন্য প্রযোজ্য।
<dependencies>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Thymeleaf (ফর্ম টেম্পলেটের জন্য) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
@EnableWebSecurity
ব্যবহার করে কাস্টম কনফিগারেশন তৈরি করুন।
SecurityConfig
ক্লাস:import org.springframework.context.annotation.Configuration;
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.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login", "/resources/**", "/css/**").permitAll() // Login পেজ এবং স্ট্যাটিক ফাইল ফ্রি
.anyRequest().authenticated() // অন্য সব রিকোয়েস্ট প্রোটেক্টেড
.and()
.formLogin()
.loginPage("/login") // Custom login পেজ
.defaultSuccessUrl("/home", true) // লগইন সফল হলে
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout")
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("{noop}password") // No password encoding (development only)
.roles("USER")
.and()
.withUser("admin")
.password("{noop}admin")
.roles("ADMIN");
}
}
Spring Boot ডিফল্ট লগইন ফর্ম ব্যবহার না করে কাস্টম লগইন পেজ ব্যবহার করা হবে।
login.html
(Thymeleaf Template):<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login</title>
</head>
<body>
<h1>Login Page</h1>
<form th:action="@{/login}" method="post">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
</div>
<div>
<button type="submit">Login</button>
</div>
</form>
<p th:if="${param.error}">Invalid username or password</p>
<p th:if="${param.logout}">You have been logged out</p>
</body>
</html>
লগইন সফল হলে ব্যবহারকারীকে /home
রিডাইরেক্ট করা হবে।
home.html
(Thymeleaf Template):<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Home</title>
</head>
<body>
<h1>Welcome to Home Page!</h1>
<p>You are successfully logged in.</p>
<form th:action="@{/logout}" method="post">
<button type="submit">Logout</button>
</form>
</body>
</html>
Spring MVC কন্ট্রোলার ব্যবহার করে /login
এবং /home
পেজ পরিচালনা করা হবে।
LoginController
:import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class LoginController {
@GetMapping("/login")
public String login() {
return "login"; // login.html টেম্পলেট রিটার্ন করবে
}
@GetMapping("/home")
public String home() {
return "home"; // home.html টেম্পলেট রিটার্ন করবে
}
}
style.css
:body {
font-family: Arial, sans-serif;
margin: 20px;
}
form {
margin-top: 20px;
}
button {
background-color: #4CAF50;
color: white;
padding: 10px 20px;
border: none;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
ফাইলটি src/main/resources/static/css/style.css
এ রাখুন।
অ্যাপ চালু করুন:
mvn spring-boot:run
http://localhost:8080/login
user
password
/login
রিকোয়েস্ট করলে কাস্টম লগইন পেজ দেখা যাবে।/home
এ রিডাইরেক্ট হবে।/logout
রিকোয়েস্ট করলে /login?logout
পেজে রিডাইরেক্ট হবে।এই উদাহরণটি একটি মৌলিক Spring Security প্রজেক্টের কাস্টম Form-Based Authentication কনফিগারেশন প্রদর্শন করে। এটি Spring Security-এর আরও উন্নত বৈশিষ্ট্য যেমন ডাটাবেস-ভিত্তিক Authentication, OAuth2 Integration, এবং JWT এর মতো ফিচার শেখার জন্য একটি ভিত্তি হিসেবে কাজ করবে।
Read more