AccessDeniedException如何处理

本文介绍Spring Security中处理用户未登录及已登录状态下访问受保护资源的两种情况,并提供了解决方案,包括配置登录页面和403错误页面,以及自定义拒绝访问处理器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有两种情况:

1.用户未登录情况下访问受保护资源

2.用户登录情况下访问被保护资源

一、用户未登录情况下访问受保护资源

用户在未登录的情况下访问受保护资源时会自动跳转到配置的登录页面。主要是以下这个配置起作用:

<security:http auto-config="false" access-decision-manager-ref="accessDecisionManager"
               use-expressions="true" entry-point-ref="loginEntryPoint">

 <bean id="loginEntryPoint"
    class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <!-- 默认登录页的url -->
    <constructor-arg value="/login?error=login"/>
</bean>

</security:http>

但是这里说的访问路径不包含ajax请求的访问,如果是ajax请求的话,你会看到后台报AccessDeniedException异常,而前台没反应。因为对ajax请求不起作用

此时你可以这样来解决,在发送ajax请求的页面判断用户是否为空,为空则直接跳转到登录页面,如下:

 var res = '${user.id}';
    if(res=='' || res==null){
        window.location.href = "/login.jsp";
    }
    $.ajax({
    ...
});
}

登录情况下的ajax请求我们下面介绍

二、用户在登录情况下访问受保护资源

用户在登录情况下访问受保护资源时,可以有两种解决方案:

1.配置403错误页面(有瑕疵)

因为我们知道访问受保护资源时会返回403错误码,我们可以直接配置403错误页面

在web.xml中配置错误页面:

<error-page>
    <error-code>403</error-code>
    <location>/WEB-INF/403.jsp</location>
</error-page>

在/WEB-INF/下引入403.jsp即可

此时访问受保护资源时会直接跳转到我们配置的403错误页面

但是问题又来了,ajax请求访问受保护资源时同样没有反应,且看下面的解决办法

2.自定义MyAccessDeniedHandler拒绝访问处理器(完美)

1.新建MyAccessDeniedHandler并实现AccessDeniedHandler接口:

public class MyAccessDeniedHandler implements AccessDeniedHandler{
private String errorPage;
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {
    String header = request.getHeader( "X-Requested-With" );
    if (header != null && "XMLHttpRequest".equals( header )) {
        //ajax请求
        String jsonObject = "{\"access-denied\":true}";
        PrintWriter out = response.getWriter();
        out.print( jsonObject );
        out.flush();
        out.close();
        return;
    } else {
        RequestDispatcher dispatcher = request.getRequestDispatcher( errorPage );
        dispatcher.forward( request, response );
    }
}

public void setErrorPage(String errorPage) {
    if(errorPage != null && !errorPage.startsWith("/")) {
        throw new IllegalArgumentException("errorPage must begin with '/'");
    } else {
        this.errorPage = errorPage;
    }
}
}

(1)通过setter方法获取配置文件中配置的错误页面

(2)根据请求头信息判断该请求是不是ajax请求

(3)如果是ajax请求,则返回json格式数据{access-denied:true}

(4)如果不是ajax请求则将请求转发到配置的错误页面

2.spring-security.xml配置自定义的AccessDeniedHandler:

<security:access-denied-handler ref="accessDeniedHandler"/>
<bean id="accessDeniedHandler" class="wang.dreamland.www.security.MyAccessDeniedHandler">
    <property name="errorPage" value="/accessDenied.jsp"></property>
</bean>

3.在webapp目录下新建accessDenied.jsp文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>无访问权限</title>
</head>
<body>
<span style="color: red">无访问权限</span>
</body>
</html>

4.在发ajax请求的页面做下判断:

 $.ajax({
        type:'post',
        url:'/list',
        dataType:'json',
        success:function(data){
            var noAccess = data["access-denied"]
            if(noAccess){
                window.location.href = "${ctx}/accessDenied.jsp";
                return
            }
        ...
    }
    });

如果noAccess=true则跳转到accessDenied.jsp页面

这样就完美解决了登陆后无访问权限跳转的问题。

更多博客内容详见我的博客 Wang's Blog

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坏菠萝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值