自定义shiro实现识别ajax请求的拒绝返回json,还是普通返回页面
类似其他的自定义只要重写过滤器中相应的方法即可:
客户端请求标志:
String contentType = httpServletRequest.getHeader("content-type");
application/json : JSON数据格式(ajax)
application/x-www-form-urlencoded :表单提交
null 浏览器直接请求
没有登录,正在登陆时每次进入登录过滤器
这时ajax请求用json格式返回失败即可(就不是返回整个失败页面),登录成功才可以请求正常请求json
登录后每次请求进入角色过等滤器
ajxa请求,json没有权限处理角色中处理json没有权限的返回即可(就不是整个页面返回),一般的请求返回登录页面也即可
FormAuthenticationFilter:MyAuthenticationFilter
进入onAccessDenied(区分ajax和普通请求,控制跳转返回格式)就已经是拒绝了,这里做拒绝后的处理,或者首次登陆的处理
onLoginSuccess登录成功之后(登录之后跳转到loginurl),做的事情(setsession)
onLoginFailure:处理登录失败后的处理(ajax请求返回json格式(里面带有自定义拒绝标志信息,和错误代码),普通请求返回拒绝页面)
AuthorizationFilter: RoleAuthorizationFilter
isAccessAllowed(定义判断是否有权限的规则)
判断角色是否具备访问要求
onAccessDenied
角色不具备的时候做的处理(ajax请求返回json格式(里面带有自定义拒绝标志信息,和错误代码),普通请求返回拒绝页面)
这两个未成功的时候都不会清除登录信息,才满足这两种情况:
1,拒绝就跳登录页面(见到的菜单都是自己有权限的情况下可以),unauthorizedUrl:没有权限默认跳转的页面。
2,当要求全部显示菜单,没有权限的菜单
就跳到提示页就提示,其他正常访问(并没有清除用户登录信息)就不能简单跳到登陆页
AuthorizationFilter(已登录):
FormAuthenticationFilter(要登录):
当需要没有权限就登出的时候在onAccessDenied中调用LogoutFilter清除登录信息
FormAuthenticationFilter:MyAuthenticationFilter
@Override
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//String requestType = request.getHeader("X-Requested-With");
String requestType = (request .getHeader("X-Requested-With")==null?request .getHeader("x-requested-with"):null);
String contentType = request.getHeader("content-type");
request.getHeaderNames();
if ((requestType != null && requestType.equalsIgnoreCase("XMLHttpRequest"))||(contentType!=null && contentType.equalsIgnoreCase("application/json; charset=utf-8"))) {
response.addHeader("loginStatus", "accessDenied");
response.sendError(HttpServletResponse.SC_FORBIDDEN);//403
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
//HttpServletResponse rs=new HttpServletResponse();
//response.
//ServletServerHttpResponse responseHeader = new ServletServerHttpResponse(rs);
//responseHeader.getHeaders().add("loginStatus", "accessDenied");
//response.getWriter().write(JSONObject.toJSONString(responseHeader));
return false;
}
//if ((requestType != null && requestType.equalsIgnoreCase("XMLHttpRequest"))) {
//
//response.addHeader("loginStatus", "accessDenied");
//response.sendError(HttpServletResponse.SC_FORBIDDEN);//403
//response.setCharacterEncoding("UTF-8");
//response.setContentType("application/json");
////HttpServletResponse rs=new HttpServletResponse();
////response.
////ServletServerHttpResponse responseHeader = new ServletServerHttpResponse(rs);
////responseHeader.getHeaders().add("loginStatus", "accessDenied");
////response.getWriter().write(JSONObject.toJSONString(responseHeader));
//return false;
//}
String method = request.getMethod();
if("GET".equalsIgnoreCase(method)){
WebUtils.issueRedirect(request, response, "/");
return false;
}
return super.onAccessDenied(request, response);
}
AuthorizationFilter: RoleAuthorizationFilter
这两个的onAccessDenied都应如此写
@Override
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
//String requestType = httpServletRequest.getHeader("X-Requested-With");
String requestType = (httpServletRequest.getHeader("X-Requested-With")==null?httpServletRequest.getHeader("x-requested-with"):null);
String contentType = httpServletRequest.getHeader("content-type");
if ((requestType != null && requestType.equalsIgnoreCase("XMLHttpRequest"))||(contentType!=null && contentType.equalsIgnoreCase("application/json; charset=utf-8"))) {
httpServletResponse.addHeader("loginStatus", "accessDenied");
httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);//403
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("application/json");
//HttpServletResponse rs=new HttpServletResponse();
//response.
//ServletServerHttpResponse responseHeader = new ServletServerHttpResponse(rs);
//responseHeader.getHeaders().add("loginStatus", "accessDenied");
//response.getWriter().write(JSONObject.toJSONString(responseHeader));
return false;
} else {//如果是普通请求进行重定向
httpServletResponse.sendRedirect("/");
}
return false;
}
注意
MyAuthenticationFilter中onLoginSuccess中的session.stop();需要注掉,否则用框架的登陆走了onLoginSuccess然后又清了session会报错
参考:
http://blog.csdn.net/u014042146/article/details/72834582
http://blog.csdn.net/qq_20989105/article/details/78075660?locationNum=9&fps=1