উদাহরণ সহ REST API এর জন্য Spring Security বাস্তবায়ন

Spring Security এবং API Security - স্প্রিং সিকিউরিটি (Spring Security) - Java Technologies

279

Spring Security হল একটি শক্তিশালী ফ্রেমওয়ার্ক যা Spring ভিত্তিক অ্যাপ্লিকেশনগুলোতে নিরাপত্তা ব্যবস্থা প্রদান করে। RESTful API-তে নিরাপত্তা যোগ করার জন্য Spring Security ব্যবহার করা হয়, যেখানে Authentication, Authorization, CSRF Protection, এবং আরও অনেক নিরাপত্তা কার্যক্রম পরিচালিত হয়।

এখানে Spring Security ব্যবহারের মাধ্যমে REST API-এর জন্য Authentication ও Authorization কনফিগারেশন দেওয়া হয়েছে, যাতে আমরা JWT (JSON Web Token) ব্যবহার করে নিরাপত্তা ব্যবস্থা ইমপ্লিমেন্ট করতে পারি।


Spring Security with JWT Authentication for REST API: উদাহরণ

Step 1: Dependencies

প্রথমে, আপনাকে আপনার pom.xml ফাইলে প্রয়োজনীয় ডিপেন্ডেন্সি যোগ করতে হবে।

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

    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.11.5</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

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

Step 2: JWT Utility Class

JWT Utility Class তৈরি করা হবে, যা Token Generation এবং Token Validation পরিচালনা করবে।

import io.jsonwebtoken.*;
import java.util.Date;

import org.springframework.stereotype.Component;

@Component
public class JwtUtil {

    private String SECRET_KEY = "your-256-bit-secret-key";

    private final int EXPIRATION_TIME = 1000 * 60 * 60 * 10; // 10 Hours

    public String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

    public String extractUsername(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(SECRET_KEY)
                .build()
                .parseClaimsJws(token)
                .getBody()
                .getSubject();
    }

    public boolean isTokenExpired(String token) {
        return getExpirationDateFromToken(token).before(new Date());
    }

    public Date getExpirationDateFromToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(SECRET_KEY)
                .build()
                .parseClaimsJws(token)
                .getBody()
                .getExpiration();
    }

    public boolean validateToken(String token, String username) {
        return (username.equals(extractUsername(token)) && !isTokenExpired(token));
    }
}

Step 3: Authentication Filter

JWT Token যাচাই করার জন্য Authentication Filter তৈরি করা হবে। এটি প্রতিটি HTTP রিকোয়েস্টের হেডারে পাঠানো JWT টোকেন যাচাই করবে।

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        final String authHeader = request.getHeader("Authorization");

        String username = null;
        String token = null;

        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            token = authHeader.substring(7);
            username = jwtUtil.extractUsername(token);
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);

            if (jwtUtil.validateToken(token, userDetails.getUsername())) {
                UsernamePasswordAuthenticationToken authToken =
                        new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                SecurityContextHolder.getContext().setAuthentication(authToken);
            }
        }
        filterChain.doFilter(request, response);
    }
}

Step 4: Spring Security Configuration

Spring Security Configuration তৈরি করা হবে যাতে JWT Filter এবং Custom Authentication Handler যুক্ত করা যায়।

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.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeHttpRequests()
                .requestMatchers("/auth/**").permitAll() // Allow login without authentication
                .anyRequest().authenticated() // Other requests need authentication
            .and()
            .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }
}

Explanation:

  • csrf().disable(): REST API-তে CSRF সাধারণত নিষ্ক্রিয় করা হয়, কারণ API কল স্টেটলেস।
  • addFilterBefore: Custom JwtAuthenticationFilter Spring Security filter chain-এ যুক্ত করা হয়েছে, যাতে টোকেন যাচাই করা হয়।

Step 5: Authentication Controller

লগইন করতে এবং JWT Token পেতে একটি API তৈরি করা হবে।

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/auth")
public class AuthController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtil jwtUtil;

    @PostMapping("/login")
    public String login(@RequestBody AuthRequest authRequest) {
        authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword())
        );
        return jwtUtil.generateToken(authRequest.getUsername());
    }
}

class AuthRequest {
    private String username;
    private String password;
    // Getters and Setters
}

Explanation:

  • login Method: ব্যবহারকারী যখন লগইন করবে, তখন JWT Token ইস্যু করা হবে।

Step 6: Accessing Protected Resources

আপনি নিরাপদ GET বা POST রিকোয়েস্ট করার জন্য JWT Token ব্যবহার করবেন। নিচে একটি উদাহরণ দেওয়া হয়েছে:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ApiController {

    @GetMapping("/protected")
    public String getProtectedData() {
        return "This is a protected resource!";
    }
}

এখানে /protected এন্ডপয়েন্টটি JWT Token যাচাই করবে এবং Token বৈধ হলে শুধুমাত্র এক্সেস পাওয়া যাবে।


Step 7: Testing with Postman

  1. প্রথমে /auth/login রিকোয়েস্ট দিয়ে JWT Token পেতে হবে।
  2. তারপর এই JWT Token হেডারে পাঠিয়ে /protected এন্ডপয়েন্টে GET রিকোয়েস্ট পাঠাতে হবে।

Example:

  • Authorization Header:

    Bearer <JWT_TOKEN>
    

Conclusion

এটি একটি সিম্পল JWT Authentication পদ্ধতি যেখানে Spring Security ব্যবহৃত হয়েছে REST API সুরক্ষিত করার জন্য। মূল পদ্ধতিগুলি ছিল:

  1. JWT Token Generation - লগইন করার সময় টোকেন তৈরি করা।
  2. JWT Token Validation - প্রতিটি রিকোয়েস্টের সাথে টোকেন যাচাই করা।
  3. Spring Security Configuration - টোকেন যাচাই করতে Spring Security ফিল্টার ব্যবহার করা।

এটি নিরাপদ REST API নির্মাণের জন্য একটি কার্যকরী পদ্ধতি।

Content added By
Promotion

Are you sure to start over?

Loading...