Spring Security 忽略拦截,免登录,匿名访问
如果某个请求接口不需要登录认证,也就是不需要被Security拦截保护,有两种实现方式。
1.HttpSecurity设置该地址匿名访问
2.WebSecurityCustomizer直接过滤掉该接口,即该接口不走Spring Security过滤器链
一:HttpSecurity
HttpSecurity 认证的几个主要方法
authenticated() :只有已登录用户可以访问,未登录用户访问会返回403
anonymous() :只有未登录用户可以访问,已登录用户访问会返回403
permitAll() :登录用户和未登录用户都可以访问
anyRequest() :所有请求
antMatchers("/private/**") :符合private/** 格式的请求
formLogin() :提供form表单登录
httpBasic() :提供Http Basic登录
例如有如下需求需要实现
/private/** 只有已登录用户可以访问
/public/showProducts 所有用户都可以访问
/public/registerUser 只有未登录用户可以访问,已登录用户访问会返回403
任何其它请求,所有用户都可以访问
创建Controller API 接口
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class EcommerceController { @GetMapping("/private/showCart") public String showCart() { return "Show Cart"; } @GetMapping("/public/showProducts") public String listProducts() { return "List Products"; } @GetMapping("/public/registerUser") public String registerUser() { return "Register User"; } @GetMapping("/hello") public String hello() { return "hello"; } }
配置SecurityFilterChain如下
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; @Configuration //@EnableWebSecurity public class SecurityConfiguration{ //配置内存用户 @Bean public UserDetailsService userDetailsService() { InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); manager.createUser(User.withDefaultPasswordEncoder().username("admin").password("password").roles("ADMIN").build()); manager.createUser(User.withDefaultPasswordEncoder().username("user").password("abcd").roles("USER").build()); return manager; } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/private/**").authenticated() //所有请求 以/private开头的接口需要登录认证 .antMatchers("/public/showProducts").permitAll() //接口/public/showProducts 登录用户和非登录用户都可以访问 .antMatchers("/public/registerUser").anonymous() //接口/public/registerUser 只能匿名访问,即登录后再访问会返回403 .anyRequest().permitAll() //任何其它接口 都需要登录认证 .and() .formLogin() //提供表单登录 .and() .httpBasic(); return http.build(); } }
启动应用,测试
没有登陆时
访问http://localhost:8080/hello 可以正常显示
访问http://localhost:8080/public/showProducts 可以正常显示
访问http://localhost:8080/public/registerUser 可以正常显示
访问http://localhost:8080/private/showCart 会跳转登录,登录成功后会正常显示
登录之后
访问http://localhost:8080/hello 可以正常显示
访问http://localhost:8080/public/showProducts 可以正常显示
访问http://localhost:8080/public/registerUser 返回403
访问http://localhost:8080/private/showCart 会跳转登录,登录成功后会正常显示
二: 配置WebSecurityCustomizer实现免登录
使用WebSecurityCustomizer也可以实现免登录认证,原理是直接过滤掉该接口,即该接口不走Spring Security过滤器链。
WebSecurityCustomizer功能类似HttpSecurity.permitAll(),不能实现HttpSecurity.anonymous()
需求:
/public/** 所有用户都可以访问
其它接口需要登录认证
配置WebSecurityCustomizer如下
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; @Configuration public class SecurityConfiguration{ @Bean public WebSecurityCustomizer webSecurityCustomizer() { return (webSecurity) -> webSecurity .ignoring() .antMatchers("/public/*"); } }
启动应用,测试
未登录时
访问http://localhost:8080/hello 会跳转登录,登录成功后会正常显示
访问http://localhost:8080/public/showProducts 可以正常显示
访问http://localhost:8080/public/registerUser 可以正常显示
访问http://localhost:8080/private/showCart 会跳转登录,登录成功后会正常显示
登录之后
访问http://localhost:8080/hello 可以正常显示
访问http://localhost:8080/public/showProducts 可以正常显示
访问http://localhost:8080/public/registerUser 可以正常显示
访问http://localhost:8080/private/showCart 可以正常显示