关于WebSecurityConfigurerAdapter和ResourceServerConfigurerAdapter区别联系

一、区别与联系

  1. ResourceServerConfigurerAdapter被配置为不同的端点(参见antMatchers),而WebSecurityConfigurerAdapter不是。

    这两个适配器之间的区别在于,RealServServer配置适配器使用一个特殊的过滤器来检查请求中的承载令牌,以便通过OAuth2对请求进行认证。WebSecurityConfigurerAdapter适配器用于通过会话对用户进行身份验证(如表单登录)

  2. WebSecurityConfigurerAdapter是默认情况下spring security的http配置,ResourceServerConfigurerAdapter是默认情况下spring security oauth2的http配置 在ResourceServerProperties中,定义了它的order默认值为SecurityProperties.ACCESS_OVERRIDE_ORDER - 1;是大于1的,即WebSecurityConfigurerAdapter的配置的拦截要优先于ResourceServerConfigurerAdapter,优先级高的http配置是可以覆盖优先级低的配置的。

  3. 某些情况下如果需要ResourceServerConfigurerAdapter的拦截优先于WebSecurityConfigurerAdapter需要在配置文件中添加

security.oauth2.resource.filter-order=99

注意:

@EnableWebSecurity 注解标注的security类创建了一个WebSecurityConfigurerAdapter,且自带了硬编码的order=3,使用spring security而不是auth,即http保护

同我们在application.yml配置一样:

一、区别与联系1、ResourceServerConfigurerAdapter被配置为不同的端点(参见antMatchers),而WebSecurityConfigurerAdapter不是。   这两个适配器之间的区别在于,RealServServer配置适配器使用一个特殊的过滤器来检查请求中的承载令牌,以便通过OAuth2对请求进行认证。WebSecurityConfigurerAdapter适配器用于通过会话对用户进行身份验证(如表单登录)2、WebSecurityConfigurerAdapter是默认情况下spring security的http配置,ResourceServerConfigurerAdapter是默认情况下spring security oauth2的http配置 在ResourceServerProperties中,定义了它的order默认值为SecurityProperties.ACCESS_OVERRIDE_ORDER - 1;是大于1的,即WebSecurityConfigurerAdapter的配置的拦截要优先于ResourceServerConfigurerAdapter,优先级高的http配置是可以覆盖优先级低的配置的。3、某些情况下如果需要ResourceServerConfigurerAdapter的拦截优先于WebSecurityConfigurerAdapter需要在配置文件中添加security.oauth2.resource.filter-order=99注意:@EnableWebSecurity 注解标注的security类创建了一个WebSecurityConfigurerAdapter,且自带了硬编码的order=3,使用spring security而不是auth,即http保护同我们在application.yml配置一样:#安全校验security:  oauth2:    resource:      #本来spring security的基础上使用了spring security oauth2,控制/api下的请求      #但是spring security的资源控制和spring securtiy oauth2的资源控制会互相覆盖      #如果配置添加了security.oauth2.resource.filter-order=3,则使用spring security的控制,反之则为oauth2的控制      filter-order: 3总而言之,WebSecurityConfigurerAdapter优先级高于ResourceServerConfigurer,用于保护oauth相关的endpoints,同时主要作用于用户的登录(form login,Basic auth),WebSecurityConfigurerAdapter是默认情况下Spring security的http配置;ResourceServerConfigurerAdapter是默认情况下spring security oauth 的http配置。如下源码分析:@order(100)public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigurer<WebSecurity> {    protected void configure(AuthenticationManagerBuilder auth) throws Exception {          ......      }    protected void configure(WebSecurity web) throws Exception {          ......    }      protected void configure(HttpSecurity http) throws Exception {         ........    }    }ResourceServerConfigurerAdapter源码:public class ResourceServerConfigurerAdapter implements ResourceServerConfigurer {    @Override    protected void configure(ResourceServerSecurityConfigurer resources) throws Exception {          ......      }    @Override    protected void configure(HttpSecurity http) throws Exception {         ........    }    }    在ResourceServerProperties中,定义了他的order默认值为SecurityProperties.ACCESS_OVERRIDE_ORDER -1(值为 2^31-5-2)是大于100的,,也就是WebSecurityConfigurerAdapter的配置拦截要优先于ResourceServerConfigurerAdapter,优先级高的http配置是可以覆盖优先级低的配置的。
	1. Ordered.HIGHEST_PRECEDENCE = -2^31-1
	2. WebSecurityConfigurerAdapter = 100 (Based on @Order(100) mentioned in Docs)
 
		1. Access_Override_Order = Basic_Auth_Order -2 for Security Properties
		2. Access_Override_Order = Basic_Auth_Order -1 for ManagementServerPropertiesBasic_Auth_Order-2 = 2^31-7
	3. Basic_Auth_Order = Ordered.Lowest_Precendence -5 = 2^31-5
	4. Ordered.LOWEST_PRECEDENCE = 2^31
 
如果在一些特定的情况下需要ResourceServerConfigurerAdapter要高于WebSecurityConfigurerAdapter需要在配置文件中添加:security.oauth2.resource.filter-order=99或者是重写WebSecurityConfigurerAdapter的order配置:@Configuration@EbableWebSecurity@order(SecurityProperties.ACCESS_OVERRIDE_ORDER)public class SecurityConfigurerAdapter extends WebSecurityConfigurerAdapter{        .....  }按照以上情况可以,在auth授权认证的时候实现其中一个保护资源即可;
 
二、简单实现
 
WebSecurityConfigurerAdapter的简单实现:
 
package com.easystudy.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.easystudy.service.impl.UserDetailsServiceImpl;
/**
 * 安全服务配置(Spring Security http URL拦截保护):
 * URL强制拦截保护服务,可以配置哪些路径不需要保护,哪些需要保护。默认全都保护
 * 继承了WebSecurityConfigurerAdapter之后,再加上几行代码,我们就能实现以下的功能:
 * 1、要求用户在进入你的应用的任何URL之前都进行验证
 * 2、创建一个用户名是“user”,密码是“password”,角色是“ROLE_USER”的用户
 * 3、启用HTTP Basic和基于表单的验证
 * 4、Spring Security将会自动生成一个登陆页面和登出成功页面
 *
 * @EnableWebSecurity注解以及WebSecurityConfigurerAdapter一起配合提供基于web的security。
 * 继承了WebSecurityConfigurerAdapter之后,再加上几行代码,我们就能实现以下的功能:
 * 1、要求用户在进入你的应用的任何URL之前都进行验证
 * 2、创建一个用户名是“user”,密码是“password”,角色是“ROLE_USER”的用户
 * 3、启用HTTP Basic和基于表单的验证
 * 4、Spring Security将会自动生成一个登陆页面和登出成功页面
 * 默认页面:
 * 登录页面:/login
 * 注销页面:/login?logout
 * 错误页面:/login?error
 *
 * 与ResourceServerConfigurerAdapter区别
 * 1、ResourceServerConfigurerAdapter被配置为不同的端点(参见antMatchers),而WebSecurityConfigurerAdapter不是。
 *   这两个适配器之间的区别在于,RealServServer配置适配器使用一个特殊的过滤器来检查请求中的承载令牌,以便通过OAuth2对请求进行认证。
 *   WebSecurityConfigurerAdapter适配器用于通过会话对用户进行身份验证(如表单登录)
 * 2、WebSecurityConfigurerAdapter是默认情况下spring security的http配置,
 *   ResourceServerConfigurerAdapter是默认情况下spring security oauth2的http配置
 *   在ResourceServerProperties中,定义了它的order默认值为SecurityProperties.ACCESS_OVERRIDE_ORDER - 1;是大于1的,
 *   即WebSecurityConfigurerAdapter的配置的拦截要优先于ResourceServerConfigurerAdapter,优先级高的http配置是可以覆盖优先级低的配置的。
 *   某些情况下如果需要ResourceServerConfigurerAdapter的拦截优先于WebSecurityConfigurerAdapter需要在配置文件中添加
 *   security.oauth2.resource.filter-order=99
 */
@Configuration
//@EnableWebSecurity  // 创建了一个WebSecurityConfigurerAdapter,且自带了硬编码的order=3,使用spring security而不是auth
@Order(1) // 定义拦截器配置拦截次序,高于ResourceServerConfigurerAdapter
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
     // 自定义用户服务-校验用户是否合法,实现改接口,spring即可获取对应用户的角色、权限等信息,然后可以拦截URL判断是否具有对应权限
     // 具体是否可以访问对应URL配置可以在HttpSecurity中配置
     @Autowired
    private UserDetailsServiceImpl userDetailsService;
     
     /**
      * 密码加密器:将用户密码进行加密
      * @return
      */
     @Bean
    public PasswordEncoder passwordEncoder() {
           // 使用BCrypt进行密码的hash
        return new BCryptPasswordEncoder();
    }
     /**
      * 不定义没有password grant_type即密码授权模式(总共四种授权模式:授权码、implicat精简模式、密码、client credentials)
      */
     @Bean
     @Override
     public AuthenticationManager authenticationManagerBean() throws Exception {
           return super.authenticationManagerBean();
     }
     
     /**
      * 系统安全用户验证模式:
      * 1、使用内存模式创建验证
      * 2、使用数据库创建验证,实现userDetailsService接口即可
      */
     @Override
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
           // 将验证过程交给自定义
          auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
           
           // 内存创建用户:写死不利于项目实际应用
           // 验证的时候就是通过创建的用户名、密码、角色进行验证的
           // 创建一个用户名是“user”,密码是“password”,角色是“ROLE_USER”的用户
           // 创建一个用户名是“admin”,密码是“123456”,角色是“ROLE_ADMIN以及ROLE_USER”的用户
          //auth.inMemoryAuthentication().withUser("user").password("password").roles("USER")  // 在内存中的验证(memory authentication)叫作”user”的用户
          //.and().withUser("admin").password("123456").roles("ADMIN", "USER") ;                  // 在内存中的验证(memory authentication)叫作”admin”的管理员用户
     }
     /**
      * 如果有要忽略拦截校验的静态资源,在此处添加
      * 忽略任何以”/resources/”开头的请求,这和在XML配置http@security=none的效果一样
      */
     @Override
     public void configure(WebSecurity web) throws Exception {
           // TODO Auto-generated method stub
           web
           .ignoring()
           .antMatchers("/resources/**");  
     }
     /**
      * 允许对特定的http请求基于安全考虑进行配置,默认情况下,适用于所有的请求,
      * 但可以使用requestMatcher(RequestMatcher)或者其它相似的方法进行限制
      */
     @Override
     protected void configure(HttpSecurity http) throws Exception {
           // 如:将所有的url访问权限设定为角色名称为"ROLE_USER"
           // http.authorizeRequests().antMatchers("/").hasRole("USER").and().formLogin();
           
           // 启用HTTP Basic和基于表单的验证
           http.authorizeRequests()                                   // 定义权限配置
                     .anyRequest().authenticated()                   // 任何请求都必须经过认证才能访问
                .and()
                     .formLogin()
                     .permitAll()                                         // 允许任何人访问登录url
                .and()
                     .csrf().disable()                                    // 禁止跨域请求
                     .httpBasic();                                        // 进行http Basic认证
           
           // 无需访问权限
//         http.authorizeRequests()
//         .antMatchers("/**/test.*", "/**/*.css","/**/*.js","/**/images/*").permitAll()
//         // admin角色访问权限 ADMIN
//         .antMatchers("/admin/**").hasAuthority("ROLE_ADMIN")     //“/admin/”开头的URL必须要是管理员用户,譬如”admin”用户  
//         // user角色访问权限
//        .antMatchers("/**/operator/*.*").hasAuthority("ROLE_USER")
//         // 公共页面
//         .antMatchers("/signup","/about").permitAll()               // 任何人(包括没有经过验证的)都可以访问”/signup”和”/about”
//         // 其他请求授权
//         .anyRequest().authenticated()                                   // 其余所有请求全部需要鉴权认证
//         .and()
//         // login页面自定义配置都可以访问
//         .formLogin()                                                         // 使用Java配置默认值设置了基于表单的验证。使用POST提交到”/login”时,需要用”username”和”password”进行验证
//         .loginPage("/login")                                            // 注明了登陆页面,意味着用GET访问”/login”时,显示登陆页面
//         .permitAll()                                                         // 任何人(包括没有经过验证的)都可以访问”/login”和”/login?error”
//         .and()
//         .logout().permitAll();                                               // 任何人都可以登出页面都可以访问                             
     }
}
 
 
更全配置实例:
           // 无需访问权限
           http.authorizeRequests()
                     .antMatchers("/**/test.*", "/**/*.css","/**/*.js","/**/images/*").permitAll()
                     // admin角色访问权限 ADMIN
                     .antMatchers("/admin/**").hasAuthority("ROLE_ADMIN")     //“/admin/”开头的URL必须要是管理员用户,譬如”admin”用户  
                     // user角色访问权限
                     .antMatchers("/**/operator/*.*").hasAuthority("ROLE_USER")
                     // 公共页面
                     .antMatchers("/signup","/about").permitAll()              // 任何人(包括没有经过验证的)都可以访问”/signup”和”/about”
                     // 其他请求授权
                     .anyRequest().authenticated()                                   // 其余所有请求全部需要鉴权认证
                .and()
                // login页面自定义配置都可以访问
                .formLogin()                                                               // 使用Java配置默认值设置了基于表单的验证。使用POST提交到”/login”时,需要用”username”和”password”进行验证
                     .loginPage("/login")                                            // 注明了登陆页面,意味着用GET访问”/login”时,显示登陆页面
                     .permitAll()                                                         // 任何人(包括没有经过验证的)都可以访问”/login”和”/login?error”
                .and()
                     .logout().permitAll();                                               // 任何人都可以登出页面都可以访问  
 
改类的方法和类都有具体的说明,可以自己理解一下。
 
ResourceServerConfigurerAdapter的实现代码:
package com.easystudy.config;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
/**
 * 资源服务配置信息:资源服务器,保护受保护的资源(保护受保护的资源(Spring Security auth 的http 资源拦截和保护))
 * @author Administrator
 * 在ResourceServerProperties中,定义了它的order默认值为SecurityProperties.ACCESS_OVERRIDE_ORDER - 1;是一个非常大的值
 */
@Configuration
@EnableResourceServer           // oauth2分为资源服务和认证授权服务,可以分开,可以统一进程
public class ResourceServerConfig extends ResourceServerConfigurerAdapter{
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
        // 关闭跨域请求
        .csrf().disable()
             .exceptionHandling()
             .authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
        .and()
        .authorizeRequests()                                               // 定义权限配置
             // 允许/test和/oauth/token请求路径
             .antMatchers("/test","/oauth/token").permitAll()     // 这两个页面任何人都可以访问
             .anyRequest().authenticated()                           // 其他任何请求都需要验证
         .and()
          .formLogin()
                .permitAll()                                                    // 允许任何人访问登录url
        .and()
           .httpBasic();
    }
}
 
 
实例配置文件:
 
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.hl</groupId>
    <artifactId>spring_boot_demo</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>
 
    <name>spring_boot_demo</name>
    <description>learn Spring Boot</description>
 
    <parent>
        <!-- 添加Spring Boot 的父级依赖,可以省去version标签,因为parent已经为我们提供默认依赖了 -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
 
    <properties>
        <!--
            项目编码设为utf-8,为了防止乱码,建议大家开发过程中统一使用utf-8编码,从代码到工具都是,
            eclipse wrokspace设置utf-8和unix模式,其他文本编辑工具如notepad++等也是如此,统一
            编码环境很好地避免了乱码问题,同时也增加了与linux的兼容性,因为项目部署基本都是在linux环境上
        -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <thymeleaf.version>3.0.3.RELEASE</thymeleaf.version>
        <thymeleaf-extras-springsecurity4.version>3.0.2.RELEASE</thymeleaf-extras-springsecurity4.version>
        <thymeleaf-layout-dialect.version>2.1.1</thymeleaf-layout-dialect.version>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <!-- 添加Spring MVC依赖 -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 添加Thymeleaf支持,Spring Boot也将自动配置 -->  
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.6</version>
        </dependency>
        <!-- 使用webjar管理前端资源,此处引入bootstrap和jquery方便演示 -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>2.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.7</version>
        </dependency>
        <!-- 辅助定位静态资源 ,省略版本号-->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator</artifactId>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <verbose>true</verbose>
                    <overwrite>false</overwrite>
                </configuration>
            </plugin>
        </plugins>
        <!-- 强制将配置文件打到war包中 -->
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>
 
</project>

总而言之,WebSecurityConfigurerAdapter优先级高于ResourceServerConfigurer,用于保护oauth相关的endpoints,同时主要作用于用户的登录(form login,Basic auth),WebSecurityConfigurerAdapter是默认情况下Spring security的http配置;ResourceServerConfigurerAdapter是默认情况下spring security oauth 的http配置。

如下源码分析:

@order(100)
public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigurer<WebSecurity> {
 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 
          ......  
 
    }
 
 
    protected void configure(WebSecurity web) throws Exception {
 
          ......
 
    }  
 
 
    protected void configure(HttpSecurity http) throws Exception {
 
         ........
 
    }
 
}
 
 
ResourceServerConfigurerAdapter源码:
 
 
public class ResourceServerConfigurerAdapter implements ResourceServerConfigurer {
 
 
    @Override
 
    protected void configure(ResourceServerSecurityConfigurer resources) throws Exception 
    {
 
          ......  
 
    }
 
 
    @Override
 
    protected void configure(HttpSecurity http) throws Exception {
 
         ........
 
    }
 
    
 
}

在ResourceServerProperties中,定义了他的order默认值为SecurityProperties.ACCESS_OVERRIDE_ORDER -1(值为 2^31-5-2)是大于100的,,也就是WebSecurityConfigurerAdapter的配置拦截要优先于ResourceServerConfigurerAdapter,优先级高的http配置是可以覆盖优先级低的配置的

  1. Ordered.HIGHEST_PRECEDENCE = -2^31-1
  2. WebSecurityConfigurerAdapter = 100 (Based on @Order(100) mentioned in Docs)
    1. **Access_Override_Order = Basic_Auth_Order -2 for **Security Properties
    2. **Access_Override_Order = Basic_Auth_Order -1 for **ManagementServerProperties
      Basic_Auth_Order-2 = 2^31-7
  3. Basic_Auth_Order = Ordered.Lowest_Precendence -5 = 2^31-5
  4. Ordered.LOWEST_PRECEDENCE = 2^31

如果在一些特定的情况下需要ResourceServerConfigurerAdapter要高于WebSecurityConfigurerAdapter需要在配置文件中添加:

security.oauth2.resource.filter-order=99

或者是重写WebSecurityConfigurerAdapter的order配置:

@Configuration
 
@EbableWebSecurity
 
@order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
 
public class SecurityConfigurerAdapter extends WebSecurityConfigurerAdapter{
 
        .....  
 
}

按照以上情况可以,在auth授权认证的时候实现其中一个保护资源即可;

二、简单实现

WebSecurityConfigurerAdapter的简单实现:

package com.easystudy.config;
 
import org.springframework.beans.factory.annotation.Autowired;
 
import org.springframework.context.annotation.Bean;
 
import org.springframework.context.annotation.Configuration;
 
import org.springframework.core.annotation.Order;
 
import org.springframework.security.authentication.AuthenticationManager;
 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 
import org.springframework.security.config.annotation.web.builders.WebSecurity;
 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 
import org.springframework.security.crypto.password.PasswordEncoder;
 
import com.easystudy.service.impl.UserDetailsServiceImpl;
 
/**
 * 安全服务配置(Spring Security http URL拦截保护):
 * URL强制拦截保护服务,可以配置哪些路径不需要保护,哪些需要保护。默认全都保护
 * 继承了WebSecurityConfigurerAdapter之后,再加上几行代码,我们就能实现以下的功能:
 * 1、要求用户在进入你的应用的任何URL之前都进行验证
 * 2、创建一个用户名是“user”,密码是“password”,角色是“ROLE_USER”的用户
 * 3、启用HTTP Basic和基于表单的验证
 * 4、Spring Security将会自动生成一个登陆页面和登出成功页面
 *
 * @EnableWebSecurity注解以及WebSecurityConfigurerAdapter一起配合提供基于web的security。
 * 继承了WebSecurityConfigurerAdapter之后,再加上几行代码,我们就能实现以下的功能:
 * 1、要求用户在进入你的应用的任何URL之前都进行验证
 * 2、创建一个用户名是“user”,密码是“password”,角色是“ROLE_USER”的用户
 * 3、启用HTTP Basic和基于表单的验证
 * 4、Spring Security将会自动生成一个登陆页面和登出成功页面
 * 默认页面:
 * 登录页面:/login
 * 注销页面:/login?logout
 * 错误页面:/login?error
 *
 * 与ResourceServerConfigurerAdapter区别
 * 1、ResourceServerConfigurerAdapter被配置为不同的端点(参见antMatchers),而WebSecurityConfigurerAdapter不是。
 *   这两个适配器之间的区别在于,RealServServer配置适配器使用一个特殊的过滤器来检查请求中的承载令牌,以便通过OAuth2对请求进行认证。
 *   WebSecurityConfigurerAdapter适配器用于通过会话对用户进行身份验证(如表单登录)
 * 2、WebSecurityConfigurerAdapter是默认情况下spring security的http配置,
 *   ResourceServerConfigurerAdapter是默认情况下spring security oauth2的http配置
 *   在ResourceServerProperties中,定义了它的order默认值为SecurityProperties.ACCESS_OVERRIDE_ORDER - 1;是大于1的,
 *   即WebSecurityConfigurerAdapter的配置的拦截要优先于ResourceServerConfigurerAdapter,优先级高的http配置是可以覆盖优先级低的配置的。
 *   某些情况下如果需要ResourceServerConfigurerAdapter的拦截优先于WebSecurityConfigurerAdapter需要在配置文件中添加
 *   security.oauth2.resource.filter-order=99
 */
 
@Configuration
 
//@EnableWebSecurity  // 创建了一个WebSecurityConfigurerAdapter,且自带了硬编码的order=3,使用spring security而不是auth
 
@Order(1) // 定义拦截器配置拦截次序,高于ResourceServerConfigurerAdapter
 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
 
     // 自定义用户服务-校验用户是否合法,实现改接口,spring即可获取对应用户的角色、权限等信息,然后可以拦截URL判断是否具有对应权限
 
     // 具体是否可以访问对应URL配置可以在HttpSecurity中配置
 
     @Autowired
 
    private UserDetailsServiceImpl userDetailsService;
 
     
 
     /**
      * 密码加密器:将用户密码进行加密
      * @return
      */
 
     @Bean
 
    public PasswordEncoder passwordEncoder() {
 
           // 使用BCrypt进行密码的hash
 
        return new BCryptPasswordEncoder();
 
    }
 
     /**
      * 不定义没有password grant_type即密码授权模式(总共四种授权模式:授权码、implicat精简模式、密码、client credentials)
      */
 
     @Bean
 
     @Override
 
     public AuthenticationManager authenticationManagerBean() throws Exception {
 
           return super.authenticationManagerBean();
 
     }
 
     
 
     /**
      * 系统安全用户验证模式:
      * 1、使用内存模式创建验证
      * 2、使用数据库创建验证,实现userDetailsService接口即可
      */
 
     @Override
 
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 
           // 将验证过程交给自定义
 
          auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
 
           
 
           // 内存创建用户:写死不利于项目实际应用
 
           // 验证的时候就是通过创建的用户名、密码、角色进行验证的
 
           // 创建一个用户名是“user”,密码是“password”,角色是“ROLE_USER”的用户
 
           // 创建一个用户名是“admin”,密码是“123456”,角色是“ROLE_ADMIN以及ROLE_USER”的用户
 
          //auth.inMemoryAuthentication().withUser("user").password("password").roles("USER")  // 在内存中的验证(memory authentication)叫作”user”的用户
 
          //.and().withUser("admin").password("123456").roles("ADMIN", "USER") ;                  // 在内存中的验证(memory authentication)叫作”admin”的管理员用户
 
     }
 
     /**
      * 如果有要忽略拦截校验的静态资源,在此处添加
      * 忽略任何以”/resources/”开头的请求,这和在XML配置http@security=none的效果一样
      */
 
     @Override
 
     public void configure(WebSecurity web) throws Exception {
 
           // TODO Auto-generated method stub
 
           web
 
           .ignoring()
 
           .antMatchers("/resources/**");  
 
     }
 
     /**
      * 允许对特定的http请求基于安全考虑进行配置,默认情况下,适用于所有的请求,
      * 但可以使用requestMatcher(RequestMatcher)或者其它相似的方法进行限制
      */
 
     @Override
 
     protected void configure(HttpSecurity http) throws Exception {
 
           // 如:将所有的url访问权限设定为角色名称为"ROLE_USER"
 
           // http.authorizeRequests().antMatchers("/").hasRole("USER").and().formLogin();
 
           
 
           // 启用HTTP Basic和基于表单的验证
 
           http.authorizeRequests()                                   // 定义权限配置
 
                     .anyRequest().authenticated()                   // 任何请求都必须经过认证才能访问
 
                .and()
 
                     .formLogin()
 
                     .permitAll()                                         // 允许任何人访问登录url
 
                .and()
 
                     .csrf().disable()                                    // 禁止跨域请求
 
                     .httpBasic();                                        // 进行http Basic认证
 
           
 
           // 无需访问权限
 
//         http.authorizeRequests()
 
//         .antMatchers("/**/test.*", "/**/*.css","/**/*.js","/**/images/*").permitAll()
 
//         // admin角色访问权限 ADMIN
 
//         .antMatchers("/admin/**").hasAuthority("ROLE_ADMIN")     //“/admin/”开头的URL必须要是管理员用户,譬如”admin”用户  
 
//         // user角色访问权限
 
//        .antMatchers("/**/operator/*.*").hasAuthority("ROLE_USER")
 
//         // 公共页面
 
//         .antMatchers("/signup","/about").permitAll()               // 任何人(包括没有经过验证的)都可以访问”/signup”和”/about”
 
//         // 其他请求授权
 
//         .anyRequest().authenticated()                                   // 其余所有请求全部需要鉴权认证
 
//         .and()
 
//         // login页面自定义配置都可以访问
 
//         .formLogin()                                                         // 使用Java配置默认值设置了基于表单的验证。使用POST提交到”/login”时,需要用”username”和”password”进行验证
 
//         .loginPage("/login")                                            // 注明了登陆页面,意味着用GET访问”/login”时,显示登陆页面
 
//         .permitAll()                                                         // 任何人(包括没有经过验证的)都可以访问”/login”和”/login?error”
 
//         .and()
 
//         .logout().permitAll();                                               // 任何人都可以登出页面都可以访问                             
 
     }
 
}
 
 
 
 
 
更全配置实例:
 
           // 无需访问权限
 
           http.authorizeRequests()
 
                     .antMatchers("/**/test.*", "/**/*.css","/**/*.js","/**/images/*").permitAll()
 
                     // admin角色访问权限 ADMIN
 
                     .antMatchers("/admin/**").hasAuthority("ROLE_ADMIN")     //“/admin/”开头的URL必须要是管理员用户,譬如”admin”用户  
 
                     // user角色访问权限
 
                     .antMatchers("/**/operator/*.*").hasAuthority("ROLE_USER")
 
                     // 公共页面
 
                     .antMatchers("/signup","/about").permitAll()              // 任何人(包括没有经过验证的)都可以访问”/signup”和”/about”
 
                     // 其他请求授权
 
                     .anyRequest().authenticated()                                   // 其余所有请求全部需要鉴权认证
 
                .and()
 
                // login页面自定义配置都可以访问
 
                .formLogin()                                                               // 使用Java配置默认值设置了基于表单的验证。使用POST提交到”/login”时,需要用”username”和”password”进行验证
 
                     .loginPage("/login")                                            // 注明了登陆页面,意味着用GET访问”/login”时,显示登陆页面
 
                     .permitAll()                                                         // 任何人(包括没有经过验证的)都可以访问”/login”和”/login?error”
 
                .and()
 
                     .logout().permitAll();                                               // 任何人都可以登出页面都可以访问

改类的方法和类都有具体的说明,可以自己理解一下。

ResourceServerConfigurerAdapter的实现代码:

import javax.servlet.http.HttpServletResponse;
 
import org.springframework.context.annotation.Configuration;
 
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
 
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
 
/**
 * 资源服务配置信息:资源服务器,保护受保护的资源(保护受保护的资源(Spring Security auth 的http 资源拦截和保护))
 * @author Administrator
 * 在ResourceServerProperties中,定义了它的order默认值为SecurityProperties.ACCESS_OVERRIDE_ORDER - 1;是一个非常大的值
 */
 
@Configuration
 
@EnableResourceServer           // oauth2分为资源服务和认证授权服务,可以分开,可以统一进程
 
public class ResourceServerConfig extends ResourceServerConfigurerAdapter{
 
    @Override
 
    public void configure(HttpSecurity http) throws Exception {
 
        http
 
        // 关闭跨域请求
 
        .csrf().disable()
 
             .exceptionHandling()
 
             .authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
 
        .and()
 
        .authorizeRequests()                                               // 定义权限配置
 
             // 允许/test和/oauth/token请求路径
 
             .antMatchers("/test","/oauth/token").permitAll()     // 这两个页面任何人都可以访问
 
             .anyRequest().authenticated()                           // 其他任何请求都需要验证
 
         .and()
 
          .formLogin()
 
                .permitAll()                                                    // 允许任何人访问登录url
 
        .and()
 
           .httpBasic();
 
    }
 
}

实例配置文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
    <modelVersion>4.0.0</modelVersion>
 
 
 
    <groupId>com.hl</groupId>
 
    <artifactId>spring_boot_demo</artifactId>
 
    <version>1.0.0</version>
 
    <packaging>jar</packaging>
 
 
 
    <name>spring_boot_demo</name>
 
    <description>learn Spring Boot</description>
 
 
 
    <parent>
 
        <!-- 添加Spring Boot 的父级依赖,可以省去version标签,因为parent已经为我们提供默认依赖了 -->
 
        <groupId>org.springframework.boot</groupId>
 
        <artifactId>spring-boot-starter-parent</artifactId>
 
        <version>1.5.9.RELEASE</version>
 
        <relativePath /> <!-- lookup parent from repository -->
 
    </parent>
 
 
 
    <properties>
 
        <!--
            项目编码设为utf-8,为了防止乱码,建议大家开发过程中统一使用utf-8编码,从代码到工具都是,
            eclipse wrokspace设置utf-8和unix模式,其他文本编辑工具如notepad++等也是如此,统一
            编码环境很好地避免了乱码问题,同时也增加了与linux的兼容性,因为项目部署基本都是在linux环境上
        -->
 
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 
        <java.version>1.8</java.version>
 
        <thymeleaf.version>3.0.3.RELEASE</thymeleaf.version>
 
        <thymeleaf-extras-springsecurity4.version>3.0.2.RELEASE</thymeleaf-extras-springsecurity4.version>
 
        <thymeleaf-layout-dialect.version>2.1.1</thymeleaf-layout-dialect.version>
 
    </properties>
 
 
 
    <dependencies>
 
        <dependency>
 
            <groupId>org.springframework.boot</groupId>
 
            <artifactId>spring-boot-starter-test</artifactId>
 
            <scope>test</scope>
 
        </dependency>
 
        <dependency>
 
            <!-- 添加Spring MVC依赖 -->
 
            <groupId>org.springframework.boot</groupId>
 
            <artifactId>spring-boot-starter-web</artifactId>
 
        </dependency>
 
        <!-- 添加Thymeleaf支持,Spring Boot也将自动配置 -->  
 
        <dependency>
 
            <groupId>org.springframework.boot</groupId>
 
            <artifactId>spring-boot-starter-security</artifactId>
 
        </dependency>
 
        <dependency>
 
            <groupId>org.springframework.boot</groupId>
 
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
 
        </dependency>
 
        <dependency>
 
            <groupId>org.thymeleaf.extras</groupId>
 
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
 
        </dependency>
 
        <dependency>
 
            <groupId>mysql</groupId>
 
            <artifactId>mysql-connector-java</artifactId>
 
            <scope>runtime</scope>
 
        </dependency>
 
        <dependency>
 
            <groupId>org.mybatis.spring.boot</groupId>
 
            <artifactId>mybatis-spring-boot-starter</artifactId>
 
            <version>1.3.1</version>
 
        </dependency>
 
        <dependency>
 
            <groupId>com.alibaba</groupId>
 
            <artifactId>druid-spring-boot-starter</artifactId>
 
            <version>1.1.6</version>
 
        </dependency>
 
        <!-- 使用webjar管理前端资源,此处引入bootstrap和jquery方便演示 -->
 
        <dependency>
 
            <groupId>org.webjars</groupId>
 
            <artifactId>jquery</artifactId>
 
            <version>2.1.1</version>
 
        </dependency>
 
        <dependency>
 
            <groupId>org.webjars</groupId>
 
            <artifactId>bootstrap</artifactId>
 
            <version>3.3.7</version>
 
        </dependency>
 
        <!-- 辅助定位静态资源 ,省略版本号-->
 
        <dependency>
 
            <groupId>org.webjars</groupId>
 
            <artifactId>webjars-locator</artifactId>
 
        </dependency>
 
    </dependencies>
 
 
 
    <build>
 
        <plugins>
 
            <plugin>
 
                <groupId>org.springframework.boot</groupId>
 
                <artifactId>spring-boot-maven-plugin</artifactId>
 
            </plugin>
 
            <plugin>
 
                <groupId>org.mybatis.generator</groupId>
 
                <artifactId>mybatis-generator-maven-plugin</artifactId>
 
                <version>1.3.6</version>
 
                <configuration>
 
                    <verbose>true</verbose>
 
                    <overwrite>false</overwrite>
 
                </configuration>
 
            </plugin>
 
        </plugins>
 
        <!-- 强制将配置文件打到war包中 -->
 
        <resources>
 
            <resource>
 
                <directory>src/main/resources</directory>
 
            </resource>
 
            <resource>
 
                <directory>src/main/java</directory>
 
                <includes>
 
                    <include>**/*.xml</include>
 
                </includes>
 
                <filtering>false</filtering>
 
            </resource>
 
        </resources>
 
    </build>
 
 
 
</project>

🐞标题:关于WebSecurityConfigurerAdapter和ResourceServerConfigurerAdapter区别联系
👽作者:ruige
🐾地址:https://jjdhhc.com/articles/2020/11/07/1604720065998.html
🙏感恩:谢谢您的打赏与支持!中间图片是我的微信公众号,扫码关注哦!
支付宝支付 微信公众号 微信支付