Java Technologies Spring Security এবং Two-Factor Authentication (2FA) গাইড ও নোট

303

Two-Factor Authentication (2FA) হলো একটি নিরাপত্তা প্রক্রিয়া যেখানে ব্যবহারকারীকে দুটি আলাদা প্রমাণীকরণ পদ্ধতির মাধ্যমে সিস্টেমে প্রবেশ করার অনুমতি দেওয়া হয়। এটি সাধারণত something you know (যেমন পাসওয়ার্ড) এবং something you have (যেমন এক-time পাসওয়ার্ড বা OTP) এর মাধ্যমে কাজ করে।

Spring Security 2FA (Two-Factor Authentication) কনফিগার করতে, আপনাকে OTP (One-Time Password) বা TOTP (Time-based One-Time Password) সিস্টেম ব্যবহার করতে হবে। এটি নিশ্চিত করে যে একজন ব্যবহারকারী শুধুমাত্র পাসওয়ার্ডই নয়, বরং দ্বিতীয় একটি যাচাইকরণ পদ্ধতিও সম্পন্ন করতে হবে।

Spring Security তে 2FA বাস্তবায়ন করার জন্য, সাধারণত SMS, Email, বা Authenticator App (যেমন Google Authenticator) ব্যবহার করা হয়।


Spring Security তে Two-Factor Authentication (2FA) কনফিগারেশন

ধাপ ১: ডিপেন্ডেন্সি যোগ করুন

প্রথমে, 2FA কার্যক্রমের জন্য যে লাইব্রেরি দরকার তা আপনার pom.xml এ যুক্ত করুন। যদি OTP প্রক্রিয়া ব্যবহার করতে চান, তাহলে সাধারণত spring-security-otp লাইব্রেরি ব্যবহার করা যায়।

Maven ডিপেন্ডেন্সি:
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-client</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-jose</artifactId>
</dependency>

<dependency>
    <groupId>com.warrenstrange</groupId>
    <artifactId>googleauth</artifactId>
    <version>1.5.0</version>
</dependency>

এখানে googleauth লাইব্রেরিটি TOTP (Time-based One-Time Password) তৈরি করার জন্য ব্যবহার করা হচ্ছে, যা Google Authenticator অ্যাপের জন্য কাজ করে।


ধাপ ২: OTP বা TOTP সেটআপ

TOTP সেটআপ উদাহরণ (Google Authenticator)

Google Authenticator বা অন্যান্য একই ধরনের অ্যাপ ব্যবহারকারীর ডিভাইসে একটি সময়ভিত্তিক OTP তৈরি করে। এটি সাধারণত একটি সিক্রেট কীগুলির মাধ্যমে কাজ করে, যেটি শুরুতে ব্যবহারকারীকে প্রদান করা হয়।

  1. সিক্রেট কী তৈরি করুন: প্রথমে একটি সিক্রেট কী তৈরি করতে হবে, যেটি ব্যবহারকারীর ডিভাইসে স্ক্যান করার জন্য তৈরি করা হবে।
import com.warrenstrange.googleauth.GoogleAuthenticator;
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;

public class TwoFactorAuthenticationService {

    private final GoogleAuthenticator gAuth = new GoogleAuthenticator();

    public String generateSecretKey() {
        GoogleAuthenticatorKey key = gAuth.createCredentials();
        return key.getKey();
    }
}

এখন, এই generateSecretKey মেথড ব্যবহারকারীকে একটি সিক্রেট কী প্রদান করবে, যা তাদের Google Authenticator অ্যাপে স্ক্যান করার জন্য ব্যবহৃত হবে।

  1. OTP যাচাই করা: ব্যবহারকারী তাদের অ্যাপ থেকে OTP পাঠালে, আমরা এই OTP যাচাই করব:
public boolean verifyCode(String secretKey, int code) {
    return gAuth.authorize(secretKey, code);
}

এখানে, secretKey হলো সেই কী যা প্রথমে তৈরি হয়েছিল এবং code হলো ব্যবহারকারী দ্বারা অ্যাপ থেকে নেওয়া OTP।


