0

I'm trying to run the example from chapter 18 of the book Spring Security in Action (written by Laurentiu Spilca). It's about getting an access token from authorization server (here it is Keycloak) and then, operating on the resources that reside on a resource server (here it is implemented in Java using Spring Security). The problem is that any attempt to add fitness record leads to the following Internal Server Error:

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

Description:
The entire scenario is taking place on the same machine. In Keycloak (15.0.2), I have defined a fitnessapp client (my application), assigned to it a Client Scope with the same name (fitnessapp). I have set its access tokens to have a lifespan of 100 minutes.
Then I define a user with username 'bill', assigning to it password '12345' within the Credentials section for user: enter image description here Then I define the role fitnessuser in the Roles section. From the Role Mappings section of the selected user, I assign fitnessuser.
In order for book example to work properly, 3 additional properties need to be added to our JWT token: audience, username and roles
As depicted below, I have done that using the Mappers section of fitnessapp Client Scope, using corresponding names for them from left to right: enter image description here As there were no problems in obtaining the access token from Keycloak, I just wrapped it up in the previous sentence and didn't explain more about this step. This is the resource server configuration file that configures our TokenStore to use JwtTokenStore:

@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();  
    }  
}

This is the application.properties file that separates the resource server port (9090) from Keycloak (8080), sets the expose endpoint for public key as well as the audience:

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

Finally, the problem resides here in my POST request where it is meant to add fitness record to database but ends up in error: enter image description here P.S.: I have set a breakpoint in controller but it's never reached while debugging. So this problem is happening before even reaching the controller (probably in one of Spring Security filters). This is why I didn't see it necessary to provide any code from controller, service or repository here.

Geralt
  • 113
  • 9
  • I know this doesn't answer directly your question, but you are using deprecated stuff. Have a look [here](https://github.com/ch4mpy/spring-addons/tree/master/samples/tutorials) for very simple ways to configure resource-servers with latest boot versions. – ch4mp Aug 10 '22 at 18:07

1 Answers1

2

The thing is that endpoint /auth/realms/master/protocol/openid-connect/certs will return to you 2 keys

  • use: sig - responsible for token signature verification
  • use: enc - responsible for encryption

The app is complaining because it can not understand the second one. Since this is only book follow up and local development, you can navigate to Realm Settings -> Keys -> Providers inside Keycloak and remove provider that is responsible for use: enc.

I hope that the answer helps.

nemanja995
  • 36
  • 2