异步请求权限充足时,没有问题,但是当权限不足时,ajax请求之后,就要进入权限不足的界面,但是ajax又不支持整页刷新,所以就要对框架进行修整.
1,添加自定义shiro过滤器,对ajax请求进行过滤
public class RoleAUthorizationFilter extends AuthorizationFilter {
@Override
protected boolean onAccessDenied(ServletRequest request,
ServletResponse response) throws IOException {
Subject subject = getSubject(request, response);
Message message = new Message();
if (subject.getPrincipal() == null) {
if (MyWebUtils.isAjax(request)) {
message.setMessage( "您还未登录,请登录系统");
MyWebUtils.out(response,message);
} else {
saveRequestAndRedirectToLogin(request, response);
}
} else {
if (MyWebUtils.isAjax(request)) {
message.setFlag(2);
message.setMessage("此账户没有权限,请联系管理员");
MyWebUtils.out(response, message);
} else {
String unauthorizedUrl = getUnauthorizedUrl();
if (StringUtils.hasText(unauthorizedUrl)) {
WebUtils.issueRedirect(request, response, unauthorizedUrl);
} else {
WebUtils.toHttp(response).sendError(401);
}
}
}
return false;
}
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception {
Subject subject = getSubject(request, response);
String[] rolesArray = (String[]) mappedValue;
if (rolesArray == null || rolesArray.length == 0) {
// no roles specified, sonothing to check - allow access.
return true;
}
Set<String> roles = CollectionUtils.asSet(rolesArray);
for (String role : roles) {
if (subject.hasRole(role)) {
return true;
}
}
return false;
}
}
查看原码发现 , AuthorizationFilter 是个抽象类 , 它继承了 AccessControlFilter 这个抽象类 , 实现了里面的 onAccessDenied 方法 , 这个方法是校验不通过之后的处理 , 我们要修改 , 就自定义一个过滤器 , 继承 AuthorizationFilter, 重写 isAccessAllowed( 校验通过的方法 ) 和 onAccessDenied 方法 , 把对 ajax 请求的判断加在校验不通过的处理方法中 .2, 定义好自定义过滤器之后,在shiro.xml中添加权限
<bean id="shiroFilter"class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login"/>
<property name="successUrl" value="/userLogin" />
<property name="unauthorizedUrl" value="/unanthorized" />
<property name="filters">
<map>
<entry key="role">
<bean class="com.snowlink.filter.RoleAUthorizationFilter"/>
</entry>
</map>
</property>
<!-- 基本系统级别权限配置 -->
<property name="filterChainDefinitions">
<value>
/css/* = anon
/js/* = anon
/img/* = anon
/plugins/* = anon
/jsp/login.jsp = anon
/userLogin = anon <!-- 登录相关不拦截 -->
/InsertUser = authc,roles[admin]
/deleteUser = authc,role[admin]
/logOut = authc
/** = authc
</value>
</property>
</bean>
注意黄色标记的,定义的entry里的key要和下面的过滤器名称相同,不然自定义过滤器就不会执行3,另外还有一点遇到的问题
@RequiresRoles("admin")
@RequestMapping("deleteUser")
public void deleteUser(HttpServletResponse response,User user) {
response.setCharacterEncoding("UTF-8");
int result = userService.deleteUser(user);
Message message = new Message();
if(result == 1){
message.setFlag(1);
message.setMessage(Answer.OK);
}else {
message.setFlag(0);
message.setMessage(Answer.ERROR);
}
try {
response.getWriter().print(JSONObject.toJSON(message));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
在ajax请求返回数据时,不能用@ResponseBody标签返回对象,必须要用response.getWriter().print()响应给js,不然就会出现后台逻辑实现完成了,但是ajax进不了success,就会出现404