一、实现功能

二、数据表设计

为了测试方便,这里创建一个简单的数据表,只含有name和password两个字段。至于角色,权限等,这里都先不考虑。

插入一条数据,name为admin,password为e10adc3949ba59abbe56e057f20f883e(这是123456经md5加密后得到的值)。

三、配置文件

1 在pom.xml中添加三个相关的包

  1. <dependency>
  2. <groupId>org.springframework.security</groupId>
  3. <artifactId>spring-security-core</artifactId>
  4. <version>${org.springframework.security.version}</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.security</groupId>
  8. <artifactId>spring-security-config</artifactId>
  9. <version>${org.springframework.security.version}</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.springframework.security</groupId>
  13. <artifactId>spring-security-web</artifactId>
  14. <version>${org.springframework.security.version}</version>
  15. </dependency>

2 web.xml中添加过滤器

  1. <!-- 添加Spring-Security过滤器 -->
  2. <filter>
  3. <filter-name>springSecurityFilterChain</filter-name>
  4. <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  5. </filter>
  6. <filter-mapping>
  7. <filter-name>springSecurityFilterChain</filter-name>
  8. <url-pattern>/service/*</url-pattern>
  9. </filter-mapping>

3 src/main/resource/spring/applicationContext-security.xml的内容为

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns="http://www.springframework.org/schema/security"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  7. http://www.springframework.org/schema/security
  8. http://www.springframework.org/schema/security/spring-security-3.1.xsd">
  9. <!-- 需要登陆能够访问的路径 -->
  10. <http access-denied-page="/service/login/unSecurity" entry-point-ref="authenticationProcessingFilterEntryPoint">
  11. <!-- 首页 -->
  12. <intercept-url pattern="/service/index/index" access="ROLE_AUTHORITY"/>
  13. <!-- 自定义loginFilter -->
  14. <custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER" />
  15. <logout logout-url="/service/login/logout" logout-success-url="/" invalidate-session="true"
  16. delete-cookies="JSESSIONID,SPRING_SECURITY_REMEMBER_ME_COOKIE"/>
  17. <session-management invalid-session-url="/service/login/unSecurity" session-authentication-strategy-ref="sas"/>
  18. </http>
  19. <!-- 登录验证器 -->
  20. <beans:bean id="loginFilter" class="com.zheng.shared.security.JadeUserPwdAuthFilter">
  21. <!-- 处理登录的action -->
  22. <beans:property name="filterProcessesUrl" value="/service/login/userLogin"/>
  23. <!-- 认证管理 点击完登录后,最终实现校验的是AuthenticationProvider-->
  24. <beans:property name="authenticationManager" ref="myAuthenticationManager"/>
  25. <!-- 验证成功后的处理-->
  26. <beans:property name="authenticationSuccessHandler" ref="loginLogAuthenticationSuccessHandler"/>
  27. <!-- 验证失败后的处理-->
  28. <beans:property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler"/>
  29. <!-- 实现多个帐号登录时最后一次登录的有效,目前只请允许登录一个帐号 -->
  30. <beans:property name="sessionAuthenticationStrategy" ref="sas"/>
  31. </beans:bean>
  32. <beans:bean id="loginLogAuthenticationSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
  33. <beans:property name="alwaysUseDefaultTargetUrl" value="true"/>
  34. <beans:property name="defaultTargetUrl" value="/service/login/loginSucc"/>
  35. </beans:bean>
  36. <beans:bean id="simpleUrlAuthenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
  37. <!-- 可以配置相应的跳转方式。属性forwardToDestination为true采用forward false为sendRedirect -->
  38. <beans:property name="defaultFailureUrl" value="/service/login/loginFail"/>
  39. </beans:bean>
  40. <beans:bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
  41. <beans:property name="maximumSessions" value="1"/>
  42. <beans:property name="exceptionIfMaximumExceeded" value="false"/>
  43. <beans:constructor-arg name="sessionRegistry" ref="sessionRegistry"/>
  44. </beans:bean>
  45. <beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/>
  46. <authentication-manager alias="myAuthenticationManager">
  47. <authentication-provider ref="authenticationProvider"/>
  48. </authentication-manager>
  49. <beans:bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
  50. <!-- 配置异常能被捕捉 -->
  51. <beans:property name="hideUserNotFoundExceptions" value="false" />
  52. <beans:property name="userDetailsService" ref="userDetailService" />
  53. <!-- <beans:property name="messageSource" ref="messageSource" /> -->
  54. <!-- <beans:property name="userCache" ref="userCache" />可使用缓存保存用户信息-->
  55. <!-- 开发过程中可以先把这两行注释掉-->
  56. <!-- <beans:property name="passwordEncoder" ref="passwordEncode"/>
  57. <beans:property name="saltSource" ref="saltSource" />  -->
  58. </beans:bean>
  59. <!-- 密码加密 -->
  60. <beans:bean id="passwordEncode" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
  61. <beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
  62. <beans:property name="userPropertyToUse" value="id"/>
  63. </beans:bean>
  64. <beans:bean id="userDetailService" class="com.zheng.service.impl.UserServiceImpl" />
  65. <!-- 未登录的切入点-->
  66. <beans:bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
  67. <beans:property name="loginFormUrl" value="/service/login/unSecurity" />
  68. </beans:bean>
  69. </beans:beans>

四、相关代码

1src/main/Java/com/zheng/shared/sercurity/JadeUserPwdAuthFilter.java中的代码为

  1. package com.zheng.shared.security;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.security.authentication.AuthenticationServiceException;
  6. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  7. import org.springframework.security.core.Authentication;
  8. import org.springframework.security.core.AuthenticationException;
  9. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  10. import com.zheng.bean.User;
  11. import com.zheng.dao.UserMapper;
  12. public class JadeUserPwdAuthFilter extends UsernamePasswordAuthenticationFilter {
  13. public static final String USERNAME = "userName";
  14. public static final String PASSWORD = "userPassword";
  15. @Autowired
  16. private UserMapper userDao;
  17. @Override
  18. public Authentication attemptAuthentication(HttpServletRequest request,
  19. HttpServletResponse response) throws AuthenticationException {
  20. if (!request.getMethod().equals("POST")) {
  21. throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
  22. }
  23. String userName = request.getParameter(USERNAME);
  24. String password = request.getParameter(PASSWORD);
  25. User user = userDao.findUserByUserName(userName);
  26. System.out.println("username: " + user.getUsername());
  27. System.out.println("password: " + user.getPassword());
  28. // 验证用户是否被启用
  29. UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(userName, password);
  30. // 允许子类设置详细属性
  31. setDetails(request, authRequest);
  32. // 运行UserDetailsService的loadUserByUsername 再次封装Authentication
  33. return this.getAuthenticationManager().authenticate(authRequest);
  34. }
  35. }

2 src/main/java/com/zheng/service/UserService.java的内容为

  1. package com.zheng.service;
  2. import org.springframework.security.core.userdetails.UserDetailsService;
  3. public interface UserService extends UserDetailsService{
  4. }

3 src/main/java/com/zheng/service/impl/UserServiceImpl.java的内容为

  1. package com.zheng.service.impl;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.security.core.userdetails.UserDetails;
  4. import org.springframework.security.core.userdetails.UsernameNotFoundException;
  5. import com.zheng.bean.User;
  6. import com.zheng.dao.UserMapper;
  7. import com.zheng.service.UserService;
  8. public class UserServiceImpl implements UserService{
  9. @Autowired
  10. private UserMapper userMapper;
  11. @Override
  12. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  13. User user = null;
  14. try {
  15. user = userMapper.findUserByUserName(username);
  16. } catch (Exception e) {
  17. e.printStackTrace();
  18. }
  19. if (user == null) {
  20. throw new UsernameNotFoundException("用户名或密码不正确!");
  21. }
  22. System.out.println("username: " + user.getUsername());
  23. System.out.println("password: " + user.getPassword());
  24. return user;
  25. }
  26. }

4 src/main/java/com/zheng/bean/User.java的内容为

  1. package com.zheng.bean;
  2. import java.io.Serializable;
  3. import java.util.Collection;
  4. import org.springframework.security.core.GrantedAuthority;
  5. import org.springframework.security.core.userdetails.UserDetails;
  6. public class User implements UserDetails , Serializable {
  7. private static final long serialVersionUID = 123L;
  8. private String userName;
  9. private String password;
  10. private Collection<GrantedAuthority> authorities;// 用户证书是否有效
  11. @Override
  12. public String getUsername() {
  13. return this.userName;
  14. }
  15. @Override
  16. public String getPassword() {
  17. return password;
  18. }
  19. public void setPassword(String password) {
  20. this.password = password;
  21. }
  22. @Override
  23. public Collection<? extends GrantedAuthority> getAuthorities() {
  24. return authorities;
  25. }
  26. public void setAuthorities(Collection<GrantedAuthority> authorities) {
  27. this.authorities = authorities;
  28. }
  29. @Override
  30. public boolean isAccountNonExpired() {
  31. return true;
  32. }
  33. @Override
  34. public boolean isAccountNonLocked() {
  35. return true;
  36. }
  37. @Override
  38. public boolean isCredentialsNonExpired() {
  39. return true;
  40. }
  41. @Override
  42. public boolean isEnabled() {
  43. return true;
  44. }
  45. }

特别需要注意的是:用户只有在不过期、没被锁定、没被禁用的情况下才能登录成功,所以isEnabled()方法的返回值设为真,表示用户没有禁用。

5 src/main/java/com/zheng/dao/UserMapper.java的内容为

  1. package com.zheng.dao;
  2. import com.zheng.bean.User;
  3. public interface UserMapper {
  4. /**
  5. * 根据用户名查找
  6. * @param userName
  7. * @return
  8. */
  9. User findUserByUserName(String name);
  10. }

