简单说说Spring Security 使用(附加验证码登录,自定义认证)
先看官方文档:http://docs.spring.io/spring-security/site/docs/4.0.x/reference/htmlsingle/
spring security4已经加入了注解的方式,但是为了比较清晰了解,还是使用了配置的方式。
第一步:web.xml 加入拦截、
<!-- 配置springSecurityFilter --> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
第二步:编写配置文件:spring-security.xml
<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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd "> <http pattern="/common/**" security="none" /> <http pattern="/login.jsp" security="none" /> <http pattern="/user/login" security="none" /> <http pattern="/index" security="none" /> <http use-expressions="true"> <intercept-url pattern="/**" access="isAuthenticated()" /> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=1" /> <logout invalidate-session="true" logout-url="/logout" logout-success-url="/" /> </http> <authentication-manager alias="myAuthenticationManager"> <authentication-provider user-service-ref="cwSysUserDetailsService"> <password-encoder hash="md5"></password-encoder> </authentication-provider> </authentication-manager> </beans:beans>
第三步:编写登录认证函数
package com.eshore.upsweb.service; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import com.eshore.upsweb.dao.CwSysUserDAO; import com.eshore.upsweb.model.CwSysUser; import com.eshore.upsweb.model.CwSysUserRole; @Service(value="cwSysUserDetailsService") public class CwSysUserDetailsService implements UserDetailsService{ @Autowired CwSysUserDAO cwSysUserDAO; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { System.out.println("username is " + username); CwSysUser user = cwSysUserDAO.findUser(username); List<GrantedAuthority> authorities = buildUserAuthority(user.getUserRoles()); return buildUserForAuthentication(user, authorities); } /** * 返回验证角色 * @param userRoles * @return */ private List<GrantedAuthority> buildUserAuthority(Set<CwSysUserRole> userRoles){ Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>(); for(CwSysUserRole userRole:userRoles){ setAuths.add(new SimpleGrantedAuthority(userRole.getRole().getRoleId().toString())); } List<GrantedAuthority> result = new ArrayList<GrantedAuthority>(setAuths); return result; } /** * 返回验证用户 * @param user * @param authorities * @return */ private User buildUserForAuthentication(CwSysUser user,List<GrantedAuthority> authorities){ return new User(user.getUserNo(),user.getPassword(),true,true,true,true,authorities); } /** * */ }
第四步:编写登录controller
package com.eshore.upsweb.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Restrictions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.eshore.upsweb.model.CwSysUser; import com.eshore.upsweb.model.LoginInfo; import com.eshore.upsweb.service.CwSysUserService; @Controller @RequestMapping(value="/user") public class CwSysUserController { @Autowired private CwSysUserService cwSysUserService; @Autowired private AuthenticationManager myAuthenticationManager; // 这样就可以自动注入?oh ,mygod ,how can it do so? @RequestMapping(value="/login",method=RequestMethod.POST) @ResponseBody public LoginInfo login(@RequestParam(defaultValue="") String username,@RequestParam(defaultValue="") String password,HttpServletRequest request){ if(!checkValidateCode(request)){ return new LoginInfo().failed().msg("验证码错误!"); } username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); /* DetachedCriteria detachedCriteria = DetachedCriteria.forClass(CwSysUser.class,"cwSysUser"); detachedCriteria.add(Restrictions.eq("userNo", username)); if(cwSysUserService.countUser(detachedCriteria)==0){ return new LoginInfo().failed().msg("用户名: "+username+" 不存在."); } */ try { Authentication authentication = myAuthenticationManager.authenticate(authRequest); //调用loadUserByUsername SecurityContextHolder.getContext().setAuthentication(authentication); HttpSession session = request.getSession(); session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext()); // 这个非常重要,否则验证后将无法登陆 return new LoginInfo().success().msg(authentication.getName()); } catch (AuthenticationException ex) { return new LoginInfo().failed().msg("用户名或密码错误"); } } /** * 验证码判断 * @param request * @return */ protected boolean checkValidateCode(HttpServletRequest request) { String result_verifyCode = request.getSession().getAttribute("verifyResult") .toString(); // 获取存于session的验证值 // request.getSession().setAttribute("verifyResult", null); String user_verifyCode = request.getParameter("verifyCode");// 获取用户输入验证码 if (null == user_verifyCode || !result_verifyCode.equalsIgnoreCase(user_verifyCode)) { return false; } return true; } }
第五步:编写对应的登录jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html"> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Login</title> <link href="./common/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="./common/bootstrap/css/bootstrap-theme.min.css" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="./common/css/demo.css"> <link rel="stylesheet" type="text/css" href="./common/css/style.css"> <link rel="stylesheet" type="text/css" href="./common/css/animate-custom.css"> <link rel="stylesheet" href="./common/bootstrap/css/bootstrap.css" type="text/css"></link> <script type="text/javascript" src="./common/bootstrap/js/bootstrap.min.js"></script> <script type="text/javascript" src="./common/jquery/jquery-2.1.1.min.js"></script> <body> <div class="container"> <header> </header> <div id="container_demo"> <div id="wrapper"> <div id="login" class="animate form"> <!-- <form name='loginForm' action="<c:url value='j_spring_security_check' />" method='POST'> --> <h1>电信融合支付平台</h1> <form id='loginForm' method="POST"> <p> <label for="" class="uname" data-icon="u"> 用户名 </label> <input id="username" name="username" required="required" type="text" placeholder="myusername or mymail@mail.com"> </p> <p> <label for="" class="youpasswd" data-icon="p"> 密码 </label> <input id="password" name="password" required="required" type="password" placeholder="eg. X8df!90EO"> </p> <p> <label for="verification" class="verification" data-icon="v"> 验证 </label> <img src="index" id="verify" align="middle" title="看不清,请点我" style="cursor:hand;"/><br/> <input type="verification" id="verifyCode" name="verifyCode" placeholder="验证码" required="required"> </p> <!-- <p class="keeplogin"> <input type="checkbox" name="loginkeeping" id="loginkeeping" value="loginkeeping"> <label for="loginkeeping">保持登录</label> </p> --> <p class="login button"> <input type="submit" id="submitId" value="登录"> </p> </form> </div> </div> </div> </body> <script type="text/javascript"> $(function(){ /////////////////登录提交//////////////////////////// $("#loginForm").submit(function() { var username=$("#username").val(); var password=$("#password").val(); var verifyCode=$("#verifyCode").val(); var data={username:username,password:password,verifyCode:verifyCode}; var url="/upsweb/user/login"; $.ajax({ type: "POST", url: url, data: data, // contentType: "application/json", dataType: "json", success:function (result) { if(result.ok){ location.href="/upsweb"; }else{ $(".error").remove(); $("#loginForm").prepend("<div class='error'><font color='red'>"+result.msg+"</font></div>"); $("#verify").attr("src","/upsweb/index?timestamp="+new Date().getTime()); // 刷新验证码 } }, error:function(XMLHttpRequest, textStatus, errorThrown){ // alert(XMLHttpRequest.status); // alert(XMLHttpRequest.readyState); // alert(textStatus); //alert(XMLHttpRequest.responseText); alert('读取超时,请检查网络连接'); } }); return false; }); ///////////////////验证码更新///////////// $("#verify").click(function(){ $(this).attr("src","/upsweb/index?timestamp="+new Date().getTime()); }); }); $(function () { $("#dd").popover(); }); </script> </html>