有两种情况:
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页面
这样就完美解决了登陆后无访问权限跳转的问题。