6 src/main/resources/config/mybatis/mapper/UserMapper.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3. <mapper namespace="com.zheng.dao.UserMapper" >
  4. <resultMap id="BaseResultMap" type="com.zheng.bean.User" >
  5. <result column="name" property="userName" jdbcType="VARCHAR" />
  6. <result column="password" property="password" jdbcType="VARCHAR" />
  7. </resultMap>
  8. <select id="findUserByUserName" parameterType="string" resultMap="BaseResultMap" >
  9. select * from user where name = #{userName}
  10. </select>
  11. </mapper>

7 LoginController.java中响应登录成功和失败的方法为

  1. /**
  2. * 登陆成功进行处理的方法
  3. * @param request
  4. * @return
  5. */
  6. @RequestMapping("/loginSucc")
  7. @ResponseBody
  8. public Map<String,Object> loginSucc(HttpServletRequest request){
  9. System.out.println("登录成功!");
  10. Map<String,Object> result = new HashMap<String,Object>();
  11. return result;
  12. }
  13. /**
  14. * 登陆失败进行的操作
  15. * @param request
  16. * @return
  17. */
  18. @RequestMapping("/loginFail")
  19. @ResponseBody
  20. public Map<String,Object> loginFail(HttpServletRequest request){
  21. System.out.println("登录失败!");
  22. Map<String,Object> result = new HashMap<String,Object>();
  23. return result;
  24. }

