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:
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:
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:
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.