
前言
现在做项目,大多都是前后端分离;权限控制都是在后台实现,前端使用ajax调用后台接口。
但是ajax对接口返回的重定向是没发处理的,会出现异常(具体错误是哪个一时想不起来了);当shiro发现失效后的session时通常会将该请求重定向到loginUrl,或者是用户访问的某个资源权限不足时(会重定向到unAuthorizedUrl),这时Ajax请求基本都是出错的。
解决方案
修改重定向302为正常返回200
shiro默认实现了一些filter,使用不同的filter处理对应的权限拦截:
/** * Enum representing all of the default Shiro Filter instances available to web applications. Each filter instance is * typically accessible in configuration the {@link #name() name} of the enum constant. * * @since 1.0 */public enum DefaultFilter { anon(AnonymousFilter.class), authc(FormAuthenticationFilter.class), authcBasic(BasicHttpAuthenticationFilter.class), logout(LogoutFilter.class), noSessionCreation(NoSessionCreationFilter.class), perms(PermissionsAuthorizationFilter.class), port(PortFilter.class), rest(HttpMethodPermissionFilter.class), roles(RolesAuthorizationFilter.class), ssl(SslFilter.class), user(UserFilter.class);
当用户没有登录或session失效后,是使用FormAuthenticationFilter进行拦截处理的,我们可以重写里面的onAccessDenied方法,从而修改重定向。
public class ShiroFormAuthenticationFilter extends FormAuthenticationFilter {
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
if (isLoginRequest(request, response)) {
if (isLoginSubmission(request, response)) {
if (log.isTraceEnabled()) {
log.trace("Login submission detected. Attempting to execute login.");
}
return executeLogin(request, response);
} else {
if (log.isTraceEnabled()) {
log.trace("Login page view.");
}
//allow them to see the login page ;)
return true;
}
} else {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse) response;
if(req.getMethod().equals(RequestMethod.OPTIONS.name())) {
resp.setStatus(HttpStatus.OK.value());
return true;
}
if (log.isTraceEnabled()) {
log.trace("Attempting to access a path which requires authentication. Forwarding to the " +
"Authentication url [" + getLoginUrl() + "]");
}
//前端Ajax请求时requestHeader里面带一些参数,用于判断是否是前端的请求
String ajaxHeader = req.getHeader(ShiroConstant.USERID);
if (ajaxHeader != null || req.getHeader("xx") != null) {
//前端Ajax请求,则不会重定向
resp.setHeader("Access-Control-Allow-Origin