五、运行结果

 

Spring Security实现后台管理员登录(一)的更多相关文章

  1. 七:Spring Security 前后端分离登录,非法请求直接返回 JSON

    Spring Security 前后端分离登录,非法请求直接返回 JSON 解决方案 在 Spring Security 中未获认证的请求默认会重定向到登录页,但是在前后端分离的登录中,这个默认行为则 ...

  2. spring security 动态 修改当前登录用户的 权限

    1.前言 spring security 可以获取当前登录的用户信息,同时提供了接口 来修改权限列表信息 , 使用这个方法 ,可以动态的修改当前登录用户权限. 那么问题来了... 如果我是管理员 ,如 ...

  3. Spring Security 入门(1-3-1)Spring Security - http元素 - 默认登录和登录定制

    登录表单配置 - http 元素下的 form-login 元素是用来定义表单登录信息的.当我们什么属性都不指定的时候 Spring Security 会为我们生成一个默认的登录页面. 如果不想使用默 ...

  4. Spring Security默认的用户登录表单 页面源代码

    Spring Security默认的用户登录表单 页面源代码 <html><head><title>Login Page</title></hea ...

  5. Spring Security OAuth2 SSO 单点登录

    基于 Spring Security OAuth2 SSO 单点登录系统 SSO简介 单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自 ...

  6. Spring Security之多次登录失败后账户锁定功能的实现

    在上一次写的文章中,为大家说到了如何动态的从数据库加载用户.角色.权限信息,从而实现登录验证及授权.在实际的开发过程中,我们通常会有这样的一个需求:当用户多次登录失败的时候,我们应该将账户锁定,等待一 ...

  7. spring security实现记录用户登录时间等信息

    目录 spring security实现记录用户登录时间等信息 一.原理分析 二.实现方式 2.1 自定义AuthenticationSuccessHandler实现类 2.2 在spring-sec ...

  8. SpringCloud微服务实战——搭建企业级开发框架(四十):使用Spring Security OAuth2实现单点登录(SSO)系统

    一.单点登录SSO介绍   目前每家企业或者平台都存在不止一套系统,由于历史原因每套系统采购于不同厂商,所以系统间都是相互独立的,都有自己的用户鉴权认证体系,当用户进行登录系统时,不得不记住每套系统的 ...

  9. Spring Security 前后端分离登录,非法请求直接返回 JSON

    hello 各位小伙伴,国庆节终于过完啦,松哥也回来啦,今天开始咱们继续发干货! 关于 Spring Security,松哥之前发过多篇文章和大家聊聊这个安全框架的使用: 手把手带你入门 Spring ...

