zoukankan      html  css  js  c++  java
  • 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中加入如下片段:

    1.   
    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 的工作机制:


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

    1. 当然要现在application.properties配置文件中配置好数据库。
    2. 开始配置相关的实体类 SysUser.java  SRole.java  SysResource.java SysResourceRole.java
      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. }  

      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. }  

      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. }  

      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会自动创建表。在表中插入几条测试数据:
    3. s_user表
    4. s_role表


         6.s_resource表


          7.s_resource_role表


    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配置类,其中不明所以的地方请参照上面的图,慢慢往下看。

    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

    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

    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

    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

    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

    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
    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
    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

    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

    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,系统出现如下界面:


    登陆成功后:

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

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

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


    1、CustomInvocationSecurityMetadataSourceService.java 参照流程图

    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

    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

    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

    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

    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. }  


    还有主类需要修改

    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就集成成功了,代码,博主已经验证,如有什么错误的地方,欢迎提出。谢谢!

    还有资源表中的url可以使用spring的RequestMappingHandlerMapping类自动扫描入库,具体请见http://blog.csdn.net/code__code/article/details/53886912

  • 相关阅读:
    算法第四章上机实践报告
    算法第三章作业
    算法第三章上机实践报告
    算法第二章总结
    关于stl::sort--算法第二章作业
    算法第二章上机实践报告
    算法第一章作业
    1
    2020-2021-1 20209302毕慧敏《Linux内核原理与分析》第十二周作业
    2020-2021-1 20209302毕慧敏《Linux内核原理与分析》第十一周作业
  • 原文地址:https://www.cnblogs.com/jpfss/p/9045724.html
Copyright © 2011-2022 走看看