ওয়েব অ্যাপ্লিকেশন ডেভেলপমেন্টে নিরাপত্তা একটি অপরিহার্য বিষয়। অনেক ডেভেলপারই শেষ মুহূর্তে নিরাপত্তা বাস্তবায়ন করতে গিয়ে জটিলতায় পড়েন, কিন্তু স্প্রিং সিকিউরিটি (Spring Security) এই কাজটিকে অত্যন্ত সহজ এবং কাঠামোবদ্ধ করে তোলে। এই টিউটোরিয়ালে আমরা স্প্রিং সিকিউরিটির মূল ধারণা, একটি Spring Boot অ্যাপ্লিকেশনে কীভাবে সহজ authentication এবং authorization কনফিগার করতে হয়, তা ধাপে ধাপে শিখব। আপনি ইন-মেমরি ইউজার, role-based access এবং REST API সুরক্ষিত করার পদ্ধতি সম্পর্কে একটি পরিষ্কার ধারণা পাবেন।
ভূমিকা (Background)
স্প্রিং সিকিউরিটি একটি শক্তিশালী এবং অত্যন্ত কাস্টমাইজযোগ্য ফ্রেমওয়ার্ক যা Java অ্যাপ্লিকেশনের জন্য authentication (প্রমাণীকরণ) এবং authorization (অনুমোদন) প্রদান করে। এটি মূলত একটি ফিল্টার চেইনের (Filter Chain) উপর ভিত্তি করে কাজ করে। প্রতিটি HTTP রিকোয়েস্ট অ্যাপ্লিকেশনে পৌঁছানোর আগে এই চেইনের বিভিন্ন ফিল্টারের মধ্য দিয়ে যায়, যা রিকোয়েস্টটি নিরাপদ কিনা তা নিশ্চিত করে।
মূল উপাদানগুলির মধ্যে রয়েছে SecurityContext, যা বর্তমান প্রমাণীকৃত ব্যবহারকারীর তথ্য ধারণ করে; Authentication অবজেক্ট, যা প্রমাণীকরণের প্রক্রিয়ার প্রতিনিধিত্ব করে; এবং GrantedAuthority, যা ব্যবহারকারীর অনুমতি (যেমন রোল) নির্ধারণ করে। এই ফ্রেমওয়ার্কটি HttpSecurity, WebSecurityConfigurerAdapter (স্প্রিং বুট ২.৭ পর্যন্ত) বা SecurityFilterChain (স্প্রিং বুট ৩.০+)-এর মাধ্যমে কনফিগার করা যায়।
- Authentication: ব্যবহারকারী কে তা যাচাই করা (যেমন: ইউজারনেম এবং পাসওয়ার্ড)।
- Authorization: একটি নির্দিষ্ট ব্যবহারকারী কী কী সম্পদ অ্যাক্সেস করতে পারে তা নিয়ন্ত্রণ করা।
- Principal: বর্তমানে লগইন করা ব্যবহারকারীকে বোঝায়।
- Role: অনুমতির একটি গ্রুপ, যেমন
ADMIN,USER।
পূর্বশর্ত (Prerequisites)
এই টিউটোরিয়ালটি অনুসরণ করার জন্য আপনার নিম্নলিখিত বিষয়গুলি সম্পর্কে প্রাথমিক ধারণা থাকা উচিত:
- Java: কমপক্ষে Java 17 বা তার উপরে ইনস্টল থাকতে হবে।
- Spring Boot: Spring Boot 3.x বা তার উপরে ব্যবহার করা হবে।
- Maven/Gradle: প্রজেক্ট বিল্ড এবং ডিপেন্ডেন্সি ম্যানেজমেন্টের জন্য Maven বা Gradle।
- IDE: IntelliJ IDEA, Eclipse, বা VS Code-এর মতো একটি উন্নত আইডিই।
- REST API:
@RestController,@GetMappingইত্যাদির প্রাথমিক জ্ঞান।
আপনার যদি Spring Boot শুরু করার টিউটোরিয়াল না দেখা থাকে, তবে আগে একটি সাধারণ "Hello World" Spring Boot অ্যাপ্লিকেশন তৈরি করে নেওয়া ভালো।
ধাপে ধাপে বাস্তবায়ন (Step-by-Step Implementation)
1. স্প্রিং বুট প্রজেক্ট তৈরি
প্রথমে Spring Initializr (start.spring.io) ব্যবহার করে একটি নতুন প্রজেক্ট তৈরি করুন। নিচের ডিপেন্ডেন্সিগুলি সিলেক্ট করুন:
Spring WebSpring Security
pom.xml ফাইলটি দেখতে এমন হবে:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
এটি আপনার প্রজেক্টে Spring MVC এবং Spring Security-এর মৌলিক সাপোর্ট যুক্ত করবে। spring-boot-starter-security অটোমেটিক্যালি সমস্ত HTTP এন্ডপয়েন্টকে সুরক্ষিত করে ফেলে এবং একটি ডিফল্ট লগইন পেজ সরবরাহ করে।
2. একটি সাধারণ REST কন্ট্রোলার তৈরি
নিরাপত্তা কনফিগার করার আগে, আসুন একটি সাধারণ কন্ট্রোলার তৈরি করি যা আমরা পরে সুরক্ষিত করব:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String sayHello() {
return "Hello, Welcome to the secured app!";
}
@GetMapping("/admin")
public String adminPage() {
return "Welcome to Admin page!";
}
}
এখানে /hello এবং /admin নামে দুটি এন্ডপয়েন্ট তৈরি করা হয়েছে। এখন যেকোনো ব্যবহারকারী এই এন্ডপয়েন্টগুলিতে অ্যাক্সেস করার চেষ্টা করলে স্প্রিং সিকিউরিটি স্বয়ংক্রিয়ভাবে একটি লগইন পেজ প্রদর্শন করবে।
3. সিকিউরিটি কনফিগারেশন ক্লাস তৈরি
এখন, আমরা একটি কনফিগারেশন ক্লাস তৈরি করব যেখানে আমরা ইন-মেমরি authentication কনফিগার করব এবং নির্দিষ্ট URL-এর জন্য authorization নিয়ম নির্ধারণ করব:
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.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable()) // REST API-র জন্য CSRF নিষ্ক্রিয়
.authorizeHttpRequests(auth -> auth
.requestMatchers("/hello").permitAll() // /hello সবার জন্য খোলা
.requestMatchers("/admin").hasRole("ADMIN") // /admin শুধু ADMIN-এর জন্য
.anyRequest().authenticated() // বাকি সব এন্ডপয়েন্ট প্রমাণীকরণ প্রয়োজন
)
.httpBasic(); // HTTP Basic Authentication ব্যবহার করা হবে
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // পাসওয়ার্ড এনকোডিং
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.builder()
.username("user")
.password(passwordEncoder().encode("password"))
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin")
.password(passwordEncoder().encode("admin123"))
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
এই কনফিগারেশনে আমরা তিনটি গুরুত্বপূর্ণ কাজ করেছি:
SecurityFilterChain: HTTP রিকোয়েস্টের জন্য নিরাপত্তা নিয়ম সংজ্ঞায়িত করে। আমরা/helloএন্ডপয়েন্টটি সবার জন্য উন্মুক্ত রেখেছি,/adminশুধুমাত্র ADMIN রোলের ব্যবহারকারীদের জন্য সীমাবদ্ধ করেছি এবং বাকি সব এন্ডপয়েন্টের জন্য authentication বাধ্যতামূলক করেছি।PasswordEncoder: পাসওয়ার্ডগুলি নিরাপদে সংরক্ষণের জন্য BCrypt এনকোডিং ব্যবহার করি।UserDetailsService: দুটি ইন-মেমরি ব্যবহারকারী তৈরি করেছি: একজন সাধারণuser(USER রোল) এবং একজনadmin(ADMIN রোল)।
4. অ্যাপ্লিকেশন রান করা
এখন SpringBootApplication ক্লাস থেকে অ্যাপ্লিকেশনটি রান করুন:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SecurityDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SecurityDemoApplication.class, args);
}
}
অ্যাপ্লিকেশনটি রান করার পর http://localhost:8080/hello এ যান — এটি কোনো প্রমাণীকরণ ছাড়াই অ্যাক্সেসযোগ্য হবে। http://localhost:8080/admin এ যাওয়ার চেষ্টা করলে এটি একটি HTTP Basic Authentication ডায়ালগ দেখাবে। admin এবং পাসওয়ার্ড admin123 দিলে আপনি অ্যাডমিন পৃষ্ঠাটি দেখতে পাবেন। ভুল ক্রেডেনশিয়াল দিলে ৪০১ (Unauthorized) এরর পাবেন।
সম্পূর্ণ উদাহরণ (Complete Example)
নিচে সম্পূর্ণ প্রজেক্টের কাঠামো এবং ফাইলগুলি দেওয়া হলো যা আপনি কপি করে সরাসরি রান করতে পারেন:
pom.xml (প্রয়োজনীয় অংশ):
<?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>3.2.0</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>security-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>security-demo</name>
<description>Demo project for Spring Security</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
SecurityConfig.java (উপরে দেওয়া হয়েছে)
HelloController.java (উপরে দেওয়া হয়েছে)
SecurityDemoApplication.java (উপরে দেওয়া হয়েছে)
application.properties ফাইলটিতে নিচের লাইনটি যোগ করলে ডিফল্ট লগইন পৃষ্ঠাটি দেখানোর পরিবর্তে HTTP Basic ব্যবহার হবে (আমরা ইতিমধ্যে কনফিগারেশনে httpBasic() ব্যবহার করেছি):
spring.security.user.name=admin
spring.security.user.password=admin123
তবে এই প্রপার্টি কনফিগারেশন ক্লাসের সাথে দ্বন্দ্ব তৈরি করতে পারে, তাই আমরা এটি না রেখে কনফিগারেশন ক্লাসের মাধ্যমেই ইউজার ডিফাইন করেছি।
এখন mvn spring-boot:run কমান্ড দিয়ে অ্যাপ্লিকেশনটি রান করুন এবং উপরে বর্ণিত URL গুলি টেস্ট করুন।
সাধারণ সমস্যা ও সমাধান (Common Issues)
স্প্রিং সিকিউরিটি নিয়ে কাজ করার সময় কিছু সাধারণ সমস্যার সম্মুখীন হতে পারেন:
- ৪০১ Unauthorized Error: আপনি যদি সঠিক ক্রেডেনশিয়াল ছাড়া কোনো প্রোটেক্টেড এন্ডপয়েন্ট অ্যাক্সেস করতে যান, তাহলে ৪০১ এরর আসবে। নিশ্চিত করুন যে আপনার ইউজার এবং পাসওয়ার্ড
UserDetailsService-এ সঠিকভাবে সংজ্ঞায়িত আছে এবং আপনি HTTP Basic-এর জন্য সঠিক হেডার পাঠাচ্ছেন (Postman বা curl-এর মাধ্যমে)। - CSRF টোকেন মিসিং: ডিফল্টভাবে CSRF সক্রিয় থাকে। আপনি যদি POST, PUT, DELETE রিকোয়েস্ট করেন তবে CSRF টোকেন প্রয়োজন। REST API-র জন্য আমরা সাধারণত
csrf().disable()ব্যবহার করি, কিন্তু ওয়েব অ্যাপ্লিকেশনে এটি সক্রিয় রাখা উচিত। সমাধান হলো রিকোয়েস্টের সাথে CSRF টোকেন অন্তর্ভুক্ত করা। - পাসওয়ার্ড এনকোডিং না করা: কখনোই প্লেইন টেক্সট পাসওয়ার্ড সংরক্ষণ করবেন না। সবসময়
PasswordEncoder(যেমনBCryptPasswordEncoder) ব্যবহার করুন। ভুল এনকোডারের কারণেThere is no PasswordEncoder mapped for the id "null"এরর আসতে পারে। - ডিফল্ট লগইন পেজ দেখা: আপনি যদি ফর্ম বেসড লগইন না চান, তবে কনফিগারেশনে
httpBasic()অথবা স্পষ্টভাবে.formLogin().disable()ব্যবহার করুন। ডিফল্ট লগইন পেজটি শুধুমাত্র ফর্ম লগইন সক্রিয় থাকলেই দেখা যাবে।
সারসংক্ষেপ (Summary)
এই টিউটোরিয়ালে আমরা স্প্রিং সিকিউরিটির মৌলিক ধারণা এবং একটি Spring Boot অ্যাপ্লিকেশনে কীভাবে সহজে authentication ও authorization কনফিগার করতে হয় তা শিখেছি। আমরা ইন-মেমরি ইউজার তৈরি করে role-based access নিয়ন্ত্রণ করা, HTTP Basic Authentication সক্রিয় করা এবং CSRF সুরক্ষা নিষ্ক্রিয় করার পদ্ধতি দেখেছি।
পরবর্তী ধাপে আপনি ডেটাবেস-ভিত্তিক ইউজার স্টোর, JWT (JSON Web Token) অথেনটিকেশন, OAuth2, এবং আরও উন্নত সুরক্ষা ফিচার নিয়ে পড়াশোনা করতে পারেন। স্প্রিং সিকিউরিটির অফিসিয়াল ডকুমেন্টেশন (spring.io/projects/spring-security) এবং Baeldung-এর টিউটোরিয়ালগুলি আপনাকে আরও গভীরে যেতে সাহায্য করবে। আপনার স্প্রিং সিকিউরিটি শেখার যাত্রা শুভ হোক!