Spring boot+Spring Security 4配置整合实例

本例所覆盖的内容:

1. 使用Spring Security管理用户身份认证、登录退出

2. 用户密码加密及验证

3. 采用数据库的方式实现Spring Securityremember-me功能

4. 获取登录用户信息。

5.使用Spring Security管理url和权限

 

本例所使用的框架:

1. Spring boot

2. Spring MVC

3. Spring Security

4. Spring Data JPA

5. thymeleaf

6.gradle

一、 整合Spring Security

build.gradle中加入如下片段:

[plain] view plain copy
  1.   
[plain] view plain copy
  1. compile('org.springframework.boot:spring-boot-starter-data-jpa')  
  2. compile("org.springframework.boot:spring-boot-starter-thymeleaf")  
  3. compile("org.springframework.boot:spring-boot-starter-security")<u>  
  4.     testCompile("org.springframework.boot:spring-boot-starter-test")  
  5. testCompile("org.springframework.security:spring-security-test")  

使用Spring Security4的四种方法概述

    那么在Spring Security4的使用中,有4种方法:

  1.     一种是全部利用配置文件,将用户、权限、资源(url)硬编码在xml文件中;
  2.     二种是用户和权限用数据库存储,而资源(url)和权限的对应采用硬编码配置。
  3.     三种是细分角色和权限,并将用户、角色、权限和资源均采用数据库存储,并且自定义过滤器,代替原有的FilterSecurityInterceptor过滤器         并分别实现AccessDecisionManager、InvocationSecurityMetadataSourceService和UserDetailsService,并在配置文件中进行相应配置。
  4.     四是修改spring security的源代码,主要是修改InvocationSecurityMetadataSourceService和UserDetailsService两个类。 前者是将配置文件     或数据库中存储的资源(url)提取出来加工成为url和权限列表的Map供Security使用,后者提取用户名和权限组成一个完整的(UserDetails)User     对象,该对象可以提供用户的详细信息供AuthentationManager进行认证与授权使用。

我们今天来实现一下第三种。

 当然,spring security4毕竟是西方国家的东西,以英文为主,使用习惯和文化的差异共存,况且为了适应大多数Web应用的权限管理,作者将Spring Security4打造的精简而灵活。精简指Spring Security4对用户和权限的表设计的非常简单,并且没有采用数据库来管理资源(URL)。这样的话,对于我们国人用户来说,是个很大的遗憾,这个遗憾甚至能够影响到我们对安全框架的选型。你想啊,在国内大多数项目中,均设置了比较复杂的权限控制,一般就会涉及到用户、角色、资源3张表,若要加上3张表之间的对应关系表2张,得有5张表。

    但是,Spring Security4提供了灵活的扩展方法。具体应该扩展哪些类呢? 或者到底Spring Security3工作的流程如何,你不妨参看下面一篇文章,就会获得
一些启示,网址为:http://www.blogjava.net/SpartaYew/archive/2011/06/15/350630.html, 哈哈,谢谢分享。

还有一个地址很有价值,http://download.csdn.net/detail/muddled/8981809,我就参考着上面的介绍扩展了4个类。

首先来说一下第三种方法的实现流程,我画了一张简易版流程图,帮助大家理解spring security4 的工作机制:

Spring boot+Spring Security 4配置整合实例

