spring-security 将Keycloak用作授权服务器时资源服务器出现问题:“当前不支持enc(use)”

6mw9ycah  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(204)

我尝试运行《Spring Security in Action》一书第18章中的示例(作者:Laurentiu Spilca)。它是关于从授权服务器获取访问令牌的(这里是Keycloak)然后,对驻留在资源服务器上的资源进行操作(这里它是使用Spring Security在Java中实现的)。问题是任何添加健身记录的尝试都会导致以下内部服务器错误:

{
    "error": "server_error",
    "error_description": "enc (use) is currently not supported."
}

说明:

整个场景都发生在同一台机器上。在Keycloak(15.0.2)中,我定义了一个fitnessapp客户端(我的应用程序),并为它分配了一个同名的Client Scope(fitnessapp)。我将其访问令牌的生命周期设置为100分钟。
然后,我定义了一个用户名为“bill”的用户,并在用户的Credentials部分中为其分配了密码“12345”:

然后我在Roles部分定义角色fitnessuser。从所选用户的Role Mappings部分,我分配fitnessuser。
为了使book示例正常工作,需要向JWT标记中添加3个附加属性:* 受众、用户名和角色 *
如下所示,我使用fitnessapp Client Scope的Mappers部分,从左到右使用它们的相应名称来完成该操作:

由于从Keycloak获取访问令牌没有问题,所以我在前面的句子中就把它包起来了,没有对这一步做更多的解释。

@Configuration  
@EnableResourceServer  
@EnableGlobalMethodSecurity(prePostEnabled = true)  
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {  

    @Value("${claim.aud}")  
    private String claimAud;  

    @Value("${jwkSetUri}")  
    private String urlJwk;  

    @Override  
    public void configure(ResourceServerSecurityConfigurer resources) {  
        resources.tokenStore(tokenStore());  
        resources.resourceId(claimAud);    
    }  

    @Bean  
    public TokenStore tokenStore() {  
        return new JwkTokenStore(urlJwk);  
    }  

    @Override  
    public void configure(HttpSecurity http) throws Exception {  
        http.authorizeRequests()  
                .mvcMatchers(HttpMethod.DELETE, "/**").hasAuthority("fitnessadmin")  
                .anyRequest().authenticated();  
    }  
}

这是一个application.properties文件,它将资源服务器端口(9090)与Keycloak(8080)分开,并为公钥和受众设置公开端点:

server.port=9090  

spring.datasource.url=jdbc:mysql://localhost/spring?useLegacyDatetimeCode=false&serverTimezone=UTC  
spring.datasource.username=root  
spring.datasource.password=  
spring.datasource.initialization-mode=always  

claim.aud=fitnessapp  
jwkSetUri=http://localhost:8080/auth/realms/master/protocol/openid-connect/certs

最后,问题出现在我的POST请求中,该请求旨在将健身记录添加到数据库中,但最终出现错误:

**P.S.:**我在控制器中设置了一个断点,但是在调试过程中从未到达过它。因此,这个问题甚至在到达控制器之前就发生了(可能是在Spring Security过滤器中)。这就是为什么我认为没有必要在这里提供来自控制器、服务或存储库的任何代码。

8ulbf1ek

8ulbf1ek1#

问题是端点**/auth/realms/master/protocol/openid-connect/certs**将返回给您两个密钥

*用途:sig-负责令牌签名验证
*用途:enc-负责加密

应用程序正在抱怨,因为它不能理解第二个。由于这只是书的后续和本地开发,您可以导航到领域设置-〉密钥-〉提供程序在Keycloak中,并删除负责使用的提供程序:附录
我希望这个答案能有所帮助。

相关问题