首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

spring security3.1 兑现验证码自定义登录

2012-09-19 
spring security3.1 实现验证码自定义登录spring security 自定义登录:1、自定义表结构T_USER:(用户表)`id`

spring security3.1 实现验证码自定义登录

spring security 自定义登录:

1、自定义表结构

T_USER:(用户表)

`id` bigint(11) NOT NULL AUTO_INCREMENT,

`name` varchar,

`password` varchar

?

T_ROLE:(角色表)

`id` bigint(11) NOT NULL AUTO_INCREMENT,

`role` varchar--角色名(spring security定义角色名以ROLE_开头)

?

T_USER_ROLE:(用户角色关联表)

`id` bigint(11) NOT NULL AUTO_INCREMENT,

`user_id` bigint(11),

`role_id` bigint(11)

?

2、需要的jar包:

spring-security-acl-3.1.0.RC2.jar

spring-security-aspects-3.1.0.RC2.jar

spring-security-cas-3.1.0.RC2.jar

spring-security-config-3.1.0.RC2.jar

spring-security-core-3.1.0.RC2.jar

spring-security-ldap-3.1.0.RC2.jar

spring-security-openid-3.1.0.RC2.jar

spring-security-taglibs-3.1.0.RC2.jar

spring-security-web-3.1.0.RC2.jar

?

3、登录页面login.jsp

<form id="loginForm"    action="<c:url value='/j_spring_security_check'/>" method="post">    <table width="100%" border="0" cellspacing="0" cellpadding="0">     <tr>      <th>用户名:</th>      <td><input type="text" name="j_username" id="username"       />      </td>      <td rowspan="3"><a onclick="javascript:login();"><img        src="../img/home/login_btn.gif" width="111" height="99" /> </a></td>     </tr>     <tr>      <th>密&nbsp;&nbsp;&nbsp;&nbsp; 码:</th>      <td><input type="password" name="j_password" id="password"       /></td>     </tr>     <tr>      <th>验证码:</th>      <td><input type="text" maxlength="4" name="code" id="code"       style="width: 80px;" onkeypress="javascript:pressKey(event);" /> <img id="validateCode"       src="validate.code" width="75" height="33" /> <a       onclick="javascript:reload();"><img        src="../img/home/refresh.gif" width="22" height="22" /> </a>      </td>     </tr>    </table>   </form>   <c:if test="${not empty param.error}">    <font color="red"> 登录失败<br /> <br /> 原因: <c:out      value="${SPRING_SECURITY_LAST_EXCEPTION.message}" /></font>   </c:if>
?

?

?

4、application-security.xml 配置

?

