我对 Spring Security 配置感到困惑。例如,我正在开发一个 Spring-boot 应用程序。在项目
resources/application.yml
中,我可以按如下方式配置它以与Keycloak(或任何其他OAuth2服务器)进行通信:
spring:
security:
oauth2:
client:
registration:
spring-app:
client-id: spring-app
client-secret: VWsQaq02oUYaWNzb51dKzACrF5QLgTm8
authorization-grant-type: authorization_code
scope: openid, profile, roles
redirect-uri: http://localhost:8080/login/oauth2/code/spring-app
provider:
spring-app:
issuer-uri: http://localhost:8383/realms/foo
如果我缩小上面的配置以突出显示我的问题的关键内容:
spring:
security:
oauth2:
client:
registration:
spring-app:
...
...
provider:
spring-app:
issuer-uri: http://localhost:8383/realms/foo
我基本上将我的项目配置为 OAuth2 client,并且我还告诉谁是 OAuth2 服务器提供商(在我的例子中是 Keycloak,但它可以是任何其他 OAuth2 服务器)。
但是如果我在同一个 spring-boot 项目中将配置完全更改为以下配置:
spring:
security:
oauth2:
resourceserver:
jwt:
jwk-set-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/protocol/openid-connect/certs
issuer-uri: http://localhost:8383/realms/foo
如您所见,上面的配置是一个 resourceserver
(资源服务器)配置,它将我的 spring-boot 应用程序视为资源服务器,而不是 OAuth2 上下文中的客户端。我的 spring-boot 控制器暴露的端点也受到具有此配置的 keycloak 的保护(我已经测试过),只要
issuer-uri
指向 keycloak uri。在使用 Spring Security 时,我很困惑什么时候应该为我的 spring-boot 项目进行
client 配置以及何时应该进行 resource server 配置?
我认为两者都有道理,因为我的 Spring 应用程序确实是一个在 Keycloak 中注册的OAuth2 客户端,而且我的 Spring 应用程序确实是一个资源服务器,它暴露了应受 OAuth2 流保护的端点。
有人可以帮我澄清一下什么时候使用哪个吗?预先感谢!
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web:3.2.3'
implementation 'org.springframework.boot:spring-boot-starter-security:3.2.3'
// oauth2 client
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client:3.2.3'
// oauth2 resource server
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.2.3'
...
oauth2Login
),安全性基于会话,这需要针对CSRF的保护。换句话说,当您使用
oauth2Login
向 Spring 应用程序发送请求时,请求授权是使用会话 cookie,而不是
Bearer
令牌进行的。此外,通常预计此类应用程序会以
302 redirect to login
响应对受保护资源的未经授权的请求。
Bearer
访问令牌的。通常预计此类应用程序会对受保护资源的未经授权的请求做出响应
401 unauthorized
。
oauth2Login
和
oauth2ResourceServer
的客户端,但由于两者之间的安全配置非常不同,在这种情况下,我配置两个单独的
Security(Web)Filterchain
。例如,我的 BFF 实例始终以这种方式配置,因为它本质上是客户端,但也公开 REST 端点,例如执行器端点。当资源服务器使用客户端凭据相互调用时,需要客户端依赖项和conf来获取此服务间调用中使用的新令牌。但不需要单独的安全过滤器链。
在配置为资源服务器的服务代表发起请求的资源所有者调用另一个资源服务器的情况下,它可以转发它收到的访问令牌。在这种情况下,调用者是其他服务的客户端,但不需要客户端 deps 和 conf:令牌是从安全上下文中获取的,而不是从授权服务器中获取的。
如果您愿意,您可能会从