zoukankan      html  css  js  c++  java
  • Spring Security实现后台管理员登录(一)

    一、实现功能

    二、数据表设计

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

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

    三、配置文件

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

     

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    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中添加过滤器

     

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    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的内容为

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

    四、相关代码

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

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

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

     

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.zheng.service;  
    2.   
    3. import org.springframework.security.core.userdetails.UserDetailsService;  
    4.   
    5. public interface UserService extends UserDetailsService{  
    6.   
    7. }  

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

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.zheng.service.impl;  
    2.   
    3. import org.springframework.beans.factory.annotation.Autowired;  
    4. import org.springframework.security.core.userdetails.UserDetails;  
    5. import org.springframework.security.core.userdetails.UsernameNotFoundException;  
    6.   
    7. import com.zheng.bean.User;  
    8. import com.zheng.dao.UserMapper;  
    9. import com.zheng.service.UserService;  
    10.   
    11.   
    12. public class UserServiceImpl implements UserService{  
    13.   
    14.     @Autowired  
    15.     private UserMapper userMapper;  
    16.       
    17.     @Override  
    18.     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {  
    19.         User user = null;  
    20.         try {  
    21.             user = userMapper.findUserByUserName(username);  
    22.         } catch (Exception e) {  
    23.             e.printStackTrace();  
    24.         }  
    25.         if (user == null) {  
    26.             throw new UsernameNotFoundException("用户名或密码不正确!");  
    27.         }  
    28.         System.out.println("username: " + user.getUsername());  
    29.         System.out.println("password: " + user.getPassword());  
    30.           
    31.         return user;  
    32.     }  
    33.   
    34. }  

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

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.zheng.bean;  
    2.   
    3. import java.io.Serializable;  
    4. import java.util.Collection;  
    5.   
    6. import org.springframework.security.core.GrantedAuthority;  
    7. import org.springframework.security.core.userdetails.UserDetails;  
    8.   
    9. public class User implements UserDetails , Serializable {  
    10.     private static final long serialVersionUID = 123L;  
    11.       
    12.     private String userName;  
    13.   
    14.     private String password;  
    15.       
    16.     private Collection<GrantedAuthority> authorities;// 用户证书是否有效  
    17.           
    18.     @Override  
    19.     public String getUsername() {  
    20.         return this.userName;  
    21.     }  
    22.   
    23.     @Override  
    24.     public String getPassword() {  
    25.         return password;  
    26.     }  
    27.       
    28.     public void setPassword(String password) {  
    29.         this.password = password;  
    30.     }  
    31.       
    32.     @Override  
    33.     public Collection<? extends GrantedAuthority> getAuthorities() {  
    34.         return authorities;  
    35.     }  
    36.       
    37.     public void setAuthorities(Collection<GrantedAuthority> authorities) {  
    38.         this.authorities = authorities;  
    39.     }  
    40.       
    41.     @Override  
    42.     public boolean isAccountNonExpired() {  
    43.         return true;  
    44.     }  
    45.   
    46.     @Override  
    47.     public boolean isAccountNonLocked() {  
    48.         return true;  
    49.     }  
    50.       
    51.     @Override  
    52.     public boolean isCredentialsNonExpired() {  
    53.         return true;  
    54.     }  
    55.   
    56.     @Override  
    57.     public boolean isEnabled() {  
    58.         return true;  
    59.     }  
    60. }  

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

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

     

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.zheng.dao;  
    2.   
    3. import com.zheng.bean.User;  
    4.   
    5. public interface UserMapper {  
    6.     /** 
    7.      * 根据用户名查找 
    8.      * @param userName 
    9.      * @return 
    10.      */  
    11.     User findUserByUserName(String name);  
    12. }  

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

     

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    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.     
    9.   <select id="findUserByUserName" parameterType="string" resultMap="BaseResultMap" >  
    10.     select * from user where name = #{userName}  
    11.   </select>  
    12.   
    13. </mapper>  

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

     

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    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.  * 登陆失败进行的操作 
    16.  * @param request 
    17.  * @return 
    18.  */  
    19. @RequestMapping("/loginFail")  
    20. @ResponseBody  
    21. public Map<String,Object> loginFail(HttpServletRequest request){  
    22.     System.out.println("登录失败!");  
    23.     Map<String,Object> result = new HashMap<String,Object>();  
    24.     return result;  
    25. }  

    五、运行结果

     
  • 相关阅读:
    codeforces 869E. The Untended Antiquity(二维树状数组,随机化)
    bzoj 3083: 遥远的国度(树上换根操作,树剖+询问整个子树)
    hdu 5534 Partial Tree(dp+降唯,好题)
    AtCoder Regular Contest 075 E
    hihocoder 1387 A Research on "The Hundred Family Surnames"(树,lca,求同一颜色的直径)
    hdu 5458 Stability(生成树,树链剖分,好题)
    推荐一套个人ui组件库
    回望2019,期盼2020
    如何从产品的角度对待自己的博客
    致一名迷茫的我
  • 原文地址:https://www.cnblogs.com/grimm/p/6732864.html
Copyright © 2011-2022 走看看