当前位置 : 首页 » 文章分类 :  开发  »  Spring-Security

Spring-Security

Spring Security 笔记

Spring Security 的底层是通过一系列的 Filter 来管理的,每个 Filter 都有其自身的功能,它们的顺序也非常重要。


SpringCloud Gateway 中使用 Spring Security

由于 SpringCloud Gateway 基于 WebFlux 并且不兼容 SpringMVC,因此对于 Security 的配置方式也跟普通 SpringBoot 项目中的配置方式不同。

配置 Spring Security,对所有 /actuator/** 进行 httpBasic 认证

  1. @EnableWebFluxSecurity
  2. @EnableGlobalMethodSecurity(prePostEnabled = true)
  3. public class SpringSecurityConfiguration {
  4. @Bean
  5. public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity httpSecurity) {
  6. httpSecurity.authorizeExchange()
  7. .pathMatchers("/actuator/**").authenticated()
  8. .anyExchange().permitAll()
  9. .and().httpBasic()
  10. .and().formLogin()
  11. .and().csrf().disable();
  12. return httpSecurity.build();
  13. }
  14. }

Springcloud Gateway 整合 Spring Security 配置与踩坑
https://blog.csdn.net/UserFrank/article/details/118281035

集成Spring Cloud Security和Spring Cloud Gateway
https://cloud.tencent.com/developer/article/2264289


httpBasic 认证的 API 调用传参方式

httpSecurity.httpBasic().and().formLogin();

在 Spring Security 中,通过 HTTP Basic Authentication 的方式进行认证,调用方在发送请求时需要在 header 中设置 Authorization 字段,其值为 “Basic “+ base64编码的用户名和密码(username:password),即 Basic base64(username:password)

具体如下:
1、将用户名和密码以 username:password 的形式进行拼接。
2、使用 Base64 对拼接后的字符串进行编码,得 dXNlcjpwYXNzd29yZA==
3、将编码后的字符串添加到 Authorization 字段中,并在其前面添加 Basic
例如
curl http://localhost:8181/v2/api-docs -H ‘Authorization: Basic dXNlcjpwYXNzd29yZA==’


默认配置

添加依赖后,不作任何配置,默认全部接口都需要认证才能访问,否则报错

  1. {
  2. "timestamp": "2023-02-03 15:07:54",
  3. "status": 403,
  4. "error": "Forbidden",
  5. "path": "/path-to-api"
  6. }
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-security</artifactId>
  4. </dependency>

HttpSecurity 配置

anyRequest 匹配所有请求路径
access SpringEl 表达式结果为 true 时可以访问
anonymous 匿名可以访问
denyAll 用户不能访问
fullyAuthenticated 用户完全认证可以访问(非remember-me下自动登录)
hasAnyAuthority 如果有参数,参数表示权限,则其中任何一个权限可以访问
hasAnyRole 如果有参数,参数表示角色,则其中任何一个角色可以访问
hasAuthority 如果有参数,参数表示权限,则其权限可以访问
hasIpAddress 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问
hasRole 如果有参数,参数表示角色,则其角色可以访问
permitAll 用户可以任意访问
rememberMe 允许通过remember-me登录的用户访问
authenticated 用户登录后可访问


CSRF 不支持 POST 导致 permitAll() 不起作用

httpSecurity.permitAll 并不会绕开 springsecurity 的过滤器验证,配置的 url 还是会通过 spring security 过滤器。
webSecurity.ignoring 是完全绕过了spring security 的所有 filter,相当于不走 spring security

  1. @Configuration
  2. public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {
  3. private static final String[] NEED_AUTH_URLS = {
  4. "/hello1",
  5. "/hello2/**"
  6. };
  7. @Override
  8. protected void configure(HttpSecurity httpSecurity) throws Exception {
  9. httpSecurity.authorizeRequests()
  10. .antMatchers(NEED_AUTH_URLS).authenticated()
  11. .anyRequest().permitAll()
  12. .and().formLogin()
  13. .and().httpBasic();
  14. }
  15. }

上面的配置并不能实现只认证某些接口,放行其他接口,全部接口都会经过 filter,导致 403 未授权,意味着已经登录认证成功(否则报401),但没有访问对应api的权限

打开debug日志,看到
Invalid CSRF token found for http://localhost:8080/path-to-api
org.springframework.security.web.csrf.CsrfFilter 中

原因:RESTful 技术与 CSRF(Cross-site request forgery 跨站请求伪造)的冲突造成的,CSRF 默认支持的方法: GET|HEAD|TRACE|OPTIONS,不支持POST。可以在security在配置中禁用

解决:
禁用 csrf

  1. @Override
  2. protected void configure(HttpSecurity httpSecurity) throws Exception {
  3. httpSecurity.authorizeRequests()
  4. .antMatchers(NEED_AUTH_URLS).authenticated() // 需要认证
  5. .anyRequest().permitAll() // 其他不需要认证
  6. .and().formLogin() // 开启表单登录
  7. .and().httpBasic() // 基础账号密码认证
  8. .and().csrf().disable(); // 关闭csrf
  9. }

上一篇 Tesseract

下一篇 Mockito

阅读
评论
912
阅读预计3分钟
创建日期 2023-02-03
修改日期 2024-03-03
类别
标签

页面信息

location:
protocol: http:
host: masikkk.com
hostname: masikkk.com
origin: http://masikkk.com
pathname: /article/Spring-Security/
href: http://masikkk.com/article/Spring-Security/
document:
referrer:
navigator:
platform: Linux x86_64
userAgent: Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)

评论