insufficient_scope response from userinfo endpoint and missing scopes in jwt token - spring-boot

After I migrated the Spring Authorization Server from 0.3.1 to 1.0.0, I found that the userInfo endpoint returns 403: insufficient_scope, after verifying the login process between the two versions I found that the endpoint POST oauth2/token is not returning the scope also the jwt token does not contain the scope, but the scope parameter in the URL is already mentioned while trying to login.
I am using the following configurations:
registeredClient = RegisteredClient.withId(new ObjectId().toString())
.clientId(oauthClient)
.clientSecret(passwordEncoder().encode(oauthClientSecret))
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST)
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.clientAuthenticationMethod(ClientAuthenticationMethod.NONE)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.redirectUris(uris -> uris.addAll(redirectUris))
.scope(OidcScopes.OPENID)
.scope(OidcScopes.PROFILE)
.tokenSettings(TokenSettings
.builder()
.accessTokenTimeToLive(Duration.ofHours(8))
.build())
.clientSettings(ClientSettings
.builder()
.requireProofKey(true)
.requireAuthorizationConsent(false)
.build())
.build();
And this is the Http configurations:
SecurityFilterChain securityFilterChain = http
.authorizeHttpRequests(authorizeRequests -> authorizeRequests
.requestMatchers(WELL_KNOWN_OPENID_CONFIGURATION).permitAll()
.requestMatchers("/logout-success").permitAll()
.requestMatchers("/api/health/status").permitAll()
.requestMatchers("/assets/**", "/webjars/**", "/login").permitAll()
.anyRequest().authenticated())
.formLogin(form -> form
.loginPage("/login")
.failureUrl("/login-error")
.usernameParameter("username")
.passwordParameter("password")
.permitAll())
.logout()
.logoutSuccessUrl("/logout-success")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.and()
.build();
I am using these URLs to test the login flow:
http://localhost:9000/oauth2/authorize?scope=openid&response_type=code&client_id=<client_id>&code_challenge=<code_challenge>&code_challenge_method=S256&redirect_uri=https://frontlocal:4600
http://localhost:9000/oauth2/token?grant_type=authorization_code&scope=openid&code=<code>&code_verifier=<code_verifer>&client_id=<client_id>&redirect_uri=https://frontlocal:4600
UPDATE
2023-01-26T20:30:11.030+01:00 TRACE 150437 --- [io-9000-exec-10] o.s.security.web.FilterChainProxy : Invoking OAuth2TokenEndpointFilter (20/23)
2023-01-26T20:30:11.031+01:00 TRACE 150437 --- [io-9000-exec-10] o.s.security.web.FilterChainProxy : Invoking OAuth2TokenIntrospectionEndpointFilter (21/23)
2023-01-26T20:30:11.031+01:00 TRACE 150437 --- [io-9000-exec-10] o.s.security.web.FilterChainProxy : Invoking OAuth2TokenRevocationEndpointFilter (22/23)
2023-01-26T20:30:11.031+01:00 TRACE 150437 --- [io-9000-exec-10] o.s.security.web.FilterChainProxy : Invoking OidcUserInfoEndpointFilter (23/23)
2023-01-26T20:30:11.031+01:00 TRACE 150437 --- [io-9000-exec-10] o.s.s.authentication.ProviderManager : Authenticating request with OidcUserInfoAuthenticationProvider (1/13)
2023-01-26T20:30:13.819+01:00 TRACE 150437 --- [io-9000-exec-10] a.o.a.OidcUserInfoAuthenticationProvider : Retrieved authorization with access token
2023-01-26T20:30:13.821+01:00 DEBUG 150437 --- [io-9000-exec-10] .s.a.DefaultAuthenticationEventPublisher : No event was found for the exception org.springframework.security.oauth2.core.OAuth2AuthenticationException
2023-01-26T20:30:13.822+01:00 TRACE 150437 --- [io-9000-exec-10] s.s.o.s.a.o.w.OidcUserInfoEndpointFilter : User info request failed: [insufficient_scope]
org.springframework.security.oauth2.core.OAuth2AuthenticationException: null
at org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcUserInfoAuthenticationProvider.authenticate(OidcUserInfoAuthenticationProvider.java:99) ~[spring-security-oauth2-authorization-server-1.0.0.jar:1.0.0]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-6.0.1.jar:6.0.1]
at org.springframework.security.authentication.ObservationAuthenticationManager.lambda$authenticate$1(ObservationAuthenticationManager.java:53) ~[spring-security-core-6.0.1.jar:6.0.1]
at io.micrometer.observation.Observation.observe(Observation.java:559) ~[micrometer-observation-1.10.2.jar:1.10.2]
at org.springframework.security.authentication.ObservationAuthenticationManager.authenticate(ObservationAuthenticationManager.java:52) ~[spring-security-core-6.0.1.jar:6.0.1]
at org.springframework.security.oauth2.server.authorization.oidc.web.OidcUserInfoEndpointFilter.doFilterInternal(OidcUserInfoEndpointFilter.java:116) ~[spring-security-oauth2-authorization-server-1.0.0.jar:1.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.3.jar:6.0.3]
at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:186) ~[spring-security-web-6.0.1.jar:6.0.1]
at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:173) ~[spring-security-web-6.0.1.jar:6.0.1]
at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:134) ~[spring-security-web-6.0.1.jar:6.0.1]
at org.springframework.security.oauth2.server.authorization.web.OAuth2TokenRevocationEndpointFilter.doFilterInternal(OAuth2TokenRevocationEndpointFilter.java:103) ~[spring-security-oauth2-authorization-server-1.0.0.jar:1.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.3.jar:6.0.3]
at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:186) ~[spring-security-web-6.0.1.jar:6.0.1]
at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:173) ~[spring-security-web-6.0.1.jar:6.0.1]
at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:134) ~[spring-security-web-6.0.1.jar:6.0.1]
at org.springframework.security.oauth2.server.authorization.web.OAuth2TokenIntrospectionEndpointFilter.doFilterInternal(OAuth2TokenIntrospectionEndpointFilter.java:106) ~[spring-security-oauth2-authorization-server-1.0.0.jar:1.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.3.jar:6.0.3]
at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:186) ~[spring-security-web-6.0.1.jar:6.0.1]
at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:173) ~[spring-security-web-6.0.1.jar:6.0.1]
at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:134) ~[spring-security-web-6.0.1.jar:6.0.1]
at org.springframework.security.oauth2.server.authorization.web.OAuth2TokenEndpointFilter.doFilterInternal(OAuth2TokenEndpointFilter.java:147) ~[spring-security-oauth2-authorization-server-1.0.0.jar:1.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.3.jar:6.0.3]
...
...
2023-01-26T20:30:13.827+01:00 TRACE 150437 --- [io-9000-exec-10] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match request to [Is Secure]

