加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Shiro和AJAX完美整合

发布时间:2020-12-15 22:00:35 所属栏目:百科 来源:网络整理
导读:Shiro和AJAX完美整合 这是我第一次认认真真写博客,以前为了图快,结果写下来基本只有自己可以看懂。不过我感觉有经验就应该要和别人分享下,在分享的同时或许可以为这个问题找到更好的解决方案。 我在上学期5月份学完了Shiro,当初学时,看了半天的英文文档

Shiro和AJAX完美整合

  这是我第一次认认真真写博客,以前为了图快,结果写下来基本只有自己可以看懂。不过我感觉有经验就应该要和别人分享下,在分享的同时或许可以为这个问题找到更好的解决方案。   我在上学期5月份学完了Shiro,当初学时,看了半天的英文文档,最后还是不知道它为什么要这么干,只知道很多人说它很方便。在今年9月初时,我在次使用它,这次终于知道它的内部原理,但是感觉它的处理方式和我的上一个项目很相似。   这个为了实现远程服务器管理平台,我用上了Shiro,不过给我的第一个感觉是为什么它老是不按照我的业务方式来。最主要的是它在处理非法请求时,不是返回错误的字符串,而是直接跳转到登入界面,这个对于使用ajax来说简直是个噩耗。针对这个问题网上也有很多解决方案,我记得最清楚的是有一个人他把登入的地址改成json字符串,对于这个方案,我只能说不够灵活。算了,不说那么多了,直接说我的解决方案。   Shiro最主要的是拦截器,所以我们只要重写个拦截器就可以达到我们的目的,不管是直接请求还是ajax请求都可以直接处理。shiro处理拦截的类主要是FormAuthenticationFilter,所以我们对里面相应的方法进行重写即可。

<!-- lang: java -->
/**

*/ 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;
	}
}

}

然后还需要告诉拦截器,你定义了这个拦截。

<!-- lang: xml -->
<!-- Shiro Filter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
	<property name="securityManager" ref="securityManager" />
	<property name="loginUrl" value="/login.jsp" />
	<!-- <property name="successUrl" value="/" /> -->
	<property name="filters">
		<map>
			<entry key="authc">
				<bean class="com.wms.studio.filter.CaptchaFormAuthenticationFilter"></bean>
			</entry>
		</map>
	</property>
	<property name="filterChainDefinitions">
		<value>
			/extjs/** = anon
			/js/userservice.js= anon
			/resources/**=anon
			/kaptcha.jpg=anon
			/**=authc
		</value>
	</property>
</bean>

这样基本就可以实现完美整合了。。。。。。。。。 看看我的效果图

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读