Spring Security自定义AccessDeniedException的处理器

AccessDeniedException指用户访问接口或其他资源时,权限不足引起的异常。本文介绍如何在Spring Security下对AccessDeniedException异常进行个性化的处理。

1.自定义AccessDeniedHandler处理类

import com.alibaba.fastjson.JSONObject;
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;
import java.io.PrintWriter;

/**
 * 注意:未登录状态下无法触发这个Handler
 * @author craigezhong
 * @Date 2021/6/19 19:41
 */
@Component("customAccessDeniedHandler")
public class CustomAccessDeniedHandler implements AccessDeniedHandler{
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        httpServletResponse.setStatus(HttpStatus.OK.value());
        //设置格式以及返回json数据 方便前台使用reponseJSON接取
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.setContentType("application/json; charset=utf-8");
        PrintWriter out = httpServletResponse.getWriter();
        JSONObject json = new JSONObject();
        json.put("40003", "权限不足,请联系管理员");
        out.append(json.toString());
    }
}

2.自定义AuthenticationEntryPoint处理类

import com.alibaba.fastjson.JSONObject;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author craigezhong
 * @Date 2021/6/21 14:27
 */
@Component("customAuthenticationEntryPoint")
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        response.setStatus(HttpStatus.OK.value());
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        JSONObject json = new JSONObject();
        json.put("40003", "权限不足,请联系管理员");
        out.append(json.toString());
    }
}

3.在WebSecurityConfigurerAdapter添加异常处理配置

/**
     * notice: The AccessDeniedHandler only applies to authenticated users.
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                //配置权限校验
                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O o) {
                        o.setSecurityMetadataSource(customMetadataSource);
                        o.setAccessDecisionManager(urlAccessDecisionManager);
                        return o;
                    }
                })
                .antMatchers("/**", "/get/code", "/authentication/require", "/*.html", "/code/*", "/oauth/*", "/team/**").permitAll()
                .anyRequest()
                .authenticated()
                // 基于表单登录
                .and().formLogin()
                // 请求登录时跳转的页面
                .loginPage(SecurityConstants.DEFAULT_UNAUTHENTICATION_URL)
                // 登录的请求url
                .loginProcessingUrl(SecurityConstants.DEFAULT_LOGIN_PROCESSING_URL_FORM)
                //登录成功或失败以后的处理url
                .successHandler(myAuthenticationSuccessHandler)
                .failureHandler(myAuthenticationFailureHandler)
                // 退出登录
                .and().logout()
                .logoutUrl(SecurityConstants.DEFAULT_LOGINOUT_PROCESSING_URL_FORM)
                .logoutSuccessHandler(myLogoutSuccessHandler);

        //异常处理
          http.exceptionHandling().authenticationEntryPoint(customAuthenticationEntryPoint).accessDeniedHandler(customAccessDeniedHandler);
        //增加前置校验器 验证码、token
        http.addFilterBefore(validateCodeFilter, AbstractPreAuthenticatedProcessingFilter.class);
        http.addFilterBefore(checkTokenFilter, AbstractPreAuthenticatedProcessingFilter.class);
    }

主要是下面这句:http.exceptionHandling().authenticationEntryPoint(customAuthenticationEntryPoint).accessDeniedHandler(customAccessDeniedHandler);

4.注意事项

ExceptionTranslationFilter catch到AccessDeniedException后,分为两种情况:

  • 如果用户处于未登录(anonymous)状态,会先触发AuthenticationEntryPoint,如果没有配置,则会重定向至登录页;
  • 如果用户处于登陆(authenticated)状态,会触发AccessDeniedHandler。

具体参考:ExceptionTranslationFilter
所以,最好将AuthenticationEntryPoint和AccessDeniedHandler都配置上。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自定义Spring Security中的403错误页面,可以按照以下步骤进行操作: 1. 创建一个403.html页面,用于显示自定义错误信息。 2. 创建一个自定义AccessDeniedHandler类,用于处理访问被拒绝的情况。 3. 在Spring Security配置文件中配置AccessDeniedHandler,指定使用自定义AccessDeniedHandler处理访问被拒绝的情况。 以下是一个简单的示例代码: 1. 创建403.html页面 ``` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Access Denied</title> </head> <body> <h1>Access Denied</h1> <p>You are not authorized to access this resource.</p> </body> </html> ``` 2. 创建自定义AccessDeniedHandler类 ``` @Component public class CustomAccessDeniedHandler implements AccessDeniedHandler { @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException { response.sendRedirect("/403.html"); } } ``` 3. 在Spring Security配置文件中配置AccessDeniedHandler ``` @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomAccessDeniedHandler accessDeniedHandler; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin() .and() .exceptionHandling().accessDeniedHandler(accessDeniedHandler); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user").password("password").roles("USER") .and() .withUser("admin").password("password").roles("USER", "ADMIN"); } } ``` 以上代码中,CustomAccessDeniedHandler类是自定义AccessDeniedHandler实现类,它在处理访问被拒绝的情况时,通过重定向到403.html页面来显示自定义错误信息。在SecurityConfig配置类中,通过exceptionHandling().accessDeniedHandler(accessDeniedHandler)方法来指定使用自定义AccessDeniedHandler处理访问被拒绝的情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值