Kih*_*ats 2 java spring-security spring-boot
我只需要了解Spring Security Configuration中的内容。使用下面的示例...
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests().antMatchers("/secret/**").authenticated()
.and()
.authorizeRequests().antMatchers("/**").permitAll();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
}
Run Code Online (Sandbox Code Playgroud)
configure(WebSecurity web)方法的目的是什么?
我不能只是添加/resources/**的configure(HttpSecurity http)方法,在这条线.authorizeRequests().antMatchers("/**", "/resources/**").permitAll();
应该不是它的工作相同,即允许所有的请求/resources/**没有任何身份验证?
sha*_*zin 13
当您使用HttpSecurity并尝试permitAll()请求时。您的请求将被允许从 Spring Security Filter Chain 访问。这是成本高昂的,因为会有其他请求也会进入此过滤器链,需要根据身份验证/授权来允许或禁止这些请求。
HttpSecurity.authorizeRequests().antMatchers("/**", "/resources/**").permitAll();
Run Code Online (Sandbox Code Playgroud)
但是当您使用时,任何请求都resources将完全绕过 Spring Security Filter Chain。这是安全的,因为您不需要任何身份验证/授权即可查看图像或读取 javascript 文件。
WebSecurity.ignoring().antMatchers("/resources/**");
Run Code Online (Sandbox Code Playgroud)
hat*_*oor 11
我想通过包含一些代码来为伟大的答案做出贡献。在 Spring Security 中,有 3 个 Bean 非常重要。根据它们的类型DelegatingFilterProxy,FilterChainProxy以及SecurityFilterChain。
DelegatingFilterProxy将过滤请求的工作委托给类型FilterChainProxy为 的bean springSecurityFilterChain,其FilterChainProxy配置如下:
@Bean(
name = {"springSecurityFilterChain"}
)
public Filter springSecurityFilterChain() throws Exception {
boolean hasConfigurers = this.webSecurityConfigurers != null && !this.webSecurityConfigurers.isEmpty();
if (!hasConfigurers) {
WebSecurityConfigurerAdapter adapter = (WebSecurityConfigurerAdapter)this.objectObjectPostProcessor.postProcess(new WebSecurityConfigurerAdapter() {
});
this.webSecurity.apply(adapter);
}
return (Filter)this.webSecurity.build();
}
Run Code Online (Sandbox Code Playgroud)
springSecurityFilterChain(或FilterChainProxy) 本身有一个SecurityFilterChain. 它本身有一个执行实际逻辑的实例SecurityFilterChain列表。Filter
每次我们扩展WebSecurityConfigurerAdapter和重写该configure(HttpSecurity httpSecurity)方法时,我们实际上创建了一个SecurityFilterChain将要使用的方法springSecurityFilterChain
如何从列表中springSecurityFilterChain选择合适的?SecurityFilterChain基于接口boolean matches(HttpServletRequest request)中定义的方法SecurityFilterChain。
因此HttpSecurity用于创建定制的SecurityFilterChain.
那么什么时候WebSecurity真正发挥作用呢?WebSecurity实际上允许我们定制springSecurityFilterChain(或FilterChainProxy)。看看是如何 springSecurityFilterChain创建的。
这是创建 bean 时调用performBuild的方法。WebSecurityspringSecurityFilterChain
@Override
protected Filter performBuild() throws Exception {
Assert.state(
!securityFilterChainBuilders.isEmpty(),
() -> "At least one SecurityBuilder<? extends SecurityFilterChain> needs to be specified. "
+ "Typically this done by adding a @Configuration that extends WebSecurityConfigurerAdapter. "
+ "More advanced users can invoke "
+ WebSecurity.class.getSimpleName()
+ ".addSecurityFilterChainBuilder directly");
int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size();
List<SecurityFilterChain> securityFilterChains = new ArrayList<>(
chainSize);
for (RequestMatcher ignoredRequest : ignoredRequests) {
securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest));
}
for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {
securityFilterChains.add(securityFilterChainBuilder.build());
}
FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
if (httpFirewall != null) {
filterChainProxy.setFirewall(httpFirewall);
}
filterChainProxy.afterPropertiesSet();
Filter result = filterChainProxy;
if (debugEnabled) {
logger.warn("\n\n"
+ "********************************************************************\n"
+ "********** Security debugging is enabled. *************\n"
+ "********** This may include sensitive information. *************\n"
+ "********** Do not use in a production system! *************\n"
+ "********************************************************************\n\n");
result = new DebugFilter(filterChainProxy);
}
postBuildAction.run();
return result;
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,当 Spring 想要将每个Spring 注册SecurityFilterChain到bean 中时,Spring 将在列表的开头 添加一个自定义实现 。springSecurityFilterChainweb.ignoring()....DefaultSecurityFilterChainSecurityFilterChain
当请求出现时springSecurityFilterChain,将检查其列表,SecurityFilterChain以便将过滤作业委托给该请求SecurityFilterChain。springSecurityFilterChain将调用match每个方法 SecurityFilterChain。如果请求 URL 以“/resources/**”开头,则将过滤请求的工作委托给列表开头Spring的实例以及通过此行添加的自定义实例:DefaultSecurityFilterChainSecurityFilterChain
for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {
securityFilterChains.add(securityFilterChainBuilder.build());
}
Run Code Online (Sandbox Code Playgroud)
完全被忽略了。
WebSecurity ignoring()方法的常规用法省略了Spring Security,并且Spring Security的功能均不可用。WebSecurity基于HttpSecurity。
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**")
.antMatchers("/publics/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/publics/**").hasRole("USER") // no effect
.anyRequest().authenticated();
}
Run Code Online (Sandbox Code Playgroud)
上面的示例中的WebSecurity让Spring忽略/resources/**和/publics/**。因此.antMatchers("/publics/**").hasRole("USER"),不考虑 HttpSecurity中的。
这将完全省略来自安全过滤器链的请求模式。请注意,与此路径匹配的所有内容都将不应用身份验证或授权服务,并且可以自由访问。
configure(HttpSecurity)允许基于选择匹配在资源级别上配置基于Web的安全性-例如,以下示例将以URL开头的URL限制为/admin/具有ADMIN角色的用户,并声明需要成功进行身份验证的所有其他URL 。
configure(WebSecurity)用于影响全局安全性的配置设置(忽略资源,设置调试模式,通过实现自定义防火墙定义拒绝请求)。例如,以下方法将导致以身份验证为开头的所有请求/resources/都被忽略。
| 归档时间: |
|
| 查看次数: |
1007 次 |
| 最近记录: |