我正在使用Keycloak作为身份提供者。我有一个springboot-mvc-client应用程序,它注册为一个机密客户端,并配置为authorization_code授予类型。当我访问应用程序时,我被重定向到Keycloak登录页面,在成功登录后,我可以看到我的springboot-mvc客户端页面。一切正常工作。。
现在我有了另一个springboot-rest-api,它是一个ResourceServer。我已经将application.properties配置为:
server.port=8182
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8181/auth/realms/my-realm现在我想从我的springboot-rest-api中访问springboot-mvc-client.端点我用Authorization捕获了AccessToken并将其作为RestTemplate头传递,而且它也运行良好。
springboot-rest-api问题:如果我将我的confidential应用程序注册为具有confidential访问类型的客户端,然后尝试从springboot-mvc-client访问springboot-mvc-client,则API调用失败,响应是登录页面的HTML。
我的理解(这可能是错误的)是因为两个客户端都在同一个领域注册,所以我应该能够使用springboot-mvc-客户机身份验证获得的身份验证令牌调用springboot-rest-api端点。
如果我将springboot-rest-api访问类型从confidential更改为仅使用承载的,则附加的观察结果表明它工作正常。此外,我还可以使用springboot-rest-api授权为client_credentials获取accessToken,并使用它来调用springboot-rest-api端点。
问题是:使用一个机密客户端的访问令牌的不能访问另一个机密客户端的资源吗?
PS: 更新1:
在springboot-rest-api中添加了安全配置的springboot-mvc-client,运行良好。,通过使用从OAuth获得的相同的AccessToken,我可以调用springboot-rest-api端点。
我已经将以下配置添加到我的springboot-rest中:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeRequests()
.anyRequest().authenticated()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.cors()
.and()
.csrf()
.disable()
.oauth2ResourceServer()
.jwt();
}
}Update2:刚刚分享了另一个观察。
当springboot-rest被配置为只包含SecurityConfig文件中的spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8181/auth/realms/my-realm的ResourceServer时,就不需要进行上述的application.properties配置。但是,如果我想让springboot-rest同时充当OAuth Client + ResourceServer,那么我需要像上面提到的那样配置ResourceServer。
发布于 2021-10-15 21:04:20
简单地说,是。OAuth2定义了客户机(请求对受保护资源的授权访问)和资源服务器(承载受保护资源)之间的交互。访问是通过访问令牌授予的。客户端与另一个客户之间没有交互。
我认为它有助于OAuth2角色的推理,而不是应用程序,因为不一定有1到1的映射。
让我们首先考虑OAuth2授权代码流。
用户授权OAuth2客户端代表他们访问由OAuth2资源服务器承载的受保护资源。访问是通过访问令牌授予的。如果springboot-mvc客户机是OAuth2客户端,并且需要代表用户访问springboot-rest-api ,那么根据OAuth2授权代码流,springboot-rest-api将是OAuth2资源服务器。
OAuth2客户端不是访问令牌的接收方。他们从OAuth2授权服务器获取它们,并将它们转发到OAuth2资源服务器,以获得对受保护资源的授权访问。OAuth2资源服务器是这些访问令牌的接收方,它们负责读取和验证它们。因此,OAuth2客户机不会使用这样的访问令牌来获得对另一个OAuth2客户端的授权访问,因为后者既不会读取访问令牌,也不会验证其签名。这是关于纯OAuth2角色的。
如果springboot-rest需要对用户进行身份验证并代表该用户执行请求,那么我们将讨论OAuth2客户端角色。但是在前面的场景中,它已经扮演了OAuth2资源服务器的角色。因此,它必须同时扮演两个角色(当用户直接调用OAuth2客户端,当springboot-mvc客户机代表用户使用访问令牌调用OAuth2资源服务器时)。在这一点上,我可能会考虑引入某种边缘服务作为系统的入口点(例如,使用Spring )是否有意义,以便它是发挥OAuth2客户端角色并对用户进行身份验证的边缘服务,而系统中的其他应用程序则是OAuth2资源服务器。
如果我们代表用户谈论授权访问,那么是有效的。如果您正在寻找一种解决方案,springboot-mvc客户端代表它(而不是用户)调用(而不是用户),那么应该使用OAuth2客户端凭据,这样就不会有任何基于浏览器的登录流了。它通常用于服务到服务的通信(不涉及用户)。不过,我们仍然会从OAuth2客户端和OAuth2资源服务器的角度进行讨论。关于这一点,在Okta的博客上有一个不错的文章。
OAuth2框架中没有在两个OAuth2客户机之间定义流,因为定义OAuth2客户端的事实是,它希望对受保护的资源发出请求,根据定义,这些资源托管在OAuth2资源服务器上。
但是,您可以有两个应用程序,第一个应用程序扮演OAuth2客户机的角色,第二个应用程序同时扮演OAuth2客户端和OAuth2资源服务器的角色,这取决于所涉及的交互。
最后,您可能会发现以下有关Keycloak (来自文档)支持的客户端类型的有用信息。
https://stackoverflow.com/questions/69566434
复制相似问题