ধাপ ৩: Spring Security কনফিগারেশন

Spring Security তে OTP যাচাই করার জন্য কাস্টম ফিল্টার তৈরি করতে হবে যা প্রথমে ইউজারের পাসওয়ার্ড যাচাই করবে এবং তার পর OTP যাচাই করবে।

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

public class TwoFactorAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private final AuthenticationManager authenticationManager;

    public TwoFactorAuthenticationFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String otp = request.getParameter("otp");

        // Perform authentication for username and password first
        Authentication authentication = super.attemptAuthentication(request, response);

        // Validate OTP
        if (authentication.isAuthenticated()) {
            String secretKey = getUserSecretKey(username); // Retrieve the stored secret key for the user
            boolean otpValid = verifyOtp(secretKey, Integer.parseInt(otp));

            if (otpValid) {
                return authentication; // Authentication successful with OTP
            } else {
                throw new AuthenticationException("Invalid OTP") {};
            }
        } else {
            throw new AuthenticationException("Invalid username or password") {};
        }
    }

    private boolean verifyOtp(String secretKey, int otp) {
        return new TwoFactorAuthenticationService().verifyCode(secretKey, otp);
    }

    private String getUserSecretKey(String username) {
        // Retrieve secret key for the user from the database or session
        return "userSecretKey"; // Example: Retrieve from DB
    }
}

এখানে, প্রথমে ব্যবহারকারীর ইউজারনেম এবং পাসওয়ার্ড যাচাই করা হয়, এরপর ব্যবহারকারী যে OTP প্রদান করেছে তা যাচাই করা হয়।


ধাপ ৪: Controller তে OTP প্রক্রিয়া

আপনার Controller-এ ব্যবহারকারীদের লগইন করার পর OTP যাচাইয়ের জন্য একটি নতুন রিকোয়েস্ট গ্রহণ করতে হবে।

import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.authentication.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class AuthenticationController {

    private final TwoFactorAuthenticationService twoFactorAuthenticationService;

    public AuthenticationController(TwoFactorAuthenticationService twoFactorAuthenticationService) {
        this.twoFactorAuthenticationService = twoFactorAuthenticationService;
    }

    @PostMapping("/login")
    public String login(@RequestParam("username") String username,
                        @RequestParam("password") String password,
                        @RequestParam("otp") String otp) {

        // First authenticate with username and password
        // Then verify OTP
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication != null && authentication.isAuthenticated()) {
            String secretKey = getUserSecretKey(username);
            if (twoFactorAuthenticationService.verifyCode(secretKey, Integer.parseInt(otp))) {
                return "redirect:/dashboard";
            } else {
                return "redirect:/login?error=invalidOtp";
            }
        }
        return "redirect:/login?error=invalidCredentials";
    }

    private String getUserSecretKey(String username) {
        // Retrieve the secret key from the database
        return "userSecretKey";
    }
}

এখানে, লগইন ফর্মে পাসওয়ার্ড ও OTP সংগ্রহ করা হচ্ছে, এবং পরে OTP যাচাই করা হচ্ছে। সফল হলে ব্যবহারকারীকে ড্যাশবোর্ডে রিডিরেক্ট করা হচ্ছে।


ধাপ ৫: Two-Factor Authentication UI

একটি সাধারণ UI তৈরি করুন যেখানে ব্যবহারকারী তাদের পাসওয়ার্ড এবং OTP ইনপুট করবে।

<form action="/login" method="POST">
    <input type="text" name="username" placeholder="Username" required/>
    <input type="password" name="password" placeholder="Password" required/>
    <input type="text" name="otp" placeholder="OTP" required/>
    <button type="submit">Login</button>
</form>

উপসংহার

Two-Factor Authentication (2FA) Spring Security তে পাসওয়ার্ডের সাথে একটি অতিরিক্ত সুরক্ষা স্তর যোগ করতে সাহায্য করে। এটি সাধারণত পাসওয়ার্ডের পরে OTP, TOTP, বা Authenticator App ব্যবহার করে। Spring Security তে 2FA কনফিগার করতে আপনাকে প্রথমে পাসওয়ার্ড যাচাই করতে হবে এবং তারপর OTP যাচাই করতে হবে। OTP যাচাইয়ের জন্য সাধারণভাবে googleauth লাইব্রেরি ব্যবহার করা হয়, যা Google Authenticator সহ অন্যান্য OTP অ্যাপ্লিকেশনগুলির সাথে কাজ করে।