下面我们就来根据这个图中标注出的,重要的几个4个类来配置吧!

  1. 当然要现在application.properties配置文件中配置好数据库。
  2. 开始配置相关的实体类 SysUser.java  SRole.java  SysResource.java SysResourceRole.java
  3. [java] view plain copy
    1. package security.entity;  
    2.   
    3. import java.util.Date;  
    4. import java.util.HashSet;  
    5. import java.util.Set;  
    6.   
    7. import javax.persistence.Column;  
    8. import javax.persistence.Entity;  
    9. import javax.persistence.FetchType;  
    10. import javax.persistence.GeneratedValue;  
    11. import javax.persistence.GenerationType;  
    12. import javax.persistence.Id;  
    13. import javax.persistence.OneToMany;  
    14. import javax.persistence.Table;  
    15. import javax.persistence.Temporal;  
    16. import javax.persistence.TemporalType;  
    17.     @Entity  
    18.     @Table(name = "s_user")//code11  
    19.     public class SysUser implements java.io.Serializable {  
    20.           
    21.         @Id  
    22.         @GeneratedValue(strategy = GenerationType.IDENTITY)  
    23.         @Column(name = "id", unique = true, nullable = false)  
    24.         private Integer id;  
    25.         @Column(name = "name", length = 120)  
    26.         private String name; //用户名  
    27.         @Column(name = "email", length = 50)  
    28.         private String email;//用户邮箱  
    29.         @Column(name = "password", length = 120)  
    30.         private String password;//用户密码  
    31.         @Temporal(TemporalType.DATE)  
    32.         @Column(name = "dob", length = 10)  
    33.         private Date dob;//时间  
    34.           
    35.         @OneToMany(fetch = FetchType.EAGER, mappedBy = "SUser")  
    36.         private Set<SysRole> SysRoles = new HashSet<SysRole>(0);// 所对应的角色集合  
    37.   
    38.         public SysUser() {  
    39.         }  
    40.   
    41.         public SysUser(String name, String email, String password, Date dob, Set<SysRole> SysRoles) {  
    42.             this.name = name;  
    43.             this.email = email;  
    44.             this.password = password;  
    45.             this.dob = dob;  
    46.             this.SysRoles = SysRoles;  
    47.         }  
    48.   
    49.           
    50.         public Integer getId() {  
    51.             return this.id;  
    52.         }  
    53.   
    54.         public void setId(Integer id) {  
    55.             this.id = id;  
    56.         }  
    57.   
    58.           
    59.         public String getName() {  
    60.             return this.name;  
    61.         }  
    62.   
    63.         public void setName(String name) {  
    64.             this.name = name;  
    65.         }  
    66.   
    67.         public String getEmail() {  
    68.             return this.email;  
    69.         }  
    70.   
    71.         public void setEmail(String email) {  
    72.             this.email = email;  
    73.         }  
    74.   
    75.         public String getPassword() {  
    76.             return this.password;  
    77.         }  
    78.   
    79.         public void setPassword(String password) {  
    80.             this.password = password;  
    81.         }  
    82.   
    83.           
    84.         public Date getDob() {  
    85.             return this.dob;  
    86.         }  
    87.   
    88.         public void setDob(Date dob) {  
    89.             this.dob = dob;  
    90.         }  
    91.   
    92.         @OneToMany(fetch = FetchType.EAGER, mappedBy = "SUser")  
    93.         public Set<SysRole> getSysRoles() {  
    94.             return this.SysRoles;  
    95.         }  
    96.   
    97.         public void setSRoles(Set<SysRole> SysRoles) {  
    98.             this.SysRoles = SysRoles;  
    99.         }  
    100.   
    101. }  

    [java] view plain copy
    1. package security.entity;  
    2.   
    3. import java.util.Date;  
    4.   
    5. import javax.persistence.Column;  
    6. import javax.persistence.Entity;  
    7. import javax.persistence.FetchType;  
    8. import javax.persistence.GeneratedValue;  
    9. import javax.persistence.GenerationType;  
    10. import javax.persistence.Id;  
    11. import javax.persistence.JoinColumn;  
    12. import javax.persistence.ManyToOne;  
    13. import javax.persistence.Table;  
    14. //角色表  
    15. @Entity  
    16. @Table(name="s_role")  
    17. public class SysRole {  
    18.     @Id  
    19.     @GeneratedValue(strategy=GenerationType.IDENTITY)  
    20.     @Column (name="id",length=10)  
    21.     private int id;  
    22.       
    23.     @ManyToOne(fetch = FetchType.LAZY)  
    24.     @JoinColumn(name = "uid", nullable = false)  
    25.     private SysUser SUser;//角色对应的用户实体  
    26.       
    27.     @Column(name="name",length=100)  
    28.     private String name;//角色名称  
    29.       
    30.     public int getId() {  
    31.         return id;  
    32.     }  
    33.     public void setId(int id) {  
    34.         this.id = id;  
    35.     }  
    36.       
    37.     public String getName() {  
    38.         return name;  
    39.     }  
    40.     public void setName(String name) {  
    41.         this.name = name;  
    42.     }  
    43.     public SysUser getSUser() {  
    44.         return SUser;  
    45.     }  
    46.     public void setSUser(SysUser sUser) {  
    47.         SUser = sUser;  
    48.     }  
    49.       
    50.       
    51. }  

    [java] view plain copy
    1. package cn.paybay.ticketManager.entity;  
    2.   
    3. import javax.persistence.Column;  
    4. import javax.persistence.Entity;  
    5. import javax.persistence.GeneratedValue;  
    6. import javax.persistence.GenerationType;  
    7. import javax.persistence.Id;  
    8. import javax.persistence.Table;  
    9. @Entity  
    10. @Table(name="s_resource")  
    11. public class SysResource {  
    12.         @Id  
    13.         @GeneratedValue(strategy=GenerationType.IDENTITY)  
    14.         @Column (name="id",length=10)  
    15.         private int id;  
    16.           
    17.         @Column(name="resourceString",length=1000)  
    18.         private String resourceString;//url  
    19.           
    20.         @Column(name="resourceId",length=50)  
    21.         private String resourceId;//资源ID  
    22.           
    23.         @Column(name="remark",length=200)  
    24.         private String remark;//备注  
    25.           
    26.         @Column(name="resourceName",length=400)  
    27.         private String resourceName;//资源名称  
    28.           
    29.         @Column(name="methodName",length=400)  
    30.         private String methodName;//资源所对应的方法名  
    31.           
    32.         @Column(name="methodPath",length=1000)  
    33.         private String methodPath;//资源所对应的包路径  
    34.           
    35.         public int getId() {  
    36.             return id;  
    37.         }  
    38.   
    39.         public void setId(int id) {  
    40.             this.id = id;  
    41.         }  
    42.   
    43.         public String getResourceString() {  
    44.             return resourceString;  
    45.         }  
    46.   
    47.         public void setResourceString(String resourceString) {  
    48.             this.resourceString = resourceString;  
    49.         }  
    50.   
    51.         public String getResourceId() {  
    52.             return resourceId;  
    53.         }  
    54.   
    55.         public void setResourceId(String resourceId) {  
    56.             this.resourceId = resourceId;  
    57.         }  
    58.   
    59.         public String getRemark() {  
    60.             return remark;  
    61.         }  
    62.   
    63.         public void setRemark(String remark) {  
    64.             this.remark = remark;  
    65.         }  
    66.   
    67.         public String getResourceName() {  
    68.             return resourceName;  
    69.         }  
    70.   
    71.         public void setResourceName(String resourceName) {  
    72.             this.resourceName = resourceName;  
    73.         }  
    74.   
    75.         public String getMethodName() {  
    76.             return methodName;  
    77.         }  
    78.   
    79.         public void setMethodName(String methodName) {  
    80.             this.methodName = methodName;  
    81.         }  
    82.   
    83.         public String getMethodPath() {  
    84.             return methodPath;  
    85.         }  
    86.   
    87.         public void setMethodPath(String methodPath) {  
    88.             this.methodPath = methodPath;  
    89.         }  
    90.           
    91.           
    92. }  

    [java] view plain copy
    1. package security.entity;  
    2.   
    3. import java.util.Date;  
    4.   
    5. import javax.persistence.Column;  
    6. import javax.persistence.Entity;  
    7. import javax.persistence.FetchType;  
    8. import javax.persistence.GeneratedValue;  
    9. import javax.persistence.GenerationType;  
    10. import javax.persistence.Id;  
    11. import javax.persistence.JoinColumn;  
    12. import javax.persistence.ManyToOne;  
    13. import javax.persistence.Table;  
    14. @Entity  
    15. @Table(name="s_resource_role")  
    16. public class SysResourceRole {  
    17.         @Id  
    18.         @GeneratedValue(strategy=GenerationType.IDENTITY)  
    19.         @Column (name="id",length=10)  
    20.         private int id;  
    21.           
    22.         @Column(name="roleId",length=50)  
    23.         private String roleId; //角色ID  
    24.           
    25.         @Column(name="resourceId",length=50)  
    26.         private String resourceId;//资源ID  
    27.           
    28.         @Column(name="updateTime")  
    29.         private Date updateTime;//更新时间  
    30.   
    31.         public int getId() {  
    32.             return id;  
    33.         }  
    34.   
    35.         public void setId(int id) {  
    36.             this.id = id;  
    37.         }  
    38.   
    39.         public String getRoleId() {  
    40.             return roleId;  
    41.         }  
    42.   
    43.         public void setRoleId(String roleId) {  
    44.             this.roleId = roleId;  
    45.         }  
    46.   
    47.         public String getResourceId() {  
    48.             return resourceId;  
    49.         }  
    50.   
    51.         public void setResourceId(String resourceId) {  
    52.             this.resourceId = resourceId;  
    53.         }  
    54.   
    55.         public Date getUpdateTime() {  
    56.             return updateTime;  
    57.         }  
    58.   
    59.         public void setUpdateTime(Date updateTime) {  
    60.             this.updateTime = updateTime;  
    61.         }  
    62.   
    63.           
    64. }  

    好了实体类都建好了。然后运行一下,springboot程序。hibernate会自动创建表。在表中插入几条测试数据:
  4. s_user表Spring boot+Spring Security 4配置整合实例
  5. s_role表
