在使用shiro过程中,发现shiro对没有权限的处理都是跳转到配置文件中的unauthorizedUrl。如果是ajax类的请求,需要返回json时,就需要自定义filter并重写onAccessDenied方法。
比如需要在验证用户权限时返回json,就需要自定义roles的filter。
public class MyRolesFilter extends RolesAuthorizationFilter {
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response)
throws IOException {
Subject subject = getSubject(request, response);
// If the subject isn't identified, redirect to login URL
if (subject.getPrincipal() == null) {
saveRequestAndRedirectToLogin(request, response);
} else {
// If subject is known but not authorized, redirect to the
// unauthorized URL if there is one
// If no unauthorized URL is specified, just return an unauthorized
// HTTP status code
String unauthorizedUrl = getUnauthorizedUrl();
String ajaxHeader = ((HttpServletRequest)request).getHeader("X-Requested-With");
if (ajaxHeader != null && "XMLHttpRequest".equals(ajaxHeader)) {
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().write("{\"msg\":\"没有权限\"}");
response.flushBuffer();
}
// SHIRO-142 - ensure that redirect _or_ error code occurs - both
// cannot happen due to response commit:
else if (StringUtils.hasText(unauthorizedUrl)) {
WebUtils.issueRedirect(request, response, unauthorizedUrl);
}
else {
WebUtils.toHttp(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
}
return false;
}
}
这个方法直接复制org.apache.shiro.web.filter.authz.AuthorizationFilter的onAccessDenied方法,黄色部分是自己添加的。思路就是在原来的判断方法前加上对ajax请求的判断,如果是ajax请求,返回json,如果不是,还是走默认的返回方式。