Shiro和AJAX完美整合
这是我第一次认认真真写博客,以前为了图快,结果写下来基本只有自己可以看懂。不过我感觉有经验就应该要和别人分享下,在分享的同时或许可以为这个问题找到更好的解决方案。 我在上学期5月份学完了Shiro,当初学时,看了半天的英文文档,最后还是不知道它为什么要这么干,只知道很多人说它很方便。在今年9月初时,我在次使用它,这次终于知道它的内部原理,但是感觉它的处理方式和我的上一个项目很相似。 这个为了实现远程服务器管理平台,我用上了Shiro,不过给我的第一个感觉是为什么它老是不按照我的业务方式来。最主要的是它在处理非法请求时,不是返回错误的字符串,而是直接跳转到登入界面,这个对于使用ajax来说简直是个噩耗。针对这个问题网上也有很多解决方案,我记得最清楚的是有一个人他把登入的地址改成json字符串,对于这个方案,我只能说不够灵活。算了,不说那么多了,直接说我的解决方案。 Shiro最主要的是拦截器,所以我们只要重写个拦截器就可以达到我们的目的,不管是直接请求还是ajax请求都可以直接处理。shiro处理拦截的类主要是FormAuthenticationFilter,所以我们对里面相应的方法进行重写即可。
/**
*/ package com.wms.studio.filter;
import java.io.IOException; import java.io.PrintWriter;
import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.subject.Subject; import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory;
/**
@author WMS
*/ public class CaptchaFormAuthenticationFilter extends FormAuthenticationFilter {
private static final Logger log = LoggerFactory
.getLogger(CaptchaFormAuthenticationFilter.class);
/*
*主要是针对登入成功的处理方法。对于请求头是AJAX的之间返回JSON字符串。
*/
@Override
protected boolean onLoginSuccess(AuthenticationToken token,Subject subject,ServletRequest request,ServletResponse response)
throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
if (!"XMLHttpRequest".equalsIgnoreCase(httpServletRequest
.getHeader("X-Requested-With"))) {// 不是ajax请求
issueSuccessRedirect(request,response);
} else {
httpServletResponse.setCharacterEncoding("UTF-8");
PrintWriter out = httpServletResponse.getWriter();
out.println("{success:true,message:'登入成功'}");
out.flush();
out.close();
}
return false;
}
/**
* 主要是处理登入失败的方法
*/
@Override
protected boolean onLoginFailure(AuthenticationToken token,AuthenticationException e,ServletResponse response) {
if (!"XMLHttpRequest".equalsIgnoreCase(((HttpServletRequest) request)
.getHeader("X-Requested-With"))) {// 不是ajax请求
setFailureAttribute(request,e);
return true;
}
try {
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
String message = e.getClass().getSimpleName();
if ("IncorrectCredentialsException".equals(message)) {
out.println("{success:false,message:'密码错误'}");
} else if ("UnknownAccountException".equals(message)) {
out.println("{success:false,message:'账号不存在'}");
} else if ("LockedAccountException".equals(message)) {
out.println("{success:false,message:'账号被锁定'}");
} else {
out.println("{success:false,message:'未知错误'}");
}
out.flush();
out.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return false;
}
/**
* 所有请求都会经过的方法。
*/
@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.");
}
if ("XMLHttpRequest"
.equalsIgnoreCase(((HttpServletRequest) request)
.getHeader("X-Requested-With"))) {// 不是ajax请求
String vcode = request.getParameter("vcode");
HttpServletRequest httpservletrequest = (HttpServletRequest) request;
String vvcode = (String) httpservletrequest
.getSession()
.getAttribute(
com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
if (vvcode == null || "".equals(vvcode)
|| !vvcode.equals(vcode)) {
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.println("{success:false,message:'验证码错误'}");
out.flush();
out.close();
return false;
}
}
return executeLogin(request,response);
} else {
if (log.isTraceEnabled()) {
log.trace("Login page view.");
}
// allow them to see the login page ;)
return true;
}
} else {
if (log.isTraceEnabled()) {
log.trace("Attempting to access a path which requires authentication. Forwarding to the "
+ "Authentication url [" + getLoginUrl() + "]");
}
if (!"XMLHttpRequest"
.equalsIgnoreCase(((HttpServletRequest) request)
.getHeader("X-Requested-With"))) {// 不是ajax请求
saveRequestAndRedirectToLogin(request,response);
} else {
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.println("{message:'login'}");
out.flush();
out.close();
}
return false;
}
}
}
然后还需要告诉拦截器,你定义了这个拦截。
/extjs/** = anon
/js/userservice.js= anon
/resources/**=anon
/kaptcha.jpg=anon
/**=authc
这样基本就可以实现完美整合了。。。。。。。。。 看看我的效果图
总结
以上是编程之家为你收集整理的Shiro和AJAX完美整合全部内容,希望文章能够帮你解决Shiro和AJAX完美整合所遇到的程序开发问题。
如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。