Content added By

Two-Factor Authentication কি এবং কেন এটি প্রয়োজন?

1k

Two-Factor Authentication (2FA) হল একটি সুরক্ষা প্রক্রিয়া যা ব্যবহারকারীর পরিচয় নিশ্চিত করতে দুটি পৃথক উপাদান চায়। এটি সাধারণত পাসওয়ার্ড (প্রথম ফ্যাক্ট) এবং একটি অতিরিক্ত উপাদান (যেমন, OTP - One Time Password, ফিঙ্গারপ্রিন্ট, বা হার্ডওয়্যার টোকেন - দ্বিতীয় ফ্যাক্ট) এর সংমিশ্রণ হয়।

2FA হল একটি শক্তিশালী নিরাপত্তা ব্যবস্থা যা একটি একক পাসওয়ার্ডের তুলনায় বেশি সুরক্ষা প্রদান করে। এটি নিশ্চিত করে যে, শুধুমাত্র পাসওয়ার্ড জানলেই কোনো অ্যাকাউন্ট অ্যাক্সেস করা সম্ভব নয়। এর মাধ্যমে ব্যবহারকারীর নিরাপত্তা বৃদ্ধি পায়, কারণ আক্রমণকারীকে দুটি ভিন্ন ধরনের প্রমাণ দিতে হয়।


Two-Factor Authentication (2FA) এর কাজ করার পদ্ধতি

2FA সাধারণত দুটি ভিন্ন ফ্যাক্টর দিয়ে কাজ করে:

  1. Something you know (Knowledge factor):
    • এটি সাধারণত পাসওয়ার্ড বা পিন হতে পারে যা ব্যবহারকারী জানে।
  2. Something you have (Possession factor):
    • এটি সাধারণত একটি মোবাইল ডিভাইস, হার্ডওয়্যার টোকেন বা OTP (One Time Password) হতে পারে, যা ব্যবহারকারী তার কাছে থাকে।

এই দুটি ফ্যাক্টরের সমন্বয়ে, ব্যবহারকারীর পরিচয় নিশ্চিত করা হয়।


Two-Factor Authentication কেন প্রয়োজন?

  1. পাসওয়ার্ড সুরক্ষা দুর্বলতা:
    • পাসওয়ার্ড সাধারণত কমপ্লেক্স হলেও, তা যদি চুরি বা অনুমান করা যায় (যেমন ফিশিং আক্রমণের মাধ্যমে), তবে একমাত্র পাসওয়ার্ডের মাধ্যমে অ্যাকাউন্ট অ্যাক্সেস পাওয়া সম্ভব হয়। 2FA ব্যবহারকারীকে আরও একটি স্তরের সুরক্ষা প্রদান করে, যাতে কেবল পাসওয়ার্ডের মাধ্যমেই অ্যাক্সেস সম্ভব না হয়।
  2. ফিশিং আক্রমণ প্রতিরোধ:
    • ফিশিং আক্রমণের মাধ্যমে আক্রমণকারী ব্যবহারকারীর পাসওয়ার্ড চুরি করতে পারে, কিন্তু OTP বা মোবাইল ফোনের মাধ্যমে প্রাপ্ত কোড (যা পাসওয়ার্ড থেকে আলাদা) চুরি করা বেশ কঠিন।
  3. ব্যবহারকারীর অ্যাকাউন্ট সুরক্ষা:
    • 2FA নিশ্চিত করে যে, শুধু পাসওয়ার্ড জানলেই অ্যাকাউন্টে প্রবেশ করা সম্ভব নয়, বরং ব্যবহারকারীকে একটি আরেকটি "তথ্য" (যেমন, OTP) প্রদান করতে হবে। এটি অ্যাকাউন্টের নিরাপত্তা আরও উন্নত করে।
  4. বড় প্রতিষ্ঠানে নিরাপত্তা চাহিদা:
    • বড় প্রতিষ্ঠান এবং সংস্থাগুলি যেখানে অ্যাক্সেসের জন্য সংবেদনশীল ডেটা থাকে, সেখানে 2FA ব্যবহার করা একটি প্রয়োজনীয় নিরাপত্তা ব্যবস্থা।
  5. নতুন নিরাপত্তা স্ট্যান্ডার্ড:
    • অনেক বড় প্রতিষ্ঠান যেমন গুগল, ফেসবুক, ব্যাংকিং সিস্টেম এবং অন্যান্য সেবাগুলি ইতিমধ্যেই তাদের সিস্টেমে 2FA ব্যবহার শুরু করেছে। এটি এখন নিরাপত্তার জন্য একটি অত্যন্ত গুরুত্বপূর্ণ ফিচার।