Add openid scope in spring-authorization-server/samples/messages-client/src/main/resources/application.yml
messaging-client-authorization-code:
provider: spring
client-id: messaging-client
client-secret: secret
authorization-grant-type: authorization_code
redirect-uri: "http://127.0.0.1:8080/authorized"
scope: openid, message.read,message.write
client-name: messaging-client-authorization-code
Here is the sample http request/response:
GET http://127.0.0.1:9000/userinfo
Authorization: Bearer <your token>
###
{
"sub": "user1"
}
Works with version 1.0.0 of spring-authorization-server

Related

Spring Authorization Server | /userinfo endpoint returns 401 Unauthorized Error

I'm trying to use Spring Authorization Server for authorizing users, but I have a problem with /userinfo endpoint, it's always returning 401 Unauthorized Error.
My /userinfo request looks like:
GET /userinfo HTTP/1.1
Host: localhost:8080
Authorization: Bearer eyJraWQiOiIyMTIxNjAzNC1kYTc4LTRlMTQtODI3Ni1lNzlmM2NlZDM3NzYiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImF1ZCI6ImN5cHJlc3MtY2xpZW50LWlkIiwibmJmIjoxNjQ2MzI2Mzc2LCJzY29wZSI6WyJvcGVuaWQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODAiLCJleHAiOjE2NDYzMjgxNzYsImlhdCI6MTY0NjMyNjM3Nn0.aJsCVLoszgi2uCq6Jd9ov83QZFsqN1HK7-sE7Lbs11APRP1cHRYV2hlnrt7i7znMMquWsIfutiVlwOlPzX-lDJpNgthHkqVlIplrIFQdvCT6FTXO7V8dnyyHFhPbnPdYtWHnFoES3gpEazKD8IHnxuvYz75D98EcU9pOFH7zwqxh7t3uhvDXzijjdM59C_94zng2ufCCRmWf0NZd9uj1M9Y8iz1SI_fNjBbkwhe8ZecN6GGX9BPkuaWc_WB4OP8nANIkGgEpf-NlEoitrRPBDVwB-yAXKr8DV6c6Nb-AnGj-ogyjmdLBRE0tFG2mH6mHyplJYnQPzJjfOx_mqV9U0A
My Spring Authorization Server configuration:
#EnableWebSecurity
public class SpringSecurityConfiguration {
#Bean
public UserDetailsService users() {
// #formatter:off
UserDetails user = User.withUsername("admin").password("password").roles("ADMIN").build();
return new InMemoryUserDetailsManager(user);
}
#Bean
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
// defining security for other endpoints of your application including the
// #formatter:off
http.authorizeRequests(authorizeRequest -> authorizeRequest.anyRequest().authenticated())
.formLogin(Customizer.withDefaults());
// #formatter:on
return http.build();
}
}
#Configuration
public class AuthorizationServerConfiguration {
#Bean
public OAuth2AuthorizationConsentService authorizationConsentService() {
return new InMemoryOAuth2AuthorizationConsentService();
}
#Bean
#Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
// Defining security for the default endpoints of an Authorization Server
applyDefaultSecurity(http);
return http.cors().configurationSource(corsConfigurationSource()).and().formLogin(Customizer.withDefaults())
.build();
}
#Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("http://localhost:3000");
config.addAllowedHeader("*");
config.addAllowedHeader("authorization");
config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PUT");
config.addAllowedMethod("TRACE");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/.well-known/openid-configuration", config);
source.registerCorsConfiguration("/oauth2/token", config);
source.registerCorsConfiguration("/userinfo", config);
source.registerCorsConfiguration("userinfo", config);
source.registerCorsConfiguration("/oauth2/authorize", config);
source.registerCorsConfiguration("/oauth2/jwks", config);
return source;
}
#Bean
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("cypress-client-id").clientAuthenticationMethod(ClientAuthenticationMethod.NONE)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE).tokenSettings(tokenSettings())
.redirectUri("http://localhost:3000/signin/callback")
.redirectUri("http://localhost:3000/silent/callback").scope(OPENID).scope("offline_access")
.clientSettings(ClientSettings.builder().requireProofKey(true).build()).build();
return new InMemoryRegisteredClientRepository(registeredClient);
}
#Bean
public TokenSettings tokenSettings() {
// #formatter:off
return TokenSettings.builder().accessTokenTimeToLive(Duration.ofMinutes(30L)).build();
// #formatter:on
}
}
The stake trace:
2022-03-03 18:08:48.875 TRACE 13257 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking SecurityContextHolderAwareRequestFilter (17/25)
2022-03-03 18:08:48.876 TRACE 13257 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking AnonymousAuthenticationFilter (18/25)
2022-03-03 18:08:49.037 TRACE 13257 --- [nio-8080-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=E12CB3A032D3C0C442783899676963FC], Granted Authorities=[ROLE_ANONYMOUS]]
2022-03-03 18:08:49.037 TRACE 13257 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking SessionManagementFilter (19/25)
2022-03-03 18:08:49.204 TRACE 13257 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking ExceptionTranslationFilter (20/25)
2022-03-03 18:08:49.360 TRACE 13257 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking FilterSecurityInterceptor (21/25)
2022-03-03 18:08:49.360 TRACE 13257 --- [nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : Did not re-authenticate AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=E12CB3A032D3C0C442783899676963FC], Granted Authorities=[ROLE_ANONYMOUS]] before authorizing
2022-03-03 18:08:49.360 TRACE 13257 --- [nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : Authorizing filter invocation [GET /userinfo] with attributes [authenticated]
2022-03-03 18:08:49.360 TRACE 13257 --- [nio-8080-exec-2] o.s.s.w.a.expression.WebExpressionVoter : Voted to deny authorization
2022-03-03 18:08:49.361 TRACE 13257 --- [nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : Failed to authorize filter invocation [GET /userinfo] with attributes [authenticated] using AffirmativeBased [DecisionVoters=[org.springframework.security.web.access.expression.WebExpressionVoter#86d6bf7], AllowIfAllAbstainDecisions=false]
2022-03-03 18:08:49.512 TRACE 13257 --- [nio-8080-exec-2] o.s.s.w.a.ExceptionTranslationFilter : Sending AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=E12CB3A032D3C0C442783899676963FC], Granted Authorities=[ROLE_ANONYMOUS]] to authentication entry point since access is denied
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:73) ~[spring-security-core-5.6.1.jar:5.6.1]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.attemptAuthorization(AbstractSecurityInterceptor.java:239) ~[spring-security-core-5.6.1.jar:5.6.1]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:208) ~[spring-security-core-5.6.1.jar:5.6.1]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:113) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:109) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
Does anyone know how to fix this problem?
Tnx in advance
Mihajlo
See OpenID Connect 1.0 UserInfo Endpoint in the reference docs, which has an example configuration demonstrating how to enable the use of the user info endpoint. Also, take a look at OidcUserInfoTests, which has a configuration that demonstrates this.
It requires the use of .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt) and a JwtDecoder #Bean to allow the JWT access token to be validated.