Spring boot+Spring Security 4配置整合实例Spring boot+Spring Security 4配置整合实例

     6.s_resource表

Spring boot+Spring Security 4配置整合实例Spring boot+Spring Security 4配置整合实例

      7.s_resource_role表

Spring boot+Spring Security 4配置整合实例Spring boot+Spring Security 4配置整合实例

[sql] view plain copy
  1. <span style="color:rgb(51,204,0);">//请勿手工写入数据 供remember-me功能使用</span>  
  2. CREATE TABLE `persistent_logins` (  
  3.   `username` varchar(64) NOT NULL,  
  4.   `series` varchar(64) NOT NULL,  
  5.   `token` varchar(64) NOT NULL,  
  6.   `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,  
  7.   PRIMARY KEY (`series`)  
  8. )  

好了,现在我们来配置一下用户和角色的认证吧。

1、首先,创建WebSecurityConfig.java配置类,其中不明所以的地方请参照上面的图,慢慢往下看。

[java] view plain copy
  1. package security;  
  2.   
  3. import org.springframework.beans.factory.annotation.Autowired;  
  4. import org.springframework.context.annotation.Bean;  
  5. import org.springframework.context.annotation.Configuration;  
  6. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;  
  7. import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
  8. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;  
  9. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;  
  10. import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;  
  11. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;  
  12.   
  13. import security.support.CustomUserDetailsService;  
  14. import security.support.LoginSuccessHandler;  
  15. @Configuration  
  16. @EnableWebSecurity  
  17. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {  
  18.     @Autowired  
  19.     private CustomUserDetailsService customUserDetailsService;  
  20.     //http://localhost:8080/login 输入正确的用户名密码 并且选中remember-me 则登陆成功,转到 index页面   
  21.     //再次访问index页面无需登录直接访问  
  22.     //访问http://localhost:8080/home 不拦截,直接访问,  
  23.     //访问http://localhost:8080/hello 需要登录验证后,且具备 “ADMIN”权限hasAuthority("ADMIN")才可以访问  
  24.     @Override  
  25.     protected void configure(HttpSecurity http) throws Exception {  
  26.         http  
  27.         .authorizeRequests()  
  28.         .antMatchers("/home").permitAll()//访问:/home 无需登录认证权限  
  29.         .anyRequest().authenticated() //其他所有资源都需要认证,登陆后访问  
  30.         .antMatchers("/hello").hasAuthority("ADMIN"//登陆后之后拥有“ADMIN”权限才可以访问/hello方法,否则系统会出现“403”权限不足的提示  
  31.         .and()  
  32.         .formLogin()  
  33.         .loginPage("/login")//指定登录页是”/login”  
  34.         .permitAll()  
  35.         .successHandler(loginSuccessHandler()) //登录成功后可使用loginSuccessHandler()存储用户信息,可选。  
  36.         .and()  
  37.         .logout()  
  38.         .logoutSuccessUrl("/home"//退出登录后的默认网址是”/home”  
  39.         .permitAll()  
  40.         .invalidateHttpSession(true)  
  41.         .and()  
  42.         .rememberMe()//登录后记住用户,下次自动登录,数据库中必须存在名为persistent_logins的表  
  43.         .tokenValiditySeconds(1209600);  
  44.     }  
  45.   
  46.     @Autowired  
  47.     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {     
  48. //指定密码加密所使用的加密器为passwordEncoder()  
  49. //需要将密码加密后写入数据库   
  50.     auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());  
  51.         auth.eraseCredentials(false);         
  52.     }  
  53.   
  54.     @Bean  
  55.     public BCryptPasswordEncoder passwordEncoder() {  
  56.         return new BCryptPasswordEncoder(4);  
  57.     }  
  58.   
  59.     @Bean  
  60.     public LoginSuccessHandler loginSuccessHandler(){  
  61.         return new LoginSuccessHandler();  
  62.     }  
  63. }  

2、CustomUserDetailsService.java

[java] view plain copy
  1. package security.support;  
  2.   
  3. import org.springframework.beans.factory.annotation.Autowired;  
  4. import org.springframework.security.core.userdetails.UserDetails;  
  5. import org.springframework.security.core.userdetails.UserDetailsService;  
  6. import org.springframework.security.core.userdetails.UsernameNotFoundException;  
  7. import org.springframework.stereotype.Component;  
  8.   
  9. import security.entity.SysUser;  
  10. import security.entity.User;  
  11. import security.service.UserService;  
  12. @Component  
  13. public class CustomUserDetailsService implements UserDetailsService {  
  14.     @Autowired  //业务服务类  
  15.     private UserService userService;  
  16.   
  17.     @Override  
  18.     public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {  
  19.         //SysUser对应数据库中的用户表,是最终存储用户和密码的表,可自定义  
  20.         //本例使用SysUser中的name作为用户名:  
  21.         SysUser user = userService.findByName(userName);  
  22.         if (user == null) {  
  23.             throw new UsernameNotFoundException("UserName " + userName + " not found");  
  24.         }  
  25.         // SecurityUser实现UserDetails并将SysUser的name映射为username  
  26.         SecurityUser seu = new SecurityUser(user);  
  27.         return  seu;  
  28.     }  
  29.   
  30. }  

3、SecurityUser.java

[java] view plain copy
  1. package security.support;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Collection;  
  5. import java.util.HashSet;  
  6. import java.util.List;  
  7. import java.util.Set;  
  8.   
  9. import org.springframework.beans.factory.annotation.Autowired;  
  10. import org.springframework.security.core.GrantedAuthority;  
  11. import org.springframework.security.core.authority.SimpleGrantedAuthority;  
  12. import org.springframework.security.core.userdetails.UserDetails;  
  13.   
  14. import security.entity.SysRole<span style="font-family:Arial, Helvetica, sans-serif;">;</span>  
  15. import security.entity.SysUser;  
  16.   
  17. public class SecurityUser extends SysUser implements UserDetails {  
  18.     private static final long serialVersionUID = 1L;  
  19.     public SecurityUser(SysUser suser) {  
  20.         if(suser != null)  
  21.         {  
  22.             this.setId(suser.getId());  
  23.             this.setName(suser.getName());  
  24.             this.setEmail(suser.getEmail());  
  25.             this.setPassword(suser.getPassword());  
  26.             this.setDob(suser.getDob());  
  27.             this.setSysRoles(suser.getSysRoles());  
  28.         }         
  29.     }  
  30.       
  31.     @Override  
  32.     public Collection<? extends GrantedAuthority> getAuthorities() {  
  33.           
  34.         Collection<GrantedAuthority> authorities = new ArrayList<>();  
  35.         Set<SysRole> userRoles = this.getSysRoles();  
  36.           
  37.         if(userRoles != null)  
  38.         {  
  39.             for (SysRole role : userRoles) {  
  40.                 SimpleGrantedAuthority authority = new SimpleGrantedAuthority(role.getName());  
  41.                 authorities.add(authority);  
  42.             }  
  43.         }  
  44.         return authorities;  
  45.     }  
  46.   
  47.     @Override  
  48.     public String getPassword() {  
  49.         return super.getPassword();  
  50.     }  
  51.   
  52.     @Override  
  53.     public String getUsername() {  
  54.         return super.getName();  
  55.     }  
  56.   
  57.     @Override  
  58.     public boolean isAccountNonExpired() {  
  59.         return true;  
  60.     }  
  61.   
  62.     @Override  
  63.     public boolean isAccountNonLocked() {  
  64.         return true;  
  65.     }  
  66.   
  67.     @Override  
  68.     public boolean isCredentialsNonExpired() {  
  69.         return true;  
  70.     }  
  71.   
  72.     @Override  
  73.     public boolean isEnabled() {  
  74.         return true;  
  75.     }  
  76. }  

4、LoginSuccessHandler.java

[java] view plain copy
  1. package security.support;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.Set;  
  5.   
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServletRequest;  
  8. import javax.servlet.http.HttpServletResponse;  
  9.   
  10. import org.springframework.security.core.Authentication;  
  11. import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;  
  12.   
  13. import security.entity.SysRole;  
  14. import security.entity.SysUser;  
  15.   
  16. public class LoginSuccessHandler extends  
  17.         SavedRequestAwareAuthenticationSuccessHandler {  
  18.     @Override    
  19.     public void onAuthenticationSuccess(HttpServletRequest request,    
  20.             HttpServletResponse response, Authentication authentication) throws IOException,    
  21.             ServletException {    
  22.         //获得授权后可得到用户信息   可使用SUserService进行数据库操作  
  23.         SysUser userDetails = (SysUser)authentication.getPrincipal();    
  24.        /* Set<SysRole> roles = userDetails.getSysRoles();*/  
  25.         //输出登录提示信息    
  26.         System.out.println("管理员 " + userDetails.getName() + " 登录");    
  27.           
  28.         System.out.println("IP :"+getIpAddress(request));  
  29.                 
  30.         super.onAuthenticationSuccess(request, response, authentication);    
  31.     }    
  32.       
  33.     public String getIpAddress(HttpServletRequest request){      
  34.         String ip = request.getHeader("x-forwarded-for");      
  35.         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {      
  36.             ip = request.getHeader("Proxy-Client-IP");      
  37.         }      
  38.         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {      
  39.             ip = request.getHeader("WL-Proxy-Client-IP");      
  40.         }      
  41.         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {      
  42.             ip = request.getHeader("HTTP_CLIENT_IP");      
  43.         }      
  44.         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {      
  45.             ip = request.getHeader("HTTP_X_FORWARDED_FOR");      
  46.         }      
  47.         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {      
  48.             ip = request.getRemoteAddr();      
  49.         }      
  50.         return ip;      
  51.     }    
  52. }  
5、MvcConfig.java

[java] view plain copy
  1. package security;  
  2.   
  3. import org.springframework.context.annotation.Configuration;  
  4. import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;  
  5. import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;  
  6.   
  7. @Configuration  
  8. public class MvcConfig extends WebMvcConfigurerAdapter {  
  9.   
  10.     @Override  
  11.     public void addViewControllers(ViewControllerRegistry registry) {  
  12.         registry.addViewController("/home").setViewName("home");  
  13.         registry.addViewController("/").setViewName("home");  
  14.         registry.addViewController("/hello").setViewName("hello");  
  15.         registry.addViewController("/login").setViewName("login");  
  16.     }  
  17.   
  18. }  


6、在resource下面创建templates目录,然后放相关的html文件:

home.html

[html] view plain copy
  1. <!DOCTYPE html>  
  2. <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">  
  3.     <head>  
  4.         <title>Spring Security Example</title>  
  5.     </head>  
  6.     <body>  
  7.         <h1>Welcome!</h1>  
  8.           
  9.         <p>Click <a th:href="@{/hello}">here</a> to see a greeting.</p>  
  10.     </body>  
  11. </html>  
hello.html
[html] view plain copy
  1. <!DOCTYPE html>  
  2. <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"  
  3.       xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">  
  4.     <head>  
  5.         <title>Hello World!</title>  
  6.     </head>  
  7.     <body>  
  8.         <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>  
  9.         <form th:action="@{/logout}" method="post">  
  10.             <input type="submit" value="Sign Out"/>  
  11.         </form>  
  12.     </body>  
  13. </html>  
login.html
[html] view plain copy
  1. <!DOCTYPE html>  
  2. <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"  
  3.       xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">  
  4.     <head>  
  5.         <title>Spring Security Example </title>  
  6.     </head>  
  7.     <body>  
  8.         <div th:if="${param.error}">  
  9.             Invalid username and password.  
  10.         </div>  
  11.         <div th:if="${param.logout}">  
  12.             You have been logged out.  
  13.         </div>  
  14.         <form th:action="@{/login}" method="post">  
  15.             <div><label> User Name : <input type="text" name="username"/> </label></div>  
  16.             <div><label> Password: <input type="password" name="password"/> </label></div>  
  17.             <div><input type="submit" value="Sign In"/></div>  
  18.             <input type="checkbox" name="remember-me" value="true" th:checked="checked"/><p>Remember me</p>  
  19.         </form>  
  20.     </body>  
  21. </html>  
接下来是主类:MainApplication.java

[java] view plain copy
  1. package security;  
  2.   
  3. import org.springframework.boot.SpringApplication;  
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;  
  5. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;  
  6. import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;  
  7. import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;  
  8.   
  9. import security.entity.SysUser;  
  10. import security.entity.User;  
  11. import security.service.UserService;  
  12. import security.Appctx;  
  13.   
  14. @SpringBootApplication  
  15. public class MainApplication{  
  16.     public static void main(String[] args) {  
  17.         //SpringApplication.run(MainApplication.class, args);  
  18.         SpringApplication app=new SpringApplication(MainApplication.class);       
  19.           
  20.         Appctx.ctx=app.run(args);  
  21.         /*UserService suserService = (UserService) Appctx.ctx.getBean("suserService"); 
  22.         SysUser su= suserService.findByName("TEST"); 
  23.         BCryptPasswordEncoder bc=new BCryptPasswordEncoder(4);//将密码加密 可以先设置初始密码:000000  
  24.         su.setPassword(bc.encode(su.getPassword()));//然后使用密码为key值进行加密,运行主类后,会自动加密密码,可连接数据库查看。 
  25.         System.out.println("密码"+su.getPassword()); 
  26.         suserService.update(su);//运行一次后记得注释这段重复加密会无法匹配*/  
  27.     }  
  28. }  

Appctx.java

[java] view plain copy
  1. package security.support;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4.   
  5. public class Appctx {  
  6.     public static ApplicationContext ctx=null;   
  7.     public static Object getObject(String string){  
  8.         return ctx.getBean(string);  
  9.     }  
  10. }  

1. 运行,访问http://localhost:8080/hello,系统出现如下界面:

Spring boot+Spring Security 4配置整合实例

登陆成功后:

Spring boot+Spring Security 4配置整合实例

登陆拥有ADMIN权限的用户,可以进入/home

如果用户不具有权限,会出现以下:

Spring boot+Spring Security 4配置整合实例

好了,根据配置:.antMatchers("/hello").hasAuthority("ADMIN")。来进行权限控制,就到这里,下面,我们来根据数据库中的资源和权限的关系,进行授权和认证


1、CustomInvocationSecurityMetadataSourceService.java 参照流程图

[java] view plain copy
  1. /* 
  2.  * @(#) MyInvocationSecurityMetadataSourceService.java  2011-3-23 下午02:58:29 
  3.  * 
  4.  * Copyright 2011 by Sparta  
  5.  */  
  6.   
  7. package security.support;  
  8.   
  9. import java.util.ArrayList;  
  10. import java.util.Collection;  
  11. import java.util.HashMap;  
  12. import java.util.Iterator;  
  13. import java.util.List;  
  14. import java.util.Map;  
  15. import java.util.Map.Entry;  
  16. import java.util.Set;  
  17.   
  18. import javax.annotation.PostConstruct;  
  19.   
  20. import org.hibernate.Session;  
  21. import org.hibernate.SessionFactory;  
  22. import org.springframework.beans.factory.annotation.Autowired;  
  23. import org.springframework.context.ApplicationContext;  
  24. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  25. import org.springframework.security.access.ConfigAttribute;  
  26. import org.springframework.security.access.SecurityConfig;  
  27. import org.springframework.security.core.GrantedAuthority;  
  28. import org.springframework.security.core.context.SecurityContextHolder;  
  29. import org.springframework.security.core.userdetails.UserDetails;  
  30. import org.springframework.security.web.FilterInvocation;  
  31. import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;  
  32. import org.springframework.security.web.util.matcher.AntPathRequestMatcher;  
  33. import org.springframework.security.web.util.matcher.RequestMatcher;  
  34. import org.springframework.stereotype.Component;  
  35. import org.springframework.stereotype.Service;  
  36.   
  37. import security.dao.SResourceVODao;  
  38. import security.dao.SRoleDao;  
  39. import security.dao.SRoleVODao;  
  40. import security.entity.SRole;  
  41. import security.service.SResourceService;  
  42. import security.service.SRoleService;  
  43.   
  44. /** 
  45.  * 最核心的地方,就是提供某个资源对应的权限定义,即getAttributes方法返回的结果。 此类在初始化时,应该取到所有资源及其对应角色的定义。 
  46.  *  
  47.  */  
  48. @Service  
  49. public class CustomInvocationSecurityMetadataSourceService implements  
  50.         FilterInvocationSecurityMetadataSource {  
  51.       
  52.     @Autowired  
  53.     private SResourceVODao sResourceVODao;  
  54.       
  55.     @Autowired  
  56.     private SRoleVODao sRoleVODao;  
  57.       
  58.     private static Map<String, Collection<ConfigAttribute>> resourceMap = null;  
  59.   
  60.     /*public CustomInvocationSecurityMetadataSourceService(SResourceService sres,SRoleService sR) { 
  61.         this.sResourceService = sres; 
  62.         this.sRoleService = sR; 
  63.         loadResourceDefine(); 
  64.     }*/  
  65.     @PostConstruct<span style="color:#33cc00;">//<span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">  </span><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;line-height:25.1875px;"><span style="font-size:10px;">被@PostConstruct修饰的方法会在服务器加载Servle的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。</span></span></span>  
  66.     private void loadResourceDefine() {  <span style="color:#33cc00;"//一定要加上<span style="font-family:Arial, Helvetica, sans-serif;">@PostConstruct注解</span></span>  
  67.     <span style="color:#33cc00;">// 在Web服务器启动时,提取系统中的所有权限。</span>  
  68.         List<Map<String,Object>> list =sRoleVODao.findAll();  
  69.         List<String> query = new ArrayList<String>();  
  70.         if(list!=null && list.size()>0) {  
  71.             for(Map<String,Object> sr :list){  
  72.                 //String name = sr.get("name")    
  73.                 Object value = sr.get("name");  
  74.                 String name = String.valueOf(value);  
  75.                 query.add(name);  
  76.             }  
  77.         }  
  78.         <span style="color:#33cc00;">/* 
  79.          * 应当是资源为key, 权限为value。 资源通常为url, 权限就是那些以ROLE_为前缀的角色。 一个资源可以由多个权限来访问。 
  80.          * sparta 
  81.          */</span>  
  82.         resourceMap = new HashMap<String, Collection<ConfigAttribute>>();  
  83.   
  84.         for (String auth : query) {  
  85.             ConfigAttribute ca = new SecurityConfig(auth);  
  86.             //List<Map<String,Object>> query1 = sResourceVODao.findByRoleName(auth);  
  87.             List<String> query1 = new ArrayList<String>();  
  88.             List<Map<String, Object>>  list1 = sResourceVODao.findByRoleName(auth);  
  89.             if(list1!=null && list1.size()>0) {  
  90.                 for(Map<String, Object> map :list1){  
  91.                     Object value = map.get("resource_string");  
  92.                     String url = String.valueOf(value);  
  93.                     query1.add(url);  
  94.                 }  
  95.             }  
  96.             for (String res : query1) {  
  97.                 String url = res;  
  98.                   
  99.                 <span style="color:#33cc00;">/* 
  100.                  * 判断资源文件和权限的对应关系,如果已经存在相关的资源url,则要通过该url为key提取出权限集合,将权限增加到权限集合中。 
  101.                  * sparta 
  102.                  */</span>  
  103.                 if (resourceMap.containsKey(url)) {  
  104.   
  105.                     Collection<ConfigAttribute> value = resourceMap.get(url);  
  106.                     value.add(ca);  
  107.                     resourceMap.put(url, value);  
  108.                 } else {  
  109.                     Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();  
  110.                     atts.add(ca);  
  111.                     resourceMap.put(url, atts);  
  112.                 }  
  113.   
  114.             }  
  115.         }  
  116.   
  117.     }  
  118.   
  119.     @Override  
  120.     public Collection<ConfigAttribute> getAllConfigAttributes() {  
  121.          return new ArrayList<ConfigAttribute>();  
  122.     }  
  123. <span style="color:#33cc00;">  
  124.     // 根据URL,找到相关的权限配置。</span>  
  125.     @Override  
  126.     public Collection<ConfigAttribute> getAttributes(Object object)  
  127.             throws IllegalArgumentException {  
  128.         System.out.println("nwuidhwuiehdfu");  
  129.         <span style="color:#33cc00;">// object 是一个URL,被用户请求的url。</span>  
  130.         FilterInvocation filterInvocation = (FilterInvocation) object;  
  131.         if (resourceMap == null) {  
  132.             loadResourceDefine();  
  133.         }  
  134.         Iterator<String> ite = resourceMap.keySet().iterator();  
  135.         while (ite.hasNext()) {  
  136.             String resURL = ite.next();  
  137.              RequestMatcher requestMatcher = new AntPathRequestMatcher(resURL);  
  138.                 if(requestMatcher.matches(filterInvocation.getHttpRequest())) {  
  139.                 return resourceMap.get(resURL);  
  140.             }  
  141.         }  
  142.   
  143.         return null;  
  144.     }  
  145.     @Override  
  146.     public boolean supports(Class<?> arg0) {  
  147.   
  148.         return true;  
  149.     }  
  150.   
  151. }  
2、CustomAccessDecisionManager.java

[html] view plain copy
  1. /*  
  2.  * @(#) MyAccessDecisionManager.java  2011-3-23 下午04:41:12  
  3.  *  
  4.  * Copyright 2011 by Sparta   
  5.  */  
  6.   
  7. package security.support;  
  8.   
  9. import java.util.Collection;  
  10. import java.util.Iterator;  
  11.   
  12. import org.springframework.security.access.AccessDecisionManager;  
  13. import org.springframework.security.access.AccessDeniedException;  
  14. import org.springframework.security.access.ConfigAttribute;  
  15. import org.springframework.security.access.SecurityConfig;  
  16. import org.springframework.security.authentication.InsufficientAuthenticationException;  
  17. import org.springframework.security.core.Authentication;  
  18. import org.springframework.security.core.GrantedAuthority;  
  19. import org.springframework.stereotype.Component;  
  20. import org.springframework.stereotype.Service;  
  21.   
  22. <span style="color:#33cc00;">/**  
  23.  *AccessdecisionManager在Spring security中是很重要的。  
  24.  *  
  25.  *在验证部分简略提过了,所有的Authentication实现需要保存在一个GrantedAuthority对象数组中。   
  26.  *这就是赋予给主体的权限。 GrantedAuthority对象通过AuthenticationManager  
  27.  *保存到 Authentication对象里,然后从AccessDecisionManager读出来,进行授权判断。   
  28.  *  
  29.  *Spring Security提供了一些拦截器,来控制对安全对象的访问权限,例如方法调用或web请求。   
  30.  *一个是否允许执行调用的预调用决定,是由AccessDecisionManager实现的。   
  31.  *这个 AccessDecisionManager 被AbstractSecurityInterceptor调用,  
  32.  *它用来作最终访问控制的决定。 这个AccessDecisionManager接口包含三个方法:   
  33.  *  
  34.  void decide(Authentication authentication, Object secureObject,  
  35.     List<ConfigAttributeDefinition> config) throws AccessDeniedException;  
  36.  boolean supports(ConfigAttribute attribute);  
  37.  boolean supports(Class clazz);  
  38.    
  39.   从第一个方法可以看出来,AccessDecisionManager使用方法参数传递所有信息,这好像在认证评估时进行决定。   
  40.   特别是,在真实的安全方法期望调用的时候,传递安全Object启用那些参数。   
  41.   比如,让我们假设安全对象是一个MethodInvocation。   
  42.   很容易为任何Customer参数查询MethodInvocation,  
  43.   然后在AccessDecisionManager里实现一些有序的安全逻辑,来确认主体是否允许在那个客户上操作。   
  44.   如果访问被拒绝,实现将抛出一个AccessDeniedException异常。  
  45.   
  46.   这个 supports(ConfigAttribute) 方法在启动的时候被  
  47.   AbstractSecurityInterceptor调用,来决定AccessDecisionManager  
  48.   是否可以执行传递ConfigAttribute。   
  49.   supports(Class)方法被安全拦截器实现调用,  
  50.   包含安全拦截器将显示的AccessDecisionManager支持安全对象的类型。  
  51.  */</span>  
  52. @Service  
  53. public class CustomAccessDecisionManager implements AccessDecisionManager {  
  54.       
  55.     public void decide( Authentication authentication, Object object,   
  56.             Collection<ConfigAttribute> configAttributes)   
  57.         throws AccessDeniedException, InsufficientAuthenticationException{  
  58.         if( configAttributes == null ) {  
  59.             return ;  
  60.         }  
  61.           
  62.         Iterator<ConfigAttribute> ite = configAttributes.iterator();  
  63.           
  64.         while( ite.hasNext()){  
  65.             ConfigAttribute ca = ite.next();  
  66.             String needRole = ((SecurityConfig)ca).getAttribute();  
  67.               
  68.         <span style="color:#33cc00;">   //ga 为用户所被赋予的权限。 needRole 为访问相应的资源应该具有的权限。</span>  
  69.             for( GrantedAuthority ga: authentication.getAuthorities()){  
  70.                   
  71.                 if(needRole.trim().equals(ga.getAuthority().trim())){  
  72.   
  73.                     return;  
  74.                 }  
  75.                   
  76.             }  
  77.               
  78.         }  
  79.           
  80.         throw new AccessDeniedException("权限不足");  
  81.           
  82.     }  
  83.       
  84.     public boolean supports( ConfigAttribute attribute ){  
  85.         <span style="color:#ff0000;">return true;</span><span style="color:#33cc00;">//都要设为true</span>  
  86.   
  87.     }  
  88.       
  89.     public boolean supports(Class<?> clazz){  
  90.         <span style="color:#ff0000;">return true;</span><span style="color:rgb(51,204,0);font-family:Arial, Helvetica, sans-serif;">//都要设为true</span>  
  91.     }  
  92.       
  93.   
  94. }  

3、 MyFilterSecurityInterceptor.java

[java] view plain copy
  1. /* 
  2.  * @(#) MyFilterSecurityInterceptor.java  2011-3-23 上午07:53:03 
  3.  * 
  4.  * Copyright 2011 by Sparta  
  5.  */  
  6.   
  7. package security.support;  
  8.   
  9. import java.io.IOException;  
  10. import java.util.Collection;  
  11. import java.util.Map;  
  12.   
  13. import javax.annotation.PostConstruct;  
  14. import javax.servlet.Filter;  
  15. import javax.servlet.FilterChain;  
  16. import javax.servlet.FilterConfig;  
  17. import javax.servlet.ServletException;  
  18. import javax.servlet.ServletRequest;  
  19. import javax.servlet.ServletResponse;  
  20.   
  21. import org.springframework.beans.factory.annotation.Autowired;  
  22. import org.springframework.security.access.ConfigAttribute;  
  23. import org.springframework.security.access.SecurityMetadataSource;  
  24. import org.springframework.security.access.intercept.AbstractSecurityInterceptor;  
  25. import org.springframework.security.access.intercept.InterceptorStatusToken;  
  26. import org.springframework.security.authentication.AuthenticationManager;  
  27. import org.springframework.security.web.FilterInvocation;  
  28. import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;  
  29. import security.service.SResourceService;  
  30.   
  31. /** 
  32.  * 该过滤器的主要作用就是通过spring著名的IoC生成securityMetadataSource。 
  33.  * securityMetadataSource相当于本包中自定义的MyInvocationSecurityMetadataSourceService。 
  34.  * 该MyInvocationSecurityMetadataSourceService的作用提从数据库提取权限和资源,装配到HashMap中, 
  35.  * 供Spring Security使用,用于权限校验。 
  36.  * @author sparta 11/3/29 
  37.  * 
  38.  */  
  39. @Component  
  40. public class MySecurityFilter   
  41.     extends AbstractSecurityInterceptor  
  42.     implements Filter{  
  43.     @Autowired  
  44.     private CustomInvocationSecurityMetadataSourceService  mySecurityMetadataSource;  
  45.       
  46.     @Autowired  
  47.     private CustomAccessDecisionManager myAccessDecisionManager;  
  48.       
  49.     @Autowired  
  50.     private AuthenticationManager authenticationManager;  
  51.       
  52.       
  53.     @PostConstruct  
  54.     public void init(){  
  55.         super.setAuthenticationManager(authenticationManager);  
  56.         super.setAccessDecisionManager(myAccessDecisionManager);  
  57.     }  
  58.       
  59.     public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain)  
  60.     throws IOException, ServletException{  
  61.         FilterInvocation fi = new FilterInvocation( request, response, chain );  
  62.         invoke(fi);  
  63.           
  64.     }  
  65.   
  66.       
  67.     public Class<? extends Object> getSecureObjectClass(){  
  68.         return FilterInvocation.class;  
  69.     }  
  70.   
  71.       
  72.     public void invoke( FilterInvocation fi ) throws IOException, ServletException{  
  73.         System.out.println("filter..........................");  
  74.         InterceptorStatusToken  token = super.beforeInvocation(fi);  
  75.         try{  
  76.             fi.getChain().doFilter(fi.getRequest(), fi.getResponse());  
  77.         }finally{  
  78.             super.afterInvocation(token, null);  
  79.         }  
  80.           
  81.     }  
  82.           
  83.       
  84.     @Override  
  85.     public SecurityMetadataSource obtainSecurityMetadataSource(){  
  86.         System.out.println("filtergergetghrthetyetyetyetyj");  
  87.         return this.mySecurityMetadataSource;  
  88.     }  
  89.       
  90.     public void destroy(){  
  91.         System.out.println("filter===========================end");  
  92.     }  
  93.     public void init( FilterConfig filterconfig ) throws ServletException{  
  94.         System.out.println("filter===========================");  
  95.     }  
  96. }  

接下来修改一个类的 大家注意:
WebSecurityConfig.java

[java] view plain copy
  1. package security;  
  2.   
  3. import org.springframework.beans.factory.annotation.Autowired;  
  4. import org.springframework.boot.autoconfigure.security.SecurityProperties;  
  5. import org.springframework.boot.web.servlet.FilterRegistrationBean;  
  6. import org.springframework.context.annotation.Bean;  
  7. import org.springframework.context.annotation.Configuration;  
  8. import org.springframework.core.annotation.Order;  
  9. import org.springframework.security.authentication.AuthenticationManager;  
  10. import org.springframework.security.authentication.AuthenticationProvider;  
  11. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;  
  12. import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
  13. import org.springframework.security.config.annotation.web.builders.WebSecurity;  
  14. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;  
  15. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;  
  16. import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;  
  17. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;  
  18. import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;  
  19.   
  20. import security.support.CustomUserDetailsService;  
  21. import security.support.LoginSuccessHandler;  
  22. import security.support.MySecurityFilter;  
  23. @Configuration  
  24. @EnableWebSecurity  
  25. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {  
  26.       
  27.     @Autowired  
  28.     private MyFilterSecurityInterceptor mySecurityFilter;  
  29.       
  30.     @Autowired  
  31.     private CustomUserDetailsService customUserDetailsService;  
  32.       
  33.     @Override  
  34.     public AuthenticationManager authenticationManagerBean() throws Exception {  
  35.        
  36.     return super.authenticationManagerBean();  
  37.        
  38.     }  
  39.     //http://localhost:8080/login 输入正确的用户名密码 并且选中remember-me 则登陆成功,转到 index页面   
  40.     //再次访问index页面无需登录直接访问  
  41.     //访问http://localhost:8080/home 不拦截,直接访问,  
  42.     //访问http://localhost:8080/hello 需要登录验证后,且具备 “ADMIN”权限hasAuthority("ADMIN")才可以访问  
  43.     @Override  
  44.     protected void configure(HttpSecurity http) throws Exception {  
  45.         http  
  46.         .addFilterBefore(mySecurityFilter, FilterSecurityInterceptor.class)//在正确的位置添加我们自定义的过滤器  
  47.         .authorizeRequests()  
  48.         .antMatchers("/home").permitAll()  
  49.         .anyRequest().authenticated()  
  50.         //.antMatchers("/hello").hasAuthority("ADMIN")  
  51.         .and()  
  52.         .formLogin()  
  53.         .loginPage("/login")      
  54.         .permitAll()  
  55.         .successHandler(loginSuccessHandler())//code3  
  56.         .and()  
  57.         .logout()  
  58.         .logoutSuccessUrl("/home")  
  59.         .permitAll()  
  60.         .invalidateHttpSession(true)  
  61.         .and()  
  62.         .rememberMe()  
  63.         .tokenValiditySeconds(1209600);  
  64.     }  
  65.     @Override  
  66.         public void configure(WebSecurity web) throws Exception {  
  67.             super.configure(web);  
  68.     }  
  69.     @Autowired  
  70.     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {     
  71. //指定密码加密所使用的加密器为passwordEncoder()  
  72. //需要将密码加密后写入数据库   
  73.     auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());  
  74. //不删除凭据,以便记住用户  
  75.         auth.eraseCredentials(false);         
  76.     }  
  77.       
  78.     // Code5----------------------------------------------  
  79.     @Bean  
  80.     public BCryptPasswordEncoder passwordEncoder() {  
  81.         return new BCryptPasswordEncoder(4);  
  82.     }  
  83.   
  84.     // Code3----------------------------------------------  
  85.     @Bean  
  86.     public LoginSuccessHandler loginSuccessHandler(){  
  87.         return new LoginSuccessHandler();  
  88.     }  
  89. }  

ServletInitializer.java

[java] view plain copy
  1. package security;  
  2.   
  3. import javax.servlet.FilterRegistration;  
  4. import javax.servlet.ServletContext;  
  5. import javax.servlet.ServletException;  
  6.   
  7. import org.springframework.boot.builder.SpringApplicationBuilder;  
  8. import org.springframework.boot.web.support.SpringBootServletInitializer;  
  9. import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;  
  10.   
  11. public class ServletInitializer extends SpringBootServletInitializer {  
  12.   
  13.     @Override  
  14.     protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {  
  15.         return application.sources(MainApplication.class);  
  16.     }  
  17.       
  18.     @Override  
  19.     public void onStartup(ServletContext servletContext)  
  20.     throws ServletException {  
  21.      FilterRegistration.Dynamic openEntityManagerInViewFilter = servletContext.addFilter("openEntityManagerInViewFilter", OpenEntityManagerInViewFilter.class);  
  22.          openEntityManagerInViewFilter.setInitParameter("entityManagerFactoryBeanName","entityManagerFactory");  
  23.          openEntityManagerInViewFilter.addMappingForUrlPatterns(nullfalse"/*");  
  24.     super.onStartup(servletContext);  
  25.     }  
  26. }  

还有主类需要修改

[java] view plain copy
  1. package security;  
  2. import java.io.IOException;  
  3. import java.util.HashMap;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6. import java.util.Set;  
  7.   
  8. import javax.annotation.PostConstruct;  
  9.   
  10. import org.slf4j.Logger;  
  11. import org.slf4j.LoggerFactory;  
  12. import org.springframework.beans.factory.annotation.Autowired;  
  13. import org.springframework.boot.SpringApplication;  
  14. import org.springframework.boot.autoconfigure.EnableAutoConfiguration;  
  15. import org.springframework.boot.autoconfigure.SpringBootApplication;  
  16. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;  
  17. import org.springframework.web.method.HandlerMethod;  
  18. import org.springframework.web.servlet.mvc.method.RequestMappingInfo;  
  19. import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;  
  20. import security.entity.SysResource;  
  21. import security.service.SResourceService;  
  22. import csecurity.service.UserService;  
  23. import security.support.MySecurityFilter;  
  24.   
  25. @SpringBootApplication  
  26. @EnableAutoConfiguration(exclude = MyFilterSecurityInterceptor.class//注意  
  27. public class MainApplication{  
  28.       
  29.     @Autowired  
  30.     private SResourceService sresourceService;  
  31.       
  32.     private static final Logger log = LoggerFactory.getLogger(MainApplication.class);  
  33.     @PostConstruct  
  34.      public void initApplication() throws IOException {  
  35.          log.info("Running with Spring profile(s) : {}");   
  36.     }  
  37.        
  38.     public static void main(String[] args) {  
  39.         //SpringApplication.run(MainApplication.class, args);  
  40.         SpringApplication app=new SpringApplication(MainApplication.class);       
  41.         Appctx.ctx=app.run(args);  
  42.         /*UserService suserService = (UserService) Appctx.ctx.getBean("suserService"); 
  43.         SysUser su= suserService.findByName("user"); 
  44.         System.out.println("密码"+su.getPassword()); 
  45.         System.out.println("名字"+su.getName()); 
  46.         BCryptPasswordEncoder bc=new BCryptPasswordEncoder(4);//将密码加密 
  47.         su.setPassword(bc.encode(su.getPassword())); 
  48.         System.out.println("密码"+su.getPassword()); 
  49.         suserService.update(su);*/  
  50. }  
  51. }  

至此,我们spring security4就集成成功了