<?xml version="1.0" encoding="UTF-8"?><beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:b="http://www.springframework.org/schema/beans" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd                         http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> <http>  <!-- 不拦截 -->  <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" />  <intercept-url pattern="/list/**"   access="ROLE_ADMIN,ROLE_MANAGER,ROLE_USER" />    <intercept-url pattern="/delete/**" access="ROLE_ADMIN" />   <!-- 设置登录过滤器 -->  <custom-filter before="FORM_LOGIN_FILTER" ref="validateCodeAuthenticationFilter" />  <!-- 登录表单设置 -->  <form-login login-page="/home/login"   default-target-url="/home/loginSuccess.action"(登录成功的url)   authentication-failure-url="/home/login.action?error=true"(登录失败的url) />  <!-- 登出操作后跳转到该页面 -->  <!-- <logout logout-success-url="/loggedout.jsp" delete-cookies="JSESSIONID"   /> <remember-me /> -->  <!-- SESSION超时后跳转到该页面 -->  <!-- <session-management invalid-session-url="/timeout.jsp"> </session-management> --> </http> <authentication-manager alias="authenticationManager">  <authentication-provider>   <!-- 直接使用SQL语句查询登录帐号对应权限, users-by-username-query:查询登录用户是否存在 authorities-by-username-query:查询登录用户权限(登录用户可以不属于任何组,从t_user_role表中获取权限)    group-authorities-by-username-query:查询登录用户所在组的权限 -->   <jdbc-user-service data-source-ref="webDataSource"    users-by-username-query="SELECT t_user.name AS username,t_user.password as password,'true' AS enabled FROM t_user WHERE t_user.name = ?"    authorities-by-username-query="SELECT name AS username,role as authorities                               FROM T_USER                               LEFT OUTER JOIN t_role AS userrole ON(t_user.id = userrole.user_id)                                LEFT OUTER JOIN t_role AS role ON (userrole.role_id = role.id)                                WHERE t_user.name = ?" />  </authentication-provider> </authentication-manager> <!-- 验证码过滤器 --> <beans:bean id="validateCodeAuthenticationFilter"  ref="authenticationManager"></beans:property> </beans:bean> <!-- 登录成功 --> <beans:bean id="loginLogAuthenticationSuccessHandler"  value="/home/loginSuccess.action"></beans:property> </beans:bean> <!-- 登录失败 --> <beans:bean id="simpleUrlAuthenticationFailureHandler"  value="/home/login.action?error=true"></beans:property> </beans:bean></beans:beans> 

?

5、验证码验证

package cn.com.trade.security;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import org.apache.commons.lang3.StringUtils;import org.springframework.security.authentication.AuthenticationServiceException;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.Authentication;import org.springframework.security.core.AuthenticationException;import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;import org.springframework.security.web.util.TextEscapeUtils;import cn.com.fxark.util.md5.MD5;import cn.com.trade.domain.adminuser.AdminUser;import cn.com.trade.global.GlobalParameter;import cn.com.trade.service.ServiceManager;/** * 带验证码校验功能的用户名、密码认证过滤器 *  * 支持不输入验证码;支持验证码忽略大小写。 *  * @author Long *  */public class ValidateCodeUsernamePasswordAuthenticationFilter extendsUsernamePasswordAuthenticationFilter {private boolean postOnly = true;private boolean allowEmptyValidateCode = false;private String sessionvalidateCodeField = DEFAULT_SESSION_VALIDATE_CODE_FIELD;private String validateCodeParameter = DEFAULT_VALIDATE_CODE_PARAMETER;public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";// session中保存的验证码public static final String DEFAULT_SESSION_VALIDATE_CODE_FIELD = "rand";// 输入的验证码public static final String DEFAULT_VALIDATE_CODE_PARAMETER = "code";@Overridepublic Authentication attemptAuthentication(HttpServletRequest request,HttpServletResponse response) throws AuthenticationException {if (postOnly && !request.getMethod().equals("POST")) {throw new AuthenticationServiceException("Authentication method not supported: "+ request.getMethod());}String username = obtainUsername(request);String password = obtainPassword(request);if (username == null) {username = "";}if (password == null) {password = "";}username = username.trim();UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);// Place the last username attempted into HttpSession for viewsHttpSession session = request.getSession(false);if (session != null || getAllowSessionCreation()) {request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY,TextEscapeUtils.escapeEntities(username));}// Allow subclasses to set the "details" propertysetDetails(request, authRequest);// check validate codeif (!isAllowEmptyValidateCode())checkValidateCode(request);// 根据用户和密码查询AdminUser adminUser = ServiceManager.getInstance().getAdminUserService().login(username, MD5.getMD5ofStr(password));session.setAttribute(GlobalParameter.HT_ADMIN_LOGIN_USER_SESSION_NAME,adminUser);return this.getAuthenticationManager().authenticate(authRequest);}/** *  * <li>比较session中的验证码和用户输入的验证码是否相等</li> *  */protected void checkValidateCode(HttpServletRequest request) {String sessionValidateCode = obtainSessionValidateCode(request);String validateCodeParameter = obtainValidateCodeParameter(request);if (StringUtils.isEmpty(validateCodeParameter)|| !sessionValidateCode.equalsIgnoreCase(validateCodeParameter)) {throw new AuthenticationServiceException("验证码错误!");}}private String obtainValidateCodeParameter(HttpServletRequest request) {return request.getParameter(validateCodeParameter);}protected String obtainSessionValidateCode(HttpServletRequest request) {Object obj = request.getSession().getAttribute(sessionvalidateCodeField);return null == obj ? "" : obj.toString();}public boolean isPostOnly() {return postOnly;}@Overridepublic void setPostOnly(boolean postOnly) {this.postOnly = postOnly;}public String getValidateCodeName() {return sessionvalidateCodeField;}public void setValidateCodeName(String validateCodeName) {this.sessionvalidateCodeField = validateCodeName;}public boolean isAllowEmptyValidateCode() {return allowEmptyValidateCode;}public void setAllowEmptyValidateCode(boolean allowEmptyValidateCode) {this.allowEmptyValidateCode = allowEmptyValidateCode;}}
?

?

<?xml version="1.0" encoding="UTF-8"?><beans:beans xmlns="http://www.springframework.org/schema/security"xmlns:beans="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"default-autowire="byName" default-lazy-init="false"><intercept-url pattern="/netservice/*" access="IS_AUTHENTICATED_ANONYMOUSLY" /><global-method-security pre-post-annotations="enabled"></global-method-security> <http use-expressions="true" auto-config="true" access-denied-page="/timeOut.jsp"><form-login login-page="/login.jsp" always-use-default-target="true"default-target-url="/index.jsp"authentication-failure-url="/login.jsp?error=1"/> <logout logout-success-url="/index.jsp" /><!-- 实现免登陆验证 --> <remember-me /> <session-management invalid-session-url="/timeout.jsp"> <concurrency-control max-sessions="10" error-if-maximum-exceeded="true" /> </session-management> <!-- 增加一个filter,这点与Acegi是不一样的,不能修改默认的filter了, 这个filter位于FILTER_SECURITY_INTERCEPTOR之前 --><custom-filter ref="myFilter"before="FILTER_SECURITY_INTERCEPTOR" /></http> <!-- 一个自定义的filter,必须包含authenticationManager,accessDecisionManager,securityMetadataSource三个属性, 我们的所有控制将在这三个类中实现,解释详见具体配置 --><beans:bean id="myFilter"/></beans:bean><beans:bean id="accessDecisionManager"class="com.health.system.springSecurity.MyAccessDecisionManager"></beans:bean><beans:bean id="filterInvocationSecurityMetadataSource"class="com.health.system.springSecurity.MyInvocationSecurityMetadataSource"></beans:bean> <!-- 验证配置 , 认证管理器,实现用户认证的入口,主要实现UserDetailsService接口即可 --><authentication-manager alias="authenticationManager"><authentication-provideruser-service-ref="userDetailServiceImpl"><password-encoder ref="passwordEncoder"></password-encoder></authentication-provider></authentication-manager><beans:bean id="userDetailServiceImpl"class="com.health.system.springSecurity.UserDetailServiceImpl"></beans:bean><beans:bean id="passwordEncoder"class="com.health.system.springSecurity.MyPasswordEncoder"></beans:bean><!-- 获取spring上下文 --><beans:bean id="SpringContextUtil"class="com.health.system.javacommon.util.SpringContextUtil"></beans:bean></beans:beans>

热点排行