随机推荐

  1. python 实用命令

    列表理解: list = [-1, -2, 1, 2] [item for item in list if item > 0] [1, 2] d = {'person': 2, 'cat': 4 ...

  2. Python datetime描述

    (1)字符串转datetime:>>> string = '2014-01-08 11:59:58'>>> time1 = datetime.datetime.st ...

  3. JS框架的实现

    众多流行的JS库都不同程度的污染了原生JS,最典型的如Prototype ,Mootools .JQuery则完全例外,一个匿名函数执行后便诞生了集所有API为一身的强大 $ .虽然如此,JQuery ...

  4. 洛谷P3391文艺平衡树(Splay)

    题目传送门 转载自https://www.cnblogs.com/yousiki/p/6147455.html,转载请注明出处 经典引文 空间效率:O(n) 时间效率:O(log n)插入.查找.删除 ...

  5. Web应用主动侦测工具Skipfish

    Web应用主动侦测工具Skipfish   Skipfish是Kali Linux附带的一个主动Web应用侦测工具.该工具会首先尽可能获取所有网站路径,进行访问,然后根据返回的内容,检测是否存在漏洞. ...

  6. Requirejs快速使用

    Requirejs是一个简单,实用,强大的前端模块化js库,它遵循AMD这一客户端模块定义规范,使用它能够使我们前端代码更加清晰高效加载,摆脱了以前前端代码杂乱无序的状态. 使用步骤如下: 1.下载r ...

  7. CodeForces - 995B Suit and Tie

    题面在这里! 明明可以出成n<=1e5但是因为拒绝写数据结构而只出到n<=100,,,出题人真的很棒棒.. 一个显然的贪心就是,把和当前序列最左端的数匹配的数移到它的右边,这样迭代下去总是 ...

  8. 【计算几何】【推导】【补集转化】AtCoder Regular Contest 082 E - ConvexScore

    题意:平面上给你N个点.对于一个“凸多边形点集”(凸多边形点集被定义为一个其所有点恰好能形成凸多边形的点集)而言,其对答案的贡献是2^(N个点内在该凸多边形点集形成的凸包内的点数 - 该凸多边形点集的 ...

  9. 【状态压缩DP】NOIP2005-river过河

    [问题描述] 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看 ...

  10. fastjson生成json时Null属性不显示的解决方法

    举个例子 Map < String , Object > jsonMap = new HashMap< String , Object>(); jsonMap.put(&quo ...