Why does Spring Security reject my Keycloak auth token with "No AuthenticationProvider found"?

I'm trying to figure out why my Spring Boot application is rejecting my Keycloak JWT bearer token with a "No AuthenticationProvider found" error message.
I have a few services running in a docker compose environment:
ui (angular) -> proxy (nginx) -> rest api (spring boot) -> auth service (keycloak)
The angular ui pulls the correct keycloak client from the rest service, and then authenticates without issue. I get back a JWT token, and then turn around and hand that to follow on requests to the rest api in a header Authorization: bearer [token].
In the rest API, I can see the correct bearer token come in as a header:
2022-02-11 01:01:31.411 DEBUG 13 --- [nio-8080-exec-4] o.a.coyote.http11.Http11InputBuffer : Received [GET /api/v3/accounts HTTP/1.0
X-Real-IP: 192.168.80.1
X-Forwarded-For: 192.168.80.1
Host: rest-api.mylocal.com
Connection: close
Accept: application/json, text/plain, */*
Authorization: Bearer eyJhbGciO...
...
2022-02-11 01:01:31.421 DEBUG 13 --- [nio-8080-exec-4] o.k.adapters.PreAuthActionsHandler : adminRequest http://rest-api.mylocal.com/api/v3/accounts
...
So the bearer token is there, and with https://jwt.io/ I can verify it's what I would expect:
{
"exp": 1644515847,
...
"iss": "http://auth-service.mylocal.com/auth/realms/LocalTestRealm",
...
"typ": "Bearer",
"azp": "LocalTestClient",
...
"allowed-origins": [
"http://web-ui.mylocal.com"
],
"realm_access": {
"roles": [
"offline_access",
"default-roles-localtestrealm",
"uma_authorization"
]
},
"resource_access": {
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"scope": "openid email profile",
...
}
Processing continues by the rest api - it contacts the keycloak service and pulls the well known config:
...
2022-02-11 01:01:33.321 INFO 13 --- [nio-8080-exec-4] o.keycloak.adapters.KeycloakDeployment : Loaded URLs from http://auth-service.mylocal.com/auth/realms/LocalTestRealm/.well-known/openid-configuration
...
Finally it looks like it successfully parses the bearer token apart, grabs the user and authenticates them:
2022-02-11 01:01:33.521 DEBUG 13 --- [nio-8080-exec-4] o.a.h.impl.conn.tsccm.ConnPoolByRoute : Releasing connection [{}->http://auth-service.mylocal.com:80][null]
2022-02-11 01:01:33.521 DEBUG 13 --- [nio-8080-exec-4] o.a.h.impl.conn.tsccm.ConnPoolByRoute : Pooling connection [{}->http://auth-service.mylocal.com:80][null]; keep alive indefinitely
2022-02-11 01:01:33.521 DEBUG 13 --- [nio-8080-exec-4] o.a.h.impl.conn.tsccm.ConnPoolByRoute : Notifying no-one, there are no waiting threads
2022-02-11 01:01:33.530 DEBUG 13 --- [nio-8080-exec-4] o.k.a.rotation.JWKPublicKeyLocator : Realm public keys successfully retrieved for client LocalTestClient. New kids: [8a7dIQFASdC8BHa0mUWwZX7RBBJSeJItdmzah0Ybpcw]
2022-02-11 01:01:33.546 DEBUG 13 --- [nio-8080-exec-4] o.k.a.BearerTokenRequestAuthenticator : successful authorized
2022-02-11 01:01:33.550 TRACE 13 --- [nio-8080-exec-4] o.k.a.RefreshableKeycloakSecurityContext : checking whether to refresh.
2022-02-11 01:01:33.550 TRACE 13 --- [nio-8080-exec-4] org.keycloak.adapters.AdapterUtils : useResourceRoleMappings
2022-02-11 01:01:33.550 TRACE 13 --- [nio-8080-exec-4] org.keycloak.adapters.AdapterUtils : Setting roles:
2022-02-11 01:01:33.555 DEBUG 13 --- [nio-8080-exec-4] a.s.a.SpringSecurityRequestAuthenticator : Completing bearer authentication. Bearer roles: []
2022-02-11 01:01:33.556 DEBUG 13 --- [nio-8080-exec-4] o.k.adapters.RequestAuthenticator : User 'bf7307ca-9352-4a02-b288-0565e2b57292' invoking 'http://rest-api.mylocal.com/api/v3/accounts' on client 'LocalTestClient'
2022-02-11 01:01:33.556 DEBUG 13 --- [nio-8080-exec-4] o.k.adapters.RequestAuthenticator : Bearer AUTHENTICATED
2022-02-11 01:01:33.556 DEBUG 13 --- [nio-8080-exec-4] f.KeycloakAuthenticationProcessingFilter : Auth outcome: AUTHENTICATED
and then immediately after that fails with the No AuthenticationProvider found error:
2022-02-11 01:01:33.559 TRACE 13 --- [nio-8080-exec-4] f.KeycloakAuthenticationProcessingFilter : Failed to process authentication request
org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:234) ~[spring-security-core-5.5.1.jar!/:5.5.1]
I'm at a loss how it can say Bearer AUTHENTICATED followed by Auth outcome: AUTHENTICATED followed by No AuthenticationProvider found... I'm assuming it somehow can't convert this bearer token into a Keycloak token, even though it definitely came from my Keycloak server.
My app config:
#ComponentScan({"com.mycompany"})
#Configuration
#EnableJpaRepositories(basePackages = "com.mycompany")
#EntityScan("com.mycompany")
#ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class ApplicationConfiguration
extends KeycloakWebSecurityConfigurerAdapter {
#Override
protected void configure(final HttpSecurity http) throws Exception {
super.configure(http);
http
.authorizeRequests()
// These paths (comma separated) are allowed to all
.antMatchers("/api/v3/auth/config").permitAll()
.and()
.authorizeRequests()
// Everything else should be authenticated
.anyRequest().authenticated()
.and()
.csrf().disable();
}
#Bean
#Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new NullAuthenticatedSessionStrategy();
}
#Bean
public KeycloakConfigResolver keycloakConfigResolver() {
// This just pulls the Keycloak config from a DB instead of the config file
return new CustomKeycloakConfigResolver();
// return new KeycloakSpringBootConfigResolver();
}
}
Missing the global config to autowire in a Keycloak auth provider:
#Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth)
throws Exception {
KeycloakAuthenticationProvider keycloakAuthenticationProvider =
keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(
new SimpleAuthorityMapper()
);
auth.authenticationProvider(keycloakAuthenticationProvider);
}

Springboot and KeycloakWebSecurityConfigurerAdapter

I'm trying to plug in Keycloak authentication in my web application on Springboot with KeycloakAdapter. But when i trying to login from application homepage, i get 401 error. Logfile contains this error:
2021-10-05 18:34:39,839 [http-nio-0.0.0.0-9090-exec-3] DEBUG o.k.a.s.f.KeycloakAuthenticationProcessingFilter - Request is to process authentication
2021-10-05 18:34:39,839 [http-nio-0.0.0.0-9090-exec-3] DEBUG o.k.a.s.f.KeycloakAuthenticationProcessingFilter - Attempting Keycloak authentication
2021-10-05 18:34:39,839 [http-nio-0.0.0.0-9090-exec-3] DEBUG o.apache.tomcat.util.http.Parameters - Set encoding to UTF-8
2021-10-05 18:34:39,839 [http-nio-0.0.0.0-9090-exec-3] DEBUG o.k.adapters.RequestAuthenticator - NOT_ATTEMPTED: bearer only
2021-10-05 18:34:39,839 [http-nio-0.0.0.0-9090-exec-3] DEBUG o.k.a.s.f.KeycloakAuthenticationProcessingFilter - Auth outcome: NOT_ATTEMPTED
2021-10-05 18:34:39,839 [http-nio-0.0.0.0-9090-exec-3] DEBUG o.k.a.s.f.KeycloakAuthenticationProcessingFilter - Authentication request failed: org.keycloak.adapters.springsecurity.KeycloakAuthenticationException: Authorization header not found, see WWW-Authenticate header
org.keycloak.adapters.springsecurity.KeycloakAuthenticationException: Authorization header not found, see WWW-Authenticate header
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.attemptAuthentication(KeycloakAuthenticationProcessingFilter.java:168)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:86)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
I think i need to get authorization token from Keycloak and call login endpoint with it, but i cant understand where and how to do this. And its starange, that i need authenticate before authenticate... Seems like I do something wrong. Colleagues, who integarates Keycloak with Springboot, give me a hand with this please.
My config:
#KeycloakConfiguration
#ComponentScan(
basePackageClasses = {KeycloakSecurityComponents.class},
excludeFilters = #ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.keycloak.adapters.springsecurity.management.HttpSessionManager"))
public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
super.configure(http);
http
.csrf().disable()
.authorizeRequests()
.antMatchers(WEBJARS_ENTRY_POINT).permitAll()
.antMatchers(DEVICE_API_ENTRY_POINT).permitAll()
.antMatchers(FORM_BASED_LOGIN_ENTRY_POINT).permitAll()
.antMatchers(PUBLIC_LOGIN_ENTRY_POINT).permitAll()
.antMatchers(TOKEN_REFRESH_ENTRY_POINT).permitAll()
.antMatchers(NON_TOKEN_BASED_AUTH_ENTRY_POINTS).permitAll()
.and()
.authorizeRequests()
.antMatchers(WS_TOKEN_BASED_AUTH_ENTRY_POINT).authenticated()
.antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated();
// #formatter:on
}
#Bean
#Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(keycloakAuthenticationProvider());
}
}
And .yml
keycloak:
realm: "myRealm"
auth-server-url: "http://localhost:18080/auth"
ssl-required: "external"
resource: "myResource"
credentials:
secret: "xxxxxxxxxxxxxxxxxxxxxxxxx"
use-resource-role-mappings: "true"
bearer-only: "true"
I found the problem. It works if change parameter bearer-only to false in .yml
keycloak:
realm: "myRealm"
auth-server-url: "http://localhost:18080/auth"
ssl-required: "external"
resource: "myResource"
credentials:
secret: "xxxxxxxxxxxxxxxxxxxxxxxxx"
use-resource-role-mappings: "true"
bearer-only: "false"

Spring boot OAuth2RestTemplate client setup, authorization_request_not_found error

I try to setup an OAuth2RestTemplate in a spring boot project. I tried to follow a custom setup, but for some reason I always get authorization_request_not_found error when trying to access a secured resource.
My AppConfig:
#EnableOAuth2Client
#SpringBootApplication
public class AppConfig {
public static void main(String[] args) {
SpringApplication.run(AppConfig.class, args);
}
#Bean
RestTemplate restTemplate(OAuth2ProtectedResourceDetails oauth2RemoteResource) {
return new OAuth2RestTemplate(oauth2RemoteResource);
}
}
SecurityConfig:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.mvcMatchers("/", "/login/**").permitAll()
.mvcMatchers("/secure").authenticated()
.anyRequest().permitAll()
.and()
.oauth2Login()
.and()
.oauth2Client();
}
}
Controller:
#GetMapping("/secure")
public String secure() {
Object result = restTemplate.getForObject("https://esi.evetech.net/latest/alliances", Object.class);
return "/";
}
application.yml:
security:
oauth2:
client:
id: eve
client-id: clientId
client-secret: secret
grant-type: authorization_code
user-authorization-uri: https://login.eveonline.com/v2/oauth/authorize
access-token-uri: https://login.eveonline.com/v2/oauth/token
pre-established-redirect-uri: http://localhost:8080/login/oauth2/code/eve
use-current-uri: false
scope:
- esi-characters.read_blueprints.v1
resource:
user-info-uri: https://login.eveonline.com/oauth/verify
spring:
security:
oauth2:
client:
registration:
eve:
authorization-grant-type: authorization_code
client-id: clientId
client-secret: secret
redirect-uri: http://localhost:8080/login/oauth2/code/eve
client-authentication-method: basic
scope:
- esi-characters.read_blueprints.v1
provider:
eve:
authorization-uri: https://login.eveonline.com/v2/oauth/authorize
token-uri: https://login.eveonline.com/v2/oauth/token
user-info-uri: https://login.eveonline.com/oauth/verify
user-name-attribute: CharacterID
Now I find this also interesting since I am not sure why I have to declare these properties twice.
I mean the OAuth2RestTemplate takes an AuthorizationCodeResourceDetails instance in the constructor in AppConfig which reads the security.oatuh2.client properties, while the DefaultOAuth2ClientContext inside the OAuth2RestTemplate constructor reads the other, I just don't understand why is it like that? Is there a simple setup?
Anyway going back to the original problem, when I access /secure it redirects me to the login page, where I login successfully which then redirects me back to the /secure page, so far so good.
Just before calling the restTemplate, I have this in the log:
2020-05-06 22:55:31.528 DEBUG 29177 --- [nio-8080-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /secure; Attributes: [authenticated]
2020-05-06 22:55:31.528 DEBUG 29177 --- [nio-8080-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken#3bb07c9: Principal: Name: [<ID>], Granted Authorities: [[ROLE_USER, SCOPE_esi-characters.read_blueprints.v1]], User Attributes: [{CharacterID=<ID>, CharacterName=<Name>, ExpiresOn=2020-05-06T22:15:31, Scopes=esi-characters.read_blueprints.v1, TokenType=Character, CharacterOwnerHash=<Hash>, IntellectualProperty=EVE}]; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 472A39D41FE34AC90781A80E39E4A52D; Granted Authorities: ROLE_USER, SCOPE_esi-characters.read_blueprints.v1
2020-05-06 22:55:31.529 DEBUG 29177 --- [nio-8080-exec-4] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter#47a65378, returned: 1
But after the restTemplate is called:
2020-05-06 23:00:31.482 DEBUG 29177 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Failed to complete request: org.springframework.security.oauth2.client.resource.UserRedirectRequiredException: A redirect is required to get the users approval
2020-05-06 23:00:31.483 DEBUG 29177 --- [nio-8080-exec-4] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#205366de
2020-05-06 23:00:31.483 DEBUG 29177 --- [nio-8080-exec-4] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2020-05-06 23:00:31.484 DEBUG 29177 --- [nio-8080-exec-4] o.s.s.web.DefaultRedirectStrategy : Redirecting to 'https://login.eveonline.com/v2/oauth/authorize?client_id=<clientId>&redirect_uri=http://localhost:8080/login/oauth2/code/eve&response_type=code&scope=esi-characters.read_blueprints.v1&state=<state>'
As you can see it takes me back to the login page, so I login back again and this time I get the error: [authorization_request_not_found]
log:
2020-05-06 23:02:27.285 DEBUG 29177 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy : /login/oauth2/code/eve?code=<code>&state=<state> at position 8 of 17 in additional filter chain; firing Filter: 'OAuth2LoginAuthenticationFilter'
2020-05-06 23:02:27.285 DEBUG 29177 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login/oauth2/code/eve'; against '/login/oauth2/code/*'
2020-05-06 23:02:27.285 DEBUG 29177 --- [nio-8080-exec-6] .s.o.c.w.OAuth2LoginAuthenticationFilter : Request is to process authentication
2020-05-06 23:02:27.287 DEBUG 29177 --- [nio-8080-exec-6] .s.o.c.w.OAuth2LoginAuthenticationFilter : Authentication request failed: org.springframework.security.oauth2.core.OAuth2AuthenticationException: [authorization_request_not_found]
org.springframework.security.oauth2.core.OAuth2AuthenticationException: [authorization_request_not_found]
at org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter.attemptAuthentication(OAuth2LoginAuthenticationFilter.java:163) ~[spring-security-oauth2-client-5.2.2.RELEASE.jar:5.2.2.RELEASE]
I am lost at this point, not sure why I am getting this.
I also uploaded the project to github in case it's easier to check out what's wrong with it.
Thanks

Spring OAuth2 Full authentication is required to access this resource

Before we get started, I have looked at many of the posts regarding this topic, but none of the posts seemed to have anything that could help.
I am trying to configure my Spring Rest API to use OAuth Password Grant authentication.
Here is my current security config. currently i have no limitations on which endpoints are permitAll() or authenticated, but I had it setup previously to permit non authenticated access to /oauth/** but still had the same issue. After reading documentation, this seems like a bad thing to do because the /oauth/token endpoint should be protected with http basic authentication where the username/password are the client ID and client secret. I also tried to have it setup to have anyRequest().authenticated() and got the same issue as I am having.
#Configuration
#EnableWebSecurity
#ComponentScan({ "com.mergg.webapp.security", "com.mergg.common.web" })
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private IUserService userService;
#Override
public void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
}
#Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
}
Here is my current setup for AuthorizationServerConfig. Please note that I have tried to create an in memory client where the secret was passwordEncoder.encode("secret"). Same problem occurred. Not sure which is best practice to use, but thats a topic for another time.
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private DataSource dataSource;
#Autowired
private BCryptPasswordEncoder passwordEncoder;
public AuthorizationServerConfiguration() {
super();
}
#Bean
public TokenStore tokenStore() {
// return new JdbcTokenStore(dataSource);
return new InMemoryTokenStore();
}
// config
#Override
public void configure(final AuthorizationServerSecurityConfigurer oauthServer) {
oauthServer.passwordEncoder(this.passwordEncoder)
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
#Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
// clients.jdbc(dataSource)
// .passwordEncoder(passwordEncoder)
// .withClient("mergg_mobile")
// .secret(passwordEncoder.encode("secret"))
// .authorizedGrantTypes("password");
clients.inMemory()
.withClient("test")
.secret("secret")
.authorizedGrantTypes("password", "refresh_token")
.accessTokenValiditySeconds(3600);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.tokenStore(tokenStore())
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
}
}
Here is my ResourceServerConfiguration. I have played around with the http security element the same way that i did with the one in my security configuration. I also toyed with a stateless vs if needed session creation policy. No luck.
#Configuration
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
//#formatter:off
http
.authorizeRequests()
.antMatchers("/roles/**").hasRole("INTERNAL")
.antMatchers("/priveleges/**").hasRole("INTERNAL")
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
//#formatter:on
}
}
Here are a few examples of requests I have made (with curl and postman):
curl -u test:secret -X POST localhost:5000/oauth/token\?grant_type=password\&username=test\&password=password
curl -u test:password -X POST localhost:5000/oauth/token\?grant_type=password\&username=test\&password=password
curl -X POST -vu test:secret http://localhost:5000/oauth/token -H "Accept: application/json" -d "password=password&username=test&grant_type=password&client_secret=secret&client_id=test"
curl -X POST -vu test:password http://localhost:5000/oauth/token -H "Accept: application/json" -d "password=password&username=test&grant_type=password&client_secret=secret&client_id=test"
Note that the oauth client id is test and its secret is secret. One user is test with password password
Here is the console output when I try to request a token:
23:07:36.571 [http-nio-5000-exec-2] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
23:07:36.625 [http-nio-5000-exec-2] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?password=password&username=test&grant_type=token at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
23:07:36.627 [http-nio-5000-exec-2] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?password=password&username=test&grant_type=token at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
23:07:36.627 [http-nio-5000-exec-2] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?password=password&username=test&grant_type=token at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
23:07:36.629 [http-nio-5000-exec-2] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?password=password&username=test&grant_type=token at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
23:07:36.629 [http-nio-5000-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', GET]
23:07:36.630 [http-nio-5000-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'POST /oauth/token' doesn't match 'GET /logout'
23:07:36.630 [http-nio-5000-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', POST]
23:07:36.630 [http-nio-5000-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/logout'
23:07:36.630 [http-nio-5000-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', PUT]
23:07:36.631 [http-nio-5000-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'POST /oauth/token' doesn't match 'PUT /logout'
23:07:36.631 [http-nio-5000-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', DELETE]
23:07:36.631 [http-nio-5000-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'POST /oauth/token' doesn't match 'DELETE /logout'
23:07:36.631 [http-nio-5000-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher - No matches found
23:07:36.631 [http-nio-5000-exec-2] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?password=password&username=test&grant_type=token at position 5 of 11 in additional filter chain; firing Filter: 'OAuth2AuthenticationProcessingFilter'
23:07:36.631 [http-nio-5000-exec-2] DEBUG o.s.s.o.p.a.BearerTokenExtractor - Token not found in headers. Trying request parameters.
23:07:36.631 [http-nio-5000-exec-2] DEBUG o.s.s.o.p.a.BearerTokenExtractor - Token not found in request parameters. Not an OAuth2 request.
23:07:36.631 [http-nio-5000-exec-2] DEBUG o.s.s.o.p.a.OAuth2AuthenticationProcessingFilter - No token in request, will continue chain.
23:07:36.631 [http-nio-5000-exec-2] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?password=password&username=test&grant_type=token at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
23:07:36.633 [http-nio-5000-exec-2] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?password=password&username=test&grant_type=token at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
23:07:36.635 [http-nio-5000-exec-2] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?password=password&username=test&grant_type=token at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
23:07:36.637 [http-nio-5000-exec-2] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#ad1846c9: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
23:07:36.637 [http-nio-5000-exec-2] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?password=password&username=test&grant_type=token at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
23:07:36.637 [http-nio-5000-exec-2] DEBUG o.s.s.w.s.SessionManagementFilter - Requested session ID 61EE2368B212EC609873DFB621D5166A is invalid.
23:07:36.637 [http-nio-5000-exec-2] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?password=password&username=test&grant_type=token at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
23:07:36.637 [http-nio-5000-exec-2] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?password=password&username=test&grant_type=token at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
23:07:36.638 [http-nio-5000-exec-2] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token?password=password&username=test&grant_type=token; Attributes: [#oauth2.throwOnError(authenticated)]
23:07:36.638 [http-nio-5000-exec-2] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#ad1846c9: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
23:07:36.645 [http-nio-5000-exec-2] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter#73ac552e, returned: -1
23:07:36.652 [http-nio-5000-exec-2] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:124)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:176)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.mergg.webapp.security.SimpleCorsFilter.doFilter(SimpleCorsFilter.java:40)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:844)
23:07:36.660 [http-nio-5000-exec-2] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Calling Authentication entry point.
23:07:36.712 [http-nio-5000-exec-2] DEBUG o.s.s.w.h.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#5bf2a0a6
23:07:36.716 [http-nio-5000-exec-2] DEBUG o.s.s.o.p.e.DefaultOAuth2ExceptionRenderer - Written [error="unauthorized", error_description="Full authentication is required to access this resource"] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#3b1af7db]
23:07:36.716 [http-nio-5000-exec-2] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
Here is the response I get in postman:
{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
}

Resources