如题:如何disable Spring Security?(不要问为什么有这种场景,问了也不知道...)方法很多,比如下面这种在Spring Boot 2中已经过期的(不要再用了):

security.basic.enabled: false
management.security.enabled: false

Spring Boot 2中比较常见的是类似下面这种方式:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  @Value("${security.enabled:true}")
  private boolean securityEnabled;

  @Override
  public void configure(WebSecurity web) throws Exception {
    if (!securityEnabled) {
      // security.enabled=false的时候,所有url都直接放行(注意WebSecurity的优先级高于HttpSecurity)
      web.ignoring().antMatchers("/**");
    }
  }

  // ...省略其它代码 
}

本文到此...可能...还没有结束。如果你的代码里面使用了@PreAuthorize@PostAuthorize,并且启用了(@EnableGlobalMethodSecurity(prePostEnabled = true)),那按照上述方式修改以后,会出现下面的异常:

org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:333)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:200)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:58)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)
    ... ...

也就是如果使用了@PreAuthorize@PostAuthorize,还需要忽略这些注解。怎么办呢?如下:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  @Value("${security.enabled:true}")
  private boolean securityEnabled;


  @Override
  public void configure(WebSecurity web) throws Exception {
    if (!securityEnabled) {
      web.ignoring().antMatchers("/**");
    }
  }

  // ...省略其它代码 

  /**
   * control @EnableGlobalMethodSecurity(prePostEnabled = true),to  solve AuthenticationCredentialsNotFoundException
   */
  @ConditionalOnProperty(prefix = "security", name = "enabled", havingValue = "true")
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  static class Dummy {
      // 什么也不做
  }
}

即搞一个空类/Bean来控制@EnableGlobalMethodSecurity(prePostEnabled = true),当security.enabled=false的时候,Dummy都没了,依托于它的注解自然也就没了。同理也可以控制@Secured等注解。至于本文提到的那些注解的功能就不赘述了,能看此文的自然都懂。

本文到此真的完了。