Spring Security-তে Two-Factor Authentication কনফিগারেশন

Spring Security তে 2FA বাস্তবায়ন করতে আপনি সাধারণত OTP বা TOTP (Time-based One-Time Password) ব্যবহার করতে পারেন। এখানে আমরা OTP-based 2FA কনফিগারেশনের উদাহরণ দেব।

ধাপ ১: ডিপেন্ডেন্সি যোগ করা

Spring Security 2FA বাস্তবায়ন করতে spring-security এবং spring-boot-starter ডিপেন্ডেন্সি ব্যবহার করতে হবে।

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

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-otp</artifactId>
    <version>1.0.0</version>
</dependency>
Gradle:
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.security:spring-security-otp:1.0.0'

ধাপ ২: OTP (One Time Password) জেনারেশন

OTP ব্যবহার করতে হলে, আপনি একটি OTP সার্ভিস তৈরি করতে পারেন। Spring Security এর সাথে OTP পাঠানোর জন্য সাধারণত SMS API (যেমন Twilio বা Nexmo) বা Email ব্যবহার করা হয়।

import org.springframework.stereotype.Service;

@Service
public class OTPService {

    public String generateOTP(String user) {
        // OTP জেনারেট করার জন্য কোনো লাইব্রেরি বা কাস্টম লজিক ব্যবহার করতে পারেন
        return "123456";  // উদাহরণস্বরূপ একটি স্ট্যাটিক OTP
    }

    public boolean validateOTP(String otp, String user) {
        // OTP যাচাই করার জন্য
        return otp.equals("123456");  // উদাহরণস্বরূপ
    }
}

ধাপ ৩: 2FA কনফিগারেশন

2FA বাস্তবায়ন করার জন্য, Spring Security কনফিগারেশন ক্লাসে অতিরিক্ত স্টেপ যোগ করতে হবে।

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;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/login", "/login/otp").permitAll() // Login and OTP pages accessible to everyone
                .anyRequest().authenticated()  // Other pages require authentication
            .and()
            .formLogin()
                .loginPage("/login")
            .and()
            .addFilterBefore(new OTPAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); // Custom filter for OTP authentication
    }
}

ধাপ ৪: OTP Authentication Filter

OTP যাচাইয়ের জন্য একটি কাস্টম ফিল্টার তৈরি করা হয় যা OTP ইনপুট সংগ্রহ করবে এবং যাচাই করবে।

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter("/login/otp")
public class OTPAuthenticationFilter implements Filter {

    private final OTPService otpService;

    public OTPAuthenticationFilter(OTPService otpService) {
        this.otpService = otpService;
    }

    @Override
    public void doFilter(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String otp = httpRequest.getParameter("otp");
        
        if (otpService.validateOTP(otp, httpRequest.getUserPrincipal().getName())) {
            chain.doFilter(request, response); // OTP valid, continue request processing
        } else {
            ((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid OTP");
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void destroy() {}
}

ধাপ ৫: OTP-ভিত্তিক লগইন পৃষ্ঠা

লগইন পৃষ্ঠায় পাসওয়ার্ড এবং OTP ইনপুট করতে হবে:

login.html

<form action="/login" method="post">
    <label for="username">Username</label>
    <input type="text" id="username" name="username" required>

    <label for="password">Password</label>
    <input type="password" id="password" name="password" required>

    <button type="submit">Login</button>
</form>

otp.html

<form action="/login/otp" method="post">
    <label for="otp">Enter OTP</label>
    <input type="text" id="otp" name="otp" required>

    <button type="submit">Verify OTP</button>
</form>

উপসংহার

Two-Factor Authentication (2FA) একটি গুরুত্বপূর্ণ নিরাপত্তা স্তর, যা ব্যবহারকারীর অ্যাকাউন্টকে অতিরিক্ত সুরক্ষা প্রদান করে। Spring Security-তে 2FA বাস্তবায়ন করতে OTP বা TOTP ব্যবহার করা যেতে পারে, যা একটি সাধারণ এবং শক্তিশালী পদ্ধতি। এটি পাসওয়ার্ড এবং একটি অতিরিক্ত উপাদান দিয়ে প্রমাণীকরণ নিশ্চিত করে, যা সিস্টেমের নিরাপত্তা বৃদ্ধি করে এবং আক্রমণকারীদের অ্যাক্সেস করা কঠিন করে।

Content added By

Spring Security তে Google Authenticator ব্যবহার করে 2FA কনফিগার করা

345

Two-Factor Authentication (2FA) বা Two-Step Verification হলো একটি নিরাপত্তা ব্যবস্থা যেখানে ব্যবহারকারীকে একটি অতিরিক্ত প্রমাণীকরণ স্তর (যেমন Google Authenticator) ব্যবহার করে তার পরিচয় যাচাই করতে হয়। এটি একটি Time-based One-Time Password (TOTP) সিস্টেম ব্যবহার করে, যা একটি নির্দিষ্ট সময়ের জন্য একক পাসওয়ার্ড তৈরি করে।

Spring Security তে Google Authenticator ব্যবহার করে 2FA কনফিগার করার জন্য কয়েকটি ধাপ অনুসরণ করতে হবে। আমরা এখানে একটি সহজ উদাহরণ দিয়ে দেখাবো কিভাবে 2FA কনফিগার করতে হয়।


ধাপ ১: প্রয়োজনীয় ডিপেনডেন্সি যোগ করা

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

<dependencies>
    <!-- Spring Boot Starter Security -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    
    <!-- Spring Boot Starter Web (for building REST API) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- Google Authenticator dependency for 2FA -->
    <dependency>
        <groupId>com.warrenstrange</groupId>
        <artifactId>googleauth</artifactId>
        <version>1.5.0</version>
    </dependency>
</dependencies>

googleauth লাইব্রেরিটি ব্যবহারকারীদের জন্য TOTP (Time-based One-Time Password) জেনারেট করতে সাহায্য করবে, যা Google Authenticator অ্যাপ্লিকেশন ব্যবহার করে ব্যবহারকারীরা প্রমাণীকরণ করতে পারবেন।


ধাপ ২: Google Authenticator সেটআপ

১. Google Authenticator ব্যবহারকারীর জন্য একটি সিক্রেট কী তৈরি করা

আপনি ব্যবহারকারীকে একটি সিক্রেট কী দিতে হবে, যা তারা Google Authenticator অ্যাপ্লিকেশনে স্ক্যান করবেন। এই সিক্রেট কীটি একটি নির্দিষ্ট সময়ে TOTP তৈরি করবে।

import com.warrenstrange.googleauth.GoogleAuthenticator;
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;

@Service
public class TwoFactorAuthService {

    private final GoogleAuthenticator googleAuthenticator;

    public TwoFactorAuthService() {
        this.googleAuthenticator = new GoogleAuthenticator();
    }

    // Generate a secret key for a new user
    public String generateSecretKey() {
        GoogleAuthenticatorKey key = googleAuthenticator.createCredentials();
        return key.getKey(); // secret key
    }
}
  • এখানে generateSecretKey() মেথডে আমরা Google Authenticator জন্য সিক্রেট কী জেনারেট করছি।

২. ব্যবহারকারীকে QR কোড দেখানো

একবার সিক্রেট কী তৈরি হলে, এটি Google Authenticator অ্যাপ্লিকেশনে স্ক্যান করার জন্য একটি QR কোড আকারে প্রদান করা যেতে পারে।

import com.warrenstrange.googleauth.GoogleAuthenticator;
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;
import com.warrenstrange.googleauth.GoogleAuthenticatorQRGenerator;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TwoFactorAuthController {

    private final TwoFactorAuthService twoFactorAuthService;

    public TwoFactorAuthController(TwoFactorAuthService twoFactorAuthService) {
        this.twoFactorAuthService = twoFactorAuthService;
    }

    // Generate QR Code URL for the user to scan
    @GetMapping("/generate-qr")
    public String generateQrCode(@RequestParam String username) {
        String secretKey = twoFactorAuthService.generateSecretKey();
        String qrUrl = GoogleAuthenticatorQRGenerator.getOtpAuthURL("YourAppName", username, secretKey);
        return qrUrl; // return the QR URL, can be rendered as image
    }
}
  • GoogleAuthenticatorQRGenerator.getOtpAuthURL() ব্যবহারকারীর জন্য একটি QR কোড URL তৈরি করবে। এই URL-টি Google Authenticator অ্যাপ্লিকেশন দ্বারা স্ক্যান করা যাবে।

৩. TOTP যাচাই

যখন ব্যবহারকারী Google Authenticator অ্যাপ্লিকেশন থেকে OTP প্রদান করবে, তখন আপনাকে সেই OTP যাচাই করতে হবে।

import com.warrenstrange.googleauth.GoogleAuthenticator;
import org.springframework.stereotype.Service;

@Service
public class TwoFactorAuthService {

    private final GoogleAuthenticator googleAuthenticator;

    public TwoFactorAuthService() {
        this.googleAuthenticator = new GoogleAuthenticator();
    }

    // Validate the OTP entered by the user
    public boolean validateOtp(String secretKey, int otp) {
        return googleAuthenticator.authorize(secretKey, otp); // validate the OTP
    }
}
  • এখানে, validateOtp() মেথডে Google Authenticator থেকে পাওয়া OTP যাচাই করা হচ্ছে। যদি এটি সঠিক হয়, তাহলে প্রমাণীকরণ সফল হবে।

ধাপ ৩: Spring Security কনফিগারেশন

Spring Security তে লগইন প্রক্রিয়া কনফিগার করতে হবে যাতে 2FA যাচাই অন্তর্ভুক্ত থাকে।

২FA কনফিগারেশন এবং ফিল্টার তৈরি করা

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
public class SecurityConfig {

    private final TwoFactorAuthService twoFactorAuthService;

    public SecurityConfig(TwoFactorAuthService twoFactorAuthService) {
        this.twoFactorAuthService = twoFactorAuthService;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/login", "/generate-qr").permitAll()
                .anyRequest().authenticated() // সমস্ত রিকোয়েস্টে অথেন্টিকেশন প্রয়োজন
            .and()
            .formLogin()
                .loginPage("/login")  // কাস্টম লগইন পেজ
                .permitAll()
            .and()
            .addFilterBefore(new TwoFactorAuthFilter(twoFactorAuthService), UsernamePasswordAuthenticationFilter.class); // 2FA filter
        return http.build();
    }
}

এখানে, TwoFactorAuthFilter নামক একটি কাস্টম ফিল্টার ব্যবহার করা হচ্ছে, যা 2FA যাচাই প্রক্রিয়া সম্পন্ন করবে। এই ফিল্টারটি ব্যবহারকারী যখন প্রথমবার লগইন করবেন, তখন তাদের OTP যাচাই করার জন্য ব্যবহৃত হবে।

২FA ফিল্টার

import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter("/login")
public class TwoFactorAuthFilter implements Filter {

    private final TwoFactorAuthService twoFactorAuthService;

    public TwoFactorAuthFilter(TwoFactorAuthService twoFactorAuthService) {
        this.twoFactorAuthService = twoFactorAuthService;
    }

    @Override
    public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        String otp = request.getParameter("otp");
        String secretKey = "user-secret-key"; // সিক্রেট কীটি ডাটাবেস বা অন্য কোথাও সংরক্ষিত থাকে

        if (otp != null) {
            boolean isValid = twoFactorAuthService.validateOtp(secretKey, Integer.parseInt(otp));
            if (isValid) {
                chain.doFilter(request, response); // OTP সঠিক হলে লগইন সম্পন্ন হবে
            } else {
                response.sendRedirect("/login?error"); // ভুল OTP হলে লগইন ফেইল
            }
        } else {
            response.sendRedirect("/2fa"); // OTP প্রবেশ করতে পেজে রিডাইরেক্ট
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void destroy() {}
}

এই ফিল্টারে, ব্যবহারকারী OTP জমা দেয়ার পরে তা যাচাই করা হয়। যদি OTP সঠিক হয়, তবে লগইন সফল হবে। যদি ভুল OTP হয়, ব্যবহারকারীকে একটি ত্রুটি পেজে রিডাইরেক্ট করা হবে।


উপসংহার

Google Authenticator ব্যবহার করে 2FA কনফিগার করার মাধ্যমে আপনি Spring Security অ্যাপ্লিকেশনে একটি শক্তিশালী দ্বৈত প্রমাণীকরণ ব্যবস্থা যুক্ত করতে পারেন। এটি ব্যবহারকারীর সুরক্ষা বাড়াতে সাহায্য করে, বিশেষ করে যখন তারা অস্বাভাবিক অবস্থানে লগইন করছে বা নতুন ডিভাইস থেকে অ্যাক্সেস করছে।

Content added By

উদাহরণ সহ 2FA বাস্তবায়ন

278

Two-Factor Authentication (2FA) হল একটি নিরাপত্তা পদ্ধতি যেখানে দুটি ভিন্ন উপায়ে ব্যবহারকারীকে যাচাই করা হয়:

  1. First Factor (Something you know): একটি পাসওয়ার্ড বা PIN।
  2. Second Factor (Something you have): একটি টোকেন বা মোবাইল ফোনের মাধ্যমে এককালীন পাসওয়ার্ড (OTP)।

Spring Security-তে 2FA বাস্তবায়ন করতে, সাধারণত OTP (One-Time Password) ব্যবহার করা হয় যা ব্যবহারকারীর ফোনে SMS বা একটি অ্যাপ্লিকেশন (যেমন Google Authenticator) মাধ্যমে পাঠানো হয়। Spring Security তে 2FA বাস্তবায়ন করার জন্য একাধিক উপায় রয়েছে। এখানে আমরা একটি উদাহরণ দেখব যেখানে SMS OTP এবং Password ব্যবহার করে 2FA কনফিগার করা হবে।


Maven Dependencies

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

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

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

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-client</artifactId>
</dependency>

<dependency>
    <groupId>com.twilio</groupId>
    <artifactId>twilio</artifactId>
    <version>8.0.0</version> <!-- Twilio for SMS -->
</dependency>

Twilio একটি জনপ্রিয় SMS API সেবা প্রদানকারী। আপনি অন্যান্য SMS প্রদানকারীর API ব্যবহার করতে পারেন।


2FA Flow

  1. First Step - Username and Password Authentication:
    • ব্যবহারকারী তাদের পাসওয়ার্ড প্রবেশ করবে।
  2. Second Step - OTP Verification:
    • সঠিক পাসওয়ার্ড দিলে, একটি OTP ব্যবহারকারীর মোবাইলে পাঠানো হবে।
  3. Final Authentication:
    • OTP সঠিকভাবে প্রবেশ করলে, লগইন সফল হবে।

1. First Step: Username and Password Authentication

Spring Security Configuration for Authentication

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()
                .requestMatchers("/login", "/otp").permitAll() // Allow login and OTP verification pages
                .anyRequest().authenticated() // Other pages require authentication
            .and()
            .formLogin()
                .loginPage("/login") // Custom login page
                .permitAll()
            .and()
            .logout()
                .permitAll();

        return http.build();
    }
}

Controller for Login Page

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.stereotype.Controller;

@Controller
public class LoginController {

    @GetMapping("/login")
    public String showLoginPage() {
        return "login"; // Return the login page (HTML)
    }
}

Login Page (login.html)

<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>
    <h2>Login</h2>
    <form action="/login" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" required><br>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required><br>
        <button type="submit">Login</button>
    </form>
</body>
</html>

2. Second Step: OTP Generation and Verification

OTP Service (For SMS Delivery)

import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
import com.twilio.type.PhoneNumber;
import org.springframework.stereotype.Service;

@Service
public class OTPService {

    // Twilio credentials
    public static final String ACCOUNT_SID = "your_account_sid";
    public static final String AUTH_TOKEN = "your_auth_token";
    public static final String FROM_PHONE = "+1234567890"; // Your Twilio phone number

    public OTPService() {
        Twilio.init(ACCOUNT_SID, AUTH_TOKEN); // Initialize Twilio API
    }

    public void sendOTP(String phoneNumber, String otp) {
        Message message = Message.creator(
                new PhoneNumber(phoneNumber), // To number
                new PhoneNumber(FROM_PHONE), // From number
                "Your OTP is: " + otp) // OTP message
            .create();
    }

    public String generateOTP() {
        int otp = (int) (Math.random() * 9000) + 1000; // Generate a 4-digit OTP
        return String.valueOf(otp);
    }
}

OTP Controller (To handle OTP generation and verification)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestController
public class OTPController {

    @Autowired
    private OTPService otpService;

    private Map<String, String> userOTPMap = new HashMap<>();

    @PostMapping("/generate-otp")
    public String generateOtp(@RequestParam String phoneNumber) {
        String otp = otpService.generateOTP();
        userOTPMap.put(phoneNumber, otp);
        otpService.sendOTP(phoneNumber, otp); // Send OTP to user's phone
        return "OTP sent to your phone";
    }

    @PostMapping("/verify-otp")
    public String verifyOtp(@RequestParam String phoneNumber, @RequestParam String otp) {
        String storedOtp = userOTPMap.get(phoneNumber);
        if (storedOtp != null && storedOtp.equals(otp)) {
            return "OTP verified successfully!";
        } else {
            return "Invalid OTP!";
        }
    }
}

OTP Page (otp.html)

<!DOCTYPE html>
<html>
<head>
    <title>OTP Verification</title>
</head>
<body>
    <h2>Enter OTP</h2>
    <form action="/verify-otp" method="post">
        <label for="phoneNumber">Phone Number:</label>
        <input type="text" id="phoneNumber" name="phoneNumber" required><br>
        <label for="otp">OTP:</label>
        <input type="text" id="otp" name="otp" required><br>
        <button type="submit">Verify OTP</button>
    </form>
</body>
</html>

3. Final Authentication

Spring Security Configuration for 2FA

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()
                .requestMatchers("/login", "/otp", "/generate-otp").permitAll() // Allow login and OTP pages
                .anyRequest().authenticated() // Other pages require authentication
            .and()
            .formLogin()
                .loginPage("/login") // Custom login page
                .permitAll()
            .and()
            .logout()
                .permitAll();

        return http.build();
    }
}

উপসংহার

Spring Security তে Two-Factor Authentication (2FA) বাস্তবায়ন করতে, আপনি পাসওয়ার্ড এবং OTP (যেমন SMS বা Authenticator অ্যাপ) ব্যবহার করে নিরাপত্তা স্তর বাড়াতে পারেন। এখানে SMS OTP-এর মাধ্যমে 2FA বাস্তবায়ন করা হয়েছে, তবে আপনি Google Authenticator বা Authy এর মতো অ্যাপ্লিকেশন ব্যবহার করেও একই ধরনের 2FA সেটআপ করতে পারেন।

আপনার অ্যাপ্লিকেশনে 2FA প্রয়োগ করতে আরও কোনও সাহায্য প্রয়োজন হলে, নির্দ্বিধায় জানাতে পারেন!

Content added By
Promotion

Are you sure to start over?

Loading...