上一篇文章:Spring Boot 整合Shiro实现登陆认证和权限控制,我们对shiro进行了整合。这一次我们具体来讲一下shiro中的拦截器。
Shiro在处理非法请求比如没有通过登录认证的请求,他会直接帮你跳转到登录页面,或者访问没有权限的页面他会给你返回403页面。然而在我的项目中,会使用ajax去请求,然而却在认证失败或者没有权限的时候不能返回对应的信息。
接下来我们要为我们的项目中添加权限验证失败的过滤器:
package com.ciyou.edu.filter
import com.ciyou.edu.utils.JSONUtil
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import javax.servlet.ServletRequest
import javax.servlet.ServletResponse
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
/**
* 权限验证失败的过滤器
*/
class ShiroPermissionsFilter extends PermissionsAuthorizationFilter {
private static final Logger logger = LoggerFactory.getLogger(ShiroPermissionsFilter.class)
/**
* shiro认证perms资源失败后回调方法
* @param servletRequest
* @param servletResponse
* @return
* @throws IOException
*/
@Override
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
logger.info("----------权限控制-------------")
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse
String header = httpServletRequest.getHeader("X-Requested-With")
boolean isAjax = "XMLHttpRequest" == header
if (isAjax) {//如果是ajax返回指定格式数据
logger.info("----------AJAX请求拒绝-------------")
httpServletResponse.setCharacterEncoding("UTF-8")
httpServletResponse.setContentType("application/json")
//返回禁止访问json字符串
httpServletResponse.getWriter().write(JSONUtil.returnForbiddenResult())
} else {//如果是普通请求进行重定向
logger.info("----------普通请求拒绝-------------")
httpServletResponse.sendRedirect("/403")
}
return false
}
}
上述代码,区分普通请求和ajax请求,并且对于ajax请求返回相应的json信息。
通过我们自己创建的JSONUtil返回特定的json字符串,整个项目返回的json都是用JSONUtil进行构造返回。
package com.ciyou.edu.utils
import net.sf.json.JSONObject
import org.slf4j.Logger
import org.slf4j.LoggerFactory
class JSONUtil {
private static final Logger logger = LoggerFactory.getLogger(JSONUtil.class)
static String returnJSONResult(boolean success, String state ,String message,Object entity){
Map map = new HashMap()
map?.put("isSuccess",success)
map?.put("stateCode",state)
map?.put("message",message)
map?.put("entity",entity)
logger.info("返回JSON字符串:" + JSONObject.fromObject(map)?.toString())
return JSONObject.fromObject(map)?.toString()
}
/**
* 设置失败消息JSON字符串
* @param message
* @return
*/
static String returnFailReuslt(String message){
return returnJSONResult(false, "200" ,message,null)
}
/**
* 设置返回实体JSON字符串
* @param entity
* @return
*/
static String returnEntityReuslt(Object entity){
return returnJSONResult(true, "200" ,null,entity)
}
/**
* 设置403权限不足JSON字符串
* @return
*/
static String returnForbiddenResult(){
return returnJSONResult(false, "403" ,"权限不足!! 禁止访问!!",null)
}
/**
* 返回成功消息JSON字符串
* @param message
* @return
*/
static String returnSuccessResult(String message){
return returnJSONResult(true, "200" ,message,null)
}
}
接下来我们需要在配置类中配置过滤器
最后,感谢几位作者的文章解惑:
Shiro和AJAX完美整合
Spring boot集成shiro使用Ajax方式,最详细教程