Spring Security Exception Handling ব্যবহারকারীর সিকিউরিটি সম্পর্কিত ত্রুটি বা ব্যতিক্রম সঠিকভাবে হ্যান্ডেল করতে সাহায্য করে। এটি ব্যবহারকারীকে ত্রুটি সম্পর্কে সঠিকভাবে জানাতে এবং অ্যাপ্লিকেশনে সিকিউরিটি নিয়ন্ত্রণ বজায় রাখতে গুরুত্বপূর্ণ। Spring Security তে exception handling এর মাধ্যমে আমরা Authentication, Authorization, এবং অন্যান্য সিকিউরিটি সম্পর্কিত ত্রুটিগুলোকে কাস্টমাইজড বা ডিফল্টভাবে হ্যান্ডেল করতে পারি।
এখানে কিছু সাধারণ Spring Security Exception Handling এর বিষয় এবং তাদের সমাধান উপস্থাপন করা হলো।
AuthenticationException তখন ঘটে যখন ব্যবহারকারী লগইন করার চেষ্টা করে এবং তাদের পরিচয় সঠিক না হয় (যেমন ভুল ইউজারনেম বা পাসওয়ার্ড)। আমরা এই ধরনের ব্যতিক্রম কাস্টমাইজডভাবে হ্যান্ডেল করতে পারি।
Spring Security তে AuthenticationFailureHandler
এবং AuthenticationSuccessHandler
ব্যবহার করে আমরা লগইন সম্পর্কিত ব্যতিক্রমগুলো কাস্টমাইজডভাবে হ্যান্ডেল করতে পারি।
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
throws IOException {
// লগইন ব্যর্থ হলে ব্যবহারকারীকে একটি কাস্টম মেসেজ শো করা
response.sendRedirect("/login?error=true");
}
}
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException {
// লগইন সফল হলে, ব্যবহারকারীকে ড্যাশবোর্ডে রিডাইরেক্ট করা
response.sendRedirect("/dashboard");
}
}
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 {
private final CustomAuthenticationFailureHandler authenticationFailureHandler;
private final CustomAuthenticationSuccessHandler authenticationSuccessHandler;
public SecurityConfig(CustomAuthenticationFailureHandler authenticationFailureHandler,
CustomAuthenticationSuccessHandler authenticationSuccessHandler) {
this.authenticationFailureHandler = authenticationFailureHandler;
this.authenticationSuccessHandler = authenticationSuccessHandler;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login")
.failureHandler(authenticationFailureHandler) // Authentication failure handler
.successHandler(authenticationSuccessHandler) // Authentication success handler
.permitAll();
}
}
AuthorizationException তখন ঘটে যখন ব্যবহারকারী কোনো রিসোর্স বা URL অ্যাক্সেস করার চেষ্টা করে যেটি তাদের অনুমোদিত নয়। এই ব্যতিক্রমটি AccessDeniedException
ক্লাসের মাধ্যমে কাস্টমাইজডভাবে হ্যান্ডল করা যেতে পারে।
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException)
throws IOException {
// যখন ব্যবহারকারী কোনো রিসোর্স অ্যাক্সেস করতে পারবে না, তখন একটি কাস্টম মেসেজ শো করা
response.sendRedirect("/access-denied");
}
}
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 {
private final CustomAccessDeniedHandler accessDeniedHandler;
public SecurityConfig(CustomAccessDeniedHandler accessDeniedHandler) {
this.accessDeniedHandler = accessDeniedHandler;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasRole("USER")
.anyRequest().authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler) // Access denied exception handler
.and()
.formLogin()
.permitAll();
}
}
Spring Security তে সেশন হ্যান্ডলিংয়ের জন্য SessionManagementFilter এবং SessionExpiredException ব্যতিক্রম হ্যান্ডল করা হয়। সাধারণত সেশন টায়ম আউট হলে SessionAuthenticationException বা ExpiredSessionException ব্যতিক্রম হতে পারে।
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SessionAuthenticationException;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomSessionExpiredHandler {
public void handleSessionExpired(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
throws IOException {
// যখন সেশন টাইম আউট হবে, তখন ব্যবহারকারীকে লগইন পেজে রিডাইরেক্ট করা
response.sendRedirect("/login?sessionExpired=true");
}
}
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 {
private final CustomSessionExpiredHandler sessionExpiredHandler;
public SecurityConfig(CustomSessionExpiredHandler sessionExpiredHandler) {
this.sessionExpiredHandler = sessionExpiredHandler;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.invalidSessionUrl("/login?sessionExpired=true")
.and()
.exceptionHandling()
.authenticationEntryPoint(sessionExpiredHandler::handleSessionExpired)
.and()
.formLogin()
.permitAll();
}
}
Spring Security তে গ্লোবালি ব্যতিক্রম হ্যান্ডলিংয়ের জন্য @ControllerAdvice
ব্যবহার করা যেতে পারে। এটি পুরো অ্যাপ্লিকেশন জুড়ে ব্যতিক্রম হ্যান্ডলিং করার জন্য উপকারী।
import org.springframework.http.HttpStatus;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(AuthenticationException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public String handleAuthenticationException(AuthenticationException ex, Model model) {
model.addAttribute("error", "Invalid username or password");
return "login"; // Return to login page
}
@ExceptionHandler(AccessDeniedException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public String handleAccessDeniedException(AccessDeniedException ex, Model model) {
model.addAttribute("error", "You do not have permission to access this page");
return "access-denied"; // Return to access denied page
}
}
Spring Security তে Exception Handling একটি গুরুত্বপূর্ণ দিক, যা সিকিউরিটি সম্পর্কিত ব্যতিক্রমগুলিকে সঠিকভাবে হ্যান্ডল করতে সাহায্য করে। এটি ব্যবহারকারীর জন্য একটি সুসংহত এবং সুরক্ষিত অ্যাপ্লিকেশন অভিজ্ঞতা প্রদান করে। AuthenticationFailureHandler
, AccessDeniedHandler
, SessionAuthenticationException
, এবং গ্লোবাল @ControllerAdvice
ব্যতিক্রম হ্যান্ডলিং ব্যবহার করে আপনি Spring Security তে সিকিউরিটি সম্পর্কিত ত্রুটিগুলোকে কাস্টমাইজডভাবে হ্যান্ডল করতে পারবেন।
Spring Security তে Exception Handling একটি গুরুত্বপূর্ণ বিষয়, কারণ এটি সুরক্ষিত অ্যাপ্লিকেশন তৈরিতে সহায়তা করে। যখন ব্যবহারকারী অননুমোদিত অ্যাক্সেসের চেষ্টা করে বা কোনো ত্রুটি ঘটে, তখন সঠিকভাবে ত্রুটির বার্তা প্রদর্শন করা এবং ত্রুটির পরিস্থিতি হ্যান্ডেল করা খুবই গুরুত্বপূর্ণ। এটা শুধুমাত্র ব্যবহারকারীদের সঠিক নির্দেশনা প্রদান করে না, বরং সিস্টেমের নিরাপত্তাও নিশ্চিত করে।
ব্যবহারকারী যদি ভুল ইউজারনেম বা পাসওয়ার্ড প্রদান করে, তাহলে Authentication Failure Handler ব্যবহার করা হয়।
উদাহরণ:
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException {
// Custom failure message
response.sendRedirect("/login?error=true");
}
}
Explanation:
onAuthenticationFailure
: যদি লগইন ব্যর্থ হয়, তবে এটি কাস্টম বার্তা পাঠাবে বা ব্যবহারকারীকে অন্য পৃষ্ঠায় রিডাইরেক্ট করবে।যদি ব্যবহারকারী একটি রিসোর্সে অ্যাক্সেসের চেষ্টা করে যা সে অনুমোদিত নয়, তাহলে 403 Access Denied এর জন্য কাস্টম হ্যান্ডলার তৈরি করা যেতে পারে।
উদাহরণ:
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
// Custom error page or message
response.sendRedirect("/403");
}
}
Explanation:
handle
: ব্যবহারকারী যদি সঠিক অনুমোদন না পেয়ে কোনো রিসোর্স অ্যাক্সেস করতে চেষ্টা করে, তবে এটি একটি কাস্টম পৃষ্ঠা বা বার্তা প্রদর্শন করবে (যেমন, "403 Forbidden" পৃষ্ঠা)।Spring Security-তে Exception Handling কনফিগার করতে, আপনি HttpSecurity
কনফিগারেশনে failureHandler এবং accessDeniedHandler ব্যবহার করতে পারেন।
উদাহরণ:
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;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.access.AccessDeniedHandler;
@Configuration
public class SecurityConfig {
private final CustomAuthenticationFailureHandler authenticationFailureHandler;
private final CustomAccessDeniedHandler accessDeniedHandler;
public SecurityConfig(CustomAuthenticationFailureHandler authenticationFailureHandler, CustomAccessDeniedHandler accessDeniedHandler) {
this.authenticationFailureHandler = authenticationFailureHandler;
this.accessDeniedHandler = accessDeniedHandler;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable() // Disable CSRF for simplicity
.authorizeHttpRequests()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.failureHandler(authenticationFailureHandler) // Custom Failure Handler
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler); // Custom Access Denied Handler
return http.build();
}
}
Explanation:
failureHandler
: লগইন ব্যর্থ হলে কাস্টম হ্যান্ডলার ব্যবহার করা হচ্ছে।accessDeniedHandler
: যদি কোনো ব্যবহারকারী নির্দিষ্ট রিসোর্সে প্রবেশ করার চেষ্টা করে, যা তাদের অনুমোদিত নয়, তখন কাস্টম হ্যান্ডলার দ্বারা ত্রুটি প্রদর্শিত হবে।CSRF আক্রমণ প্রতিরোধ করতে, Spring Security CSRF টোকেনের ব্যবহার করে। যদি CSRF টোকেন মিসিং থাকে বা ভুল থাকে, তখন একটি 403 Forbidden
ত্রুটি ঘটবে। আপনি এই ত্রুটির জন্য একটি কাস্টম হ্যান্ডলার সেট করতে পারেন।
উদাহরণ:
import org.springframework.security.web.csrf.CsrfException;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomCsrfErrorHandler {
public void handleCsrfError(HttpServletRequest request, HttpServletResponse response, CsrfException exception) throws IOException {
// Custom CSRF error handling logic
response.sendRedirect("/csrf-error");
}
}
Spring-এ আপনি @ControllerAdvice অ্যানোটেশন ব্যবহার করে অ্যাপ্লিকেশন-wide Exception Handling করতে পারেন। এটি বিশেষভাবে কার্যকর যখন আপনি কাস্টম এক্সেপশন তৈরির মাধ্যমে গ্রহনযোগ্য ত্রুটি বার্তা পাঠাতে চান।
উদাহরণ:
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.http.ResponseEntity;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BadCredentialsException.class)
public ResponseEntity<String> handleBadCredentials(BadCredentialsException ex) {
return new ResponseEntity<>("Invalid username or password", HttpStatus.UNAUTHORIZED);
}
@ExceptionHandler(AccessDeniedException.class)
public ResponseEntity<String> handleAccessDenied(AccessDeniedException ex) {
return new ResponseEntity<>("You do not have permission to access this resource", HttpStatus.FORBIDDEN);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGlobalException(Exception ex) {
return new ResponseEntity<>("An unexpected error occurred", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Explanation:
@ExceptionHandler
: বিভিন্ন ধরণের Exception কাস্টম বার্তা সহ হ্যান্ডেল করা হয়েছে। উদাহরণস্বরূপ, BadCredentialsException
এর জন্য একটি কাস্টম বার্তা এবং AccessDeniedException
এর জন্য একটি আলাদা বার্তা প্রদর্শিত হবে।Spring Security তে Exception Handling ব্যবহার করে, আপনি সঠিকভাবে ত্রুটিগুলি পরিচালনা করতে পারেন এবং ব্যবহারকারীদের নিরাপদ অভিজ্ঞতা প্রদান করতে পারেন। Exception Handling এর মাধ্যমে:
Spring Security তে Exception Handling কনফিগার করার মাধ্যমে আপনি একটি নিরাপদ এবং ব্যবহারকারী-বান্ধব অ্যাপ্লিকেশন তৈরি করতে পারেন।
Spring Security তে AuthenticationFailureHandler এবং AccessDeniedHandler হল দুটি গুরুত্বপূর্ণ ইন্টারফেস, যা প্রমাণীকরণ ব্যর্থ হলে বা ব্যবহারকারী অনুমোদিত না হলে কাস্টম হ্যান্ডলিং করতে সাহায্য করে। এগুলি সাধারণত ব্যবহারকারীকে আরও ভাল ফলাফল এবং তথ্য প্রদান করার জন্য কাস্টমাইজ করা হয়।
AuthenticationFailureHandler হল একটি ইন্টারফেস যা AuthenticationException ফেলা হলে প্রক্রিয়া পরিচালনা করে। এটি সাধারণত লগইন প্রক্রিয়ার সময় ব্যবহার করা হয়, যেমন ব্যবহারকারী ভুল পাসওয়ার্ড বা ইউজারনেম প্রদান করলে।
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException {
// এখানে কাস্টম ফেইল মেসেজ প্রদর্শন করা যেতে পারে
String errorMessage = "Invalid username or password. Please try again.";
// ফেইল মেসেজ কাস্টম রিডিরেক্টে পাঠানো
request.setAttribute("error", errorMessage);
request.getRequestDispatcher("/login?error").forward(request, response);
}
}
ব্যাখ্যা:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login")
.failureHandler(customAuthenticationFailureHandler) // Custom Failure Handler
.permitAll();
}
}
AccessDeniedHandler হল একটি ইন্টারফেস যা ব্যবহারকারী যদি অনুমোদনপ্রাপ্ত না হন, যেমন তারা একটি সীমাবদ্ধ রিসোর্স অ্যাক্সেস করতে চায় তবে এটি ট্রিগার হয়। সাধারণত এটি 403 Forbidden এর জন্য কাস্টম হ্যান্ডলিং বা রিডিরেক্ট ব্যবহৃত হয়।
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException)
throws IOException, ServletException {
// কাস্টম ত্রুটি বার্তা ব্যবহারকারীকে প্রদর্শন করা
String errorMessage = "You do not have permission to access this page.";
// রিডিরেক্ট পেজে ত্রুটি বার্তা পাঠানো
request.setAttribute("error", errorMessage);
request.getRequestDispatcher("/access-denied").forward(request, response);
}
}
ব্যাখ্যা:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomAccessDeniedHandler customAccessDeniedHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN") // ADMIN রোল ছাড়া অ্যাক্সেস নিষিদ্ধ
.anyRequest().authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(customAccessDeniedHandler); // Custom Access Denied Handler
}
}
এখন আমরা পুরো প্রক্রিয়াটি একত্রিত করি: একটি কাস্টম AuthenticationFailureHandler এবং AccessDeniedHandler সহ Spring Security কনফিগারেশন।
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;
@Autowired
private CustomAccessDeniedHandler customAccessDeniedHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login")
.failureHandler(customAuthenticationFailureHandler) // Custom Authentication Failure Handler
.permitAll()
.and()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN") // ADMIN রোল ছাড়া অ্যাক্সেস নিষিদ্ধ
.anyRequest().authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(customAccessDeniedHandler) // Custom Access Denied Handler
.and()
.csrf().disable(); // CSRF Disabling (Optional)
}
}
Spring Security এ Custom Exception Handling একটি গুরুত্বপূর্ণ দিক, কারণ এটি ব্যবহারকারীকে সঠিক এবং পরিষ্কার ত্রুটি বার্তা প্রদান করতে সাহায্য করে যখন কিছু ভুল হয়। Spring Security ডিফল্টভাবে কিছু সাধারণ নিরাপত্তা ত্রুটি যেমন AuthenticationException এবং AccessDeniedException পরিচালনা করে, তবে আপনি আপনার প্রয়োজন অনুসারে কাস্টম ত্রুটি হ্যান্ডলিং যুক্ত করতে পারেন।
এখানে Custom Exception Handling কিভাবে করতে হয়, তার একটি উদাহরণ দেওয়া হলো:
Spring Security তে Custom Exception Handling এর জন্য আমরা নিম্নলিখিত স্টেপগুলো অনুসরণ করব:
প্রথমে, আমরা একটি কাস্টম AuthenticationException
তৈরি করি যা Spring Security তে Authentication সমস্যা হওয়ার সময় ব্যবহার হবে।
import org.springframework.security.core.AuthenticationException;
public class CustomAuthenticationException extends AuthenticationException {
public CustomAuthenticationException(String msg) {
super(msg);
}
public CustomAuthenticationException(String msg, Throwable cause) {
super(msg, cause);
}
}
CustomAuthenticationException
ক্লাসটি Spring Security এর AuthenticationException
এক্সটেন্ড করে তৈরি করা হয়েছে, যাতে আপনি যে কোনো কাস্টম মেসেজ বা অন্যান্য তথ্য রাখতে পারেন।এখন, আমরা একটি AuthenticationFailureHandler তৈরি করব, যাতে Authentication ব্যর্থ হলে কাস্টম এক্সসেপশন পরিচালিত হয়।
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException {
// কাস্টম মেসেজ বা লগিং করা যেতে পারে এখানে
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication failed: " + exception.getMessage());
}
}
onAuthenticationFailure
মেথডে Authentication ব্যর্থ হলে কাস্টম ত্রুটি বার্তা প্রদান করা হয়েছে। আপনি চাইলে আরও বিস্তারিত ত্রুটি বার্তা এবং লগিং যুক্ত করতে পারেন।এখন, Spring Security কনফিগারেশন ফাইলে আমাদের এই কাস্টম Failure Handler যুক্ত করতে হবে।
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 {
private final CustomAuthenticationFailureHandler customAuthenticationFailureHandler;
public SecurityConfig(CustomAuthenticationFailureHandler customAuthenticationFailureHandler) {
this.customAuthenticationFailureHandler = customAuthenticationFailureHandler;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login", "/register").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.failureHandler(customAuthenticationFailureHandler) // Custom Failure Handler
.permitAll()
.and()
.logout()
.permitAll();
}
}
এখানে failureHandler(customAuthenticationFailureHandler)
কল করে Spring Security কে জানানো হচ্ছে যে, যদি authentication ব্যর্থ হয়, তাহলে আমাদের কাস্টম failure handler কার্যকর হবে।
Spring Security তে যখন ব্যবহারকারী একটি সুরক্ষিত রিসোর্স অ্যাক্সেস করার চেষ্টা করে এবং সে অনুমোদিত না হয়, তখন AccessDeniedException ঘটে। আমরা কাস্টম AccessDeniedException হ্যান্ডলার ব্যবহার করে এই সমস্যাও সমাধান করতে পারি।
import org.springframework.security.web.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
// কাস্টম এক্সেস ডিনাইড বার্তা
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied: " + accessDeniedException.getMessage());
}
}
এখন, SecurityConfig এ আমাদের CustomAccessDeniedHandler যুক্ত করতে হবে।
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 {
private final CustomAccessDeniedHandler customAccessDeniedHandler;
public SecurityConfig(CustomAccessDeniedHandler customAccessDeniedHandler) {
this.customAccessDeniedHandler = customAccessDeniedHandler;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN") // Admin only endpoint
.anyRequest().authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(customAccessDeniedHandler) // Custom Access Denied Handler
.and()
.formLogin()
.permitAll()
.and()
.logout()
.permitAll();
}
}
এখানে accessDeniedHandler(customAccessDeniedHandler)
ব্যবহার করে AccessDeniedException হলে আমাদের কাস্টম হ্যান্ডলার ব্যবহৃত হবে।
Spring MVC তে আপনি কাস্টম Exception Handler ব্যবহার করতে পারেন। যদি আপনি কিছু কাস্টম exception হ্যান্ডলিং করতে চান, তবে @ControllerAdvice ব্যবহার করতে পারেন।
import org.springframework.http.HttpStatus;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(CustomAuthenticationException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public String handleCustomAuthenticationException(CustomAuthenticationException e, Model model) {
model.addAttribute("error", e.getMessage());
return "error"; // Return a custom error page
}
}
এখানে @ExceptionHandler ব্যবহার করা হয়েছে কাস্টম exception হ্যান্ডল করার জন্য। এটি CustomAuthenticationException সনাক্ত করলে handleCustomAuthenticationException মেথডটি কল হবে এবং একটি কাস্টম error page রিটার্ন করবে।
Spring Security তে কাস্টম exception handling ব্যবহার করলে আপনি সিস্টেমের নিরাপত্তা এবং ব্যবহারকারীর অভিজ্ঞতাকে উন্নত করতে পারেন। আপনি AuthenticationException, AccessDeniedException এবং অন্যান্য exception গুলি কাস্টমাইজ করে ব্যবহারকারীদের আরও পরিষ্কার এবং কাস্টম ত্রুটি বার্তা প্রদান করতে পারেন। Spring Security তে এই কাস্টম হ্যান্ডলিং কনফিগারেশন খুব সহজেই করা যায় এবং এটি নিরাপত্তা এবং ব্যবহারের সুবিধা বাড়াতে সাহায্য করে।
Read more