一、区别与联系
-
ResourceServerConfigurerAdapter被配置为不同的端点(参见antMatchers),而WebSecurityConfigurerAdapter不是。
这两个适配器之间的区别在于,RealServServer配置适配器使用一个特殊的过滤器来检查请求中的承载令牌,以便通过OAuth2对请求进行认证。WebSecurityConfigurerAdapter适配器用于通过会话对用户进行身份验证(如表单登录)
-
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
注意:
@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配置是可以覆盖优先级低的配置的。
- Ordered.HIGHEST_PRECEDENCE = -2^31-1
- WebSecurityConfigurerAdapter = 100 (Based on @Order(100) mentioned in Docs)
- **Access_Override_Order = Basic_Auth_Order -2 for **Security Properties
- **Access_Override_Order = Basic_Auth_Order -1 for **ManagementServerProperties
Basic_Auth_Order-2 = 2^31-7
- Basic_Auth_Order = Ordered.Lowest_Precendence -5 = 2^31-5
- 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
🙏感恩:谢谢您的打赏与支持!中间图片是我的微信公众号,扫码关注哦!