why does spring security oauth2 authorization server keep calling UserDetailsService? - spring

Get access token through password grant type, why does authorization server keep calling UserDetailsService when user password is wrong
2021-01-19 20:41:29.801 DEBUG 38781 --- [nio-9007-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
2021-01-19 20:41:29.801 DEBUG 38781 --- [nio-9007-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
2021-01-19 20:41:29.801 DEBUG 38781 --- [nio-9007-exec-1] o.s.security.web.FilterChainProxy : /oauth/token reached end of additional filter chain; proceeding with original chain
2021-01-19 20:41:29.807 DEBUG 38781 --- [nio-9007-exec-1] o.s.web.servlet.DispatcherServlet : POST "/oauth/token", parameters={masked}
2021-01-19 20:41:29.817 DEBUG 38781 --- [nio-9007-exec-1] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped to org.springframework.security.oauth2.provider.endpoint.TokenEndpoint#postAccessToken(Principal, Map)
2021-01-19 20:41:30.292 DEBUG 38781 --- [nio-9007-exec-1] o.s.s.a.dao.DaoAuthenticationProvider : Authentication failed: password does not match stored value
2021-01-19 20:41:30.297 DEBUG 38781 --- [nio-9007-exec-1] o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2021-01-19 20:41:30.297 DEBUG 38781 --- [nio-9007-exec-1] o.s.jdbc.datasource.DataSourceUtils : Fetching JDBC Connection from DataSource
2021-01-19 20:41:30.302 DEBUG 38781 --- [nio-9007-exec-1] o.s.jdbc.datasource.DataSourceUtils : Fetching JDBC Connection from DataSource
2021-01-19 20:41:30.306 DEBUG 38781 --- [nio-9007-exec-1] o.s.jdbc.datasource.DataSourceUtils : Fetching JDBC Connection from DataSource
2021-01-19 20:41:30.425 DEBUG 38781 --- [nio-9007-exec-1] o.s.s.a.dao.DaoAuthenticationProvider : Authentication failed: password does not match stored value
2021-01-19 20:41:30.425 DEBUG 38781 --- [nio-9007-exec-1] o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2021-01-19 20:41:30.426 DEBUG 38781 --- [nio-9007-exec-1] o.s.jdbc.datasource.DataSourceUtils : Fetching JDBC Connection from DataSource
2021-01-19 20:41:30.431 DEBUG 38781 --- [nio-9007-exec-1] o.s.jdbc.datasource.DataSourceUtils : Fetching JDBC Connection from DataSource
2021-01-19 20:41:30.435 DEBUG 38781 --- [nio-9007-exec-1] o.s.jdbc.datasource.DataSourceUtils : Fetching JDBC Connection from DataSource
Hope is to prompt that the password is wrong.
My UserDetailsService is:
#Service
public class MyUserDetailsService implements UserDetailsService {
#Autowired
private UserMapper userMapper;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMapper.selectByUserName(username);
User userRoles = userMapper.selectRolesById(user.getId());
List<String> roles = userRoles.getRoles().stream().map(Role::getRole).collect(Collectors.toList());
User userResourcePermissions = userMapper.selectResourcePermissionsById(user.getId());
List<String> resourcePermissions = userResourcePermissions.getResourcePermissions().stream()
.map(roleResourcePermissionRef -> String.format("%s:%s",roleResourcePermissionRef.getResourceCode(),roleResourcePermissionRef.getPermissionCode()))
.collect(Collectors.toList());
resourcePermissions.add("a1");
UserDetails userDetails = org.springframework.security.core.userdetails.User
.withUsername(user.getUserName())
.password(user.getPassword())
.roles(roles.toArray(new String[0]))
.authorities(resourcePermissions.toArray(new String[0]))
.build();
return userDetails;
}
}
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService)
.passwordEncoder(passwordEncoder)
// .and().parentAuthenticationManager(authenticationManagerBean())
;
}
}
Caused by the .and().parentAuthenticationManager(authenticationManagerBean()) .

Because it has to get the user details in order to check the password.
if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
this.logger.debug("Failed to authenticate since password does not match stored value");
throw new BadCredentialsException(this.messages
.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
}
o.s.s.a.dao.DaoAuthenticationProvider.java:76

Related

403 Forbidden when introducing authorization on spring boot rest

I am with my first spring-boot project. I did succesfully configure it to check for authentication; if the user/password was wrong the method was not invoked (status 401 unauthorized), if it was right it succeeded.
Now I have added authorization with JSR250 and I am only getting 403 Access denied.
The WS:
#RestController
#RequestMapping("/password")
public class ServicioPassword {
#GetMapping(path = "ldap")
public ResponseEntity<String> getLdap() {
var authentication = SecurityContextHolder.getContext().getAuthentication();
System.out.println("EN LDAP " + authentication.getPrincipal() + " - " + authentication.isAuthenticated());
for (var authority : authentication.getAuthorities()) {
System.out.println("Authority= " + authority);
}
return ResponseEntity.ok("DE LDAP");
}
When invoked, I get this on console:
EN LDAP LdapUserDetailsImpl [Dn=cn=ivr_apl_user,ou=IVR,ou=Aplicaciones,dc=pre,dc=aplssib; Username=ivr_apl_user; Password=[PROTECTED]; Enabled=true; AccountNonExpired=true; CredentialsNonExpired=true; AccountNonLocked=true; Granted Authorities=[AGNI_OIMIVR]] - true
Authority= AGNI_OIMIVR
Yet, if I add #RolesAllowed("AGNI_OIMIVR"), when I invoke it I get a 403 Forbidden.
The MethodSecurityConfig:
#Configuration
#EnableGlobalMethodSecurity(jsr250Enabled = true, prePostEnabled = true)
public class MethodSecurityConfig
extends GlobalMethodSecurityConfiguration{
}
I have kept the WebSecurityConfig:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig {
#Configuration
#EnableWebSecurity
public class WebSecurityConfig {
#Autowired
private Environment environment;
#Bean
BindAuthenticator bindAuthenticator(
final BaseLdapPathContextSource contextSource) {
var bindAuthenticator = new BindAuthenticator(contextSource);
bindAuthenticator.setUserDnPatterns(new String[]{environment.getRequiredProperty("spring.ldap.userdnpattern")});
return bindAuthenticator;
}
#Bean
AuthenticationProvider ldapAuthenticationProvider(
final LdapAuthenticator ldapAuthenticator) {
var ldapAuthenticationProvider = new LdapAuthenticationProvider(ldapAuthenticator);
var ldapUserDetailsMapper = new CustomUserDetailsMapper();
var ldapMemberRoles = environment.getRequiredProperty("spring.ldap.roleattributes");
ldapUserDetailsMapper.setRoleAttributes(ldapMemberRoles.split(","));
ldapUserDetailsMapper.setRolePrefix("");
ldapAuthenticationProvider.setUserDetailsContextMapper(ldapUserDetailsMapper);
return ldapAuthenticationProvider;
}
#Bean
SecurityFilterChain filterChain(
final HttpSecurity http)
throws Exception {
http.csrf().disable()
.cors().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER).and()
.authorizeRequests()
.anyRequest().authenticated().and()
.httpBasic();
return http.build();
}
UPDATE: Adding log after setting logging.level.org.springframework.security=TRACE:
Note that the line: 2022-07-07 13:04:27.464 WARN 81968 --- [nio-8080-exec-2] e.s.d.o.s.ws.CustomUserDetailsMapper : createAuthority agni_oimivr comes from a log from one of my custom classes.
2022-07-07 13:04:27.441 TRACE 81968 --- [nio-8080-exec-2] o.s.s.w.a.www.BasicAuthenticationFilter : Found username 'ivr_apl_user' in Basic Authorization header
2022-07-07 13:04:27.442 TRACE 81968 --- [nio-8080-exec-2] o.s.s.authentication.ProviderManager : Authenticating request with LdapAuthenticationProvider (1/1)
2022-07-07 13:04:27.444 TRACE 81968 --- [nio-8080-exec-2] o.s.s.l.a.BindAuthenticator : Attempting to bind as cn=ivr_apl_user,ou=[REDACTED]
2022-07-07 13:04:27.444 TRACE 81968 --- [nio-8080-exec-2] s.s.l.DefaultSpringSecurityContextSource : Removing pooling flag for user cn=ivr_apl_user,ou=[REDACTED]
2022-07-07 13:04:27.463 DEBUG 81968 --- [nio-8080-exec-2] o.s.s.l.a.BindAuthenticator : Bound cn=ivr_apl_user,ou=[REDACTED]
2022-07-07 13:04:27.463 DEBUG 81968 --- [nio-8080-exec-2] o.s.s.l.u.LdapUserDetailsMapper : Mapping user details from context with DN cn=ivr_apl_user,ou=[REDACTED]
2022-07-07 13:04:27.464 WARN 81968 --- [nio-8080-exec-2] e.s.d.o.s.ws.CustomUserDetailsMapper : createAuthority agni_oimivr
2022-07-07 13:04:27.464 DEBUG 81968 --- [nio-8080-exec-2] o.s.s.l.a.LdapAuthenticationProvider : Authenticated user
2022-07-07 13:04:27.465 DEBUG 81968 --- [nio-8080-exec-2] o.s.s.w.a.www.BasicAuthenticationFilter : Set SecurityContextHolder to UsernamePasswordAuthenticationToken [Principal=LdapUserDetailsImpl [Dn=cn=ivr_apl_user,ou=IVR,ou=Aplicaciones,dc=pre,dc=aplssib; Username=ivr_apl_user; Password=[PROTECTED]; Enabled=true; AccountNonExpired=true; CredentialsNonExpired=true; AccountNonLocked=true; Granted Authorities=[AGNI_OIMIVR]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[AGNI_OIMIVR]]
2022-07-07 13:04:27.465 TRACE 81968 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking RequestCacheAwareFilter (7/12)
2022-07-07 13:04:27.465 TRACE 81968 --- [nio-8080-exec-2] o.s.s.w.s.HttpSessionRequestCache : No saved request
2022-07-07 13:04:27.465 TRACE 81968 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking SecurityContextHolderAwareRequestFilter (8/12)
2022-07-07 13:04:27.466 TRACE 81968 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking AnonymousAuthenticationFilter (9/12)
2022-07-07 13:04:27.466 TRACE 81968 --- [nio-8080-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Did not set SecurityContextHolder since already authenticated UsernamePasswordAuthenticationToken [Principal=LdapUserDetailsImpl [Dn=cn=ivr_apl_user,ou=IVR,ou=Aplicaciones,dc=pre,dc=aplssib; Username=ivr_apl_user; Password=[PROTECTED]; Enabled=true; AccountNonExpired=true; CredentialsNonExpired=true; AccountNonLocked=true; Granted Authorities=[AGNI_OIMIVR]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[AGNI_OIMIVR]]
2022-07-07 13:04:27.466 TRACE 81968 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking SessionManagementFilter (10/12)
2022-07-07 13:04:27.467 TRACE 81968 --- [nio-8080-exec-2] s.CompositeSessionAuthenticationStrategy : Preparing session with ChangeSessionIdAuthenticationStrategy (1/1)
2022-07-07 13:04:27.467 DEBUG 81968 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : The HttpSession is currently null, and the HttpSessionSecurityContextRepository is prohibited from creating an HttpSession (because the allowSessionCreation property is false) - SecurityContext thus not stored for next request
2022-07-07 13:04:27.467 TRACE 81968 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking ExceptionTranslationFilter (11/12)
2022-07-07 13:04:27.467 TRACE 81968 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking FilterSecurityInterceptor (12/12)
2022-07-07 13:04:27.468 TRACE 81968 --- [nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : Did not re-authenticate UsernamePasswordAuthenticationToken [Principal=LdapUserDetailsImpl [Dn=cn=ivr_apl_user,ou=IVR,ou=Aplicaciones,dc=pre,dc=aplssib; Username=ivr_apl_user; Password=[PROTECTED]; Enabled=true; AccountNonExpired=true; CredentialsNonExpired=true; AccountNonLocked=true; Granted Authorities=[AGNI_OIMIVR]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[AGNI_OIMIVR]] before authorizing
2022-07-07 13:04:27.468 TRACE 81968 --- [nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : Authorizing filter invocation [GET /password/ldap] with attributes [authenticated]
2022-07-07 13:04:27.469 DEBUG 81968 --- [nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : Authorized filter invocation [GET /password/ldap] with attributes [authenticated]
2022-07-07 13:04:27.470 TRACE 81968 --- [nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : Did not switch RunAs authentication since RunAsManager returned null
2022-07-07 13:04:27.470 DEBUG 81968 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Secured GET /password/ldap
2022-07-07 13:04:27.471 TRACE 81968 --- [nio-8080-exec-2] o.s.s.a.i.a.MethodSecurityInterceptor : Did not re-authenticate UsernamePasswordAuthenticationToken [Principal=LdapUserDetailsImpl [Dn=cn=ivr_apl_user,ou=IVR,ou=Aplicaciones,dc=pre,dc=aplssib; Username=ivr_apl_user; Password=[PROTECTED]; Enabled=true; AccountNonExpired=true; CredentialsNonExpired=true; AccountNonLocked=true; Granted Authorities=[AGNI_OIMIVR]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[AGNI_OIMIVR]] before authorizing
2022-07-07 13:04:27.472 TRACE 81968 --- [nio-8080-exec-2] o.s.s.a.i.a.MethodSecurityInterceptor : Authorizing ReflectiveMethodInvocation: public org.springframework.http.ResponseEntity es.ssib.dtic.oimivr.service.ws.v1.ServicioPassword.getLdap(); target is of class [es.ssib.dtic.oimivr.service.ws.v1.ServicioPassword] with attributes [ROLE_AGNI_OIMIVR]
2022-07-07 13:04:27.475 TRACE 81968 --- [nio-8080-exec-2] o.s.s.a.i.a.MethodSecurityInterceptor : Failed to authorize ReflectiveMethodInvocation: public org.springframework.http.ResponseEntity es.ssib.dtic.oimivr.service.ws.v1.ServicioPassword.getLdap(); target is of class [es.ssib.dtic.oimivr.service.ws.v1.ServicioPassword] with attributes [ROLE_AGNI_OIMIVR] using AffirmativeBased [DecisionVoters=[org.springframework.security.access.annotation.Jsr250Voter#6797e2e2, org.springframework.security.access.vote.RoleVoter#2ab76862, org.springframework.security.access.vote.AuthenticatedVoter#152f6a2e], AllowIfAllAbstainDecisions=false]
2022-07-07 13:04:27.484 TRACE 81968 --- [nio-8080-exec-2] o.s.s.w.a.ExceptionTranslationFilter : Sending UsernamePasswordAuthenticationToken [Principal=LdapUserDetailsImpl [Dn=cn=ivr_apl_user,ou=IVR,ou=Aplicaciones,dc=pre,dc=aplssib; Username=ivr_apl_user; Password=[PROTECTED]; Enabled=true; AccountNonExpired=true; CredentialsNonExpired=true; AccountNonLocked=true; Granted Authorities=[AGNI_OIMIVR]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[AGNI_OIMIVR]] to access denied handler since access is denied
org.springframework.security.access.AccessDeniedException: Acceso denegado
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:73) ~[spring-security-core-5.7.1.jar:5.7.1]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.attemptAuthorization(AbstractSecurityInterceptor.java:239) ~[spring-security-core-5.7.1.jar:5.7.1]
[...]
2022-07-07 13:04:27.497 DEBUG 81968 --- [nio-8080-exec-2] o.s.s.w.access.AccessDeniedHandlerImpl : Responding with 403 status code
What am I doing wrong?
The Authentication object of your authenticated user is:
UsernamePasswordAuthenticationToken [Principal=LdapUserDetailsImpl [Dn=cn=ivr_apl_user,ou=IVR,ou=Aplicaciones,dc=pre,dc=aplssib; Username=ivr_apl_user; Password=[PROTECTED]; Enabled=true; AccountNonExpired=true; CredentialsNonExpired=true; AccountNonLocked=true; Granted Authorities=[AGNI_OIMIVR]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[AGNI_OIMIVR]]
Note that the GrantedAuthorities is Granted Authorities=[AGNI_OIMIVR], there is no ROLE_ prefix there. When you add #RolesAllowed("AGNI_OIMIVR") to the method, the ROLE_ prefix will be added automatically to the authority that you passed as an argument to the annotation, becoming ROLE_AGNI_OIMIVR.
Spring Security will try to match ROLE_AGNI_OIMIVR that is in the annotation with AGNI_OIMIVR that is in the granted authorities' property, but they do not match.
You have three options:
Change the role in LDAP to have the ROLE_ prefix
Expose a Bean of GrantedAuthorityDefaults removing the rolePrefix, like so:
#Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
return new GrantedAuthorityDefaults("");
}
Use #PreAuthorize("hasAuthority('AGNI_OIMIVR')")
Another tip would be to use the new #EnableMethodSecurity(jsr250Enabled = true) which uses the simplified AuthorizationManager API, improve logging, amongst others.

Keycloak integration with SpringDoc and spring boot

App stack: Spring boot / Spring Doc / Keycloak
I am trying to integrate the above stack together, everything works well till I am using keycloak policy enforcement.
At the bringing the app is running and I can access the Swagger UI served thanks to spring doc, but after like 20 or 30 seconds, I got HTTP ERROR 401 while I am trying to access the exact link of swagger and keycloak refuse all access to any URL or rest API
Console Error:
2022-05-22 23:31:55.650 DEBUG 92263 --- [io-8080-exec-10] o.k.adapters.PreAuthActionsHandler : adminRequest http://localhost:8080/swagger-ui/index.html
2022-05-22 23:31:55.650 DEBUG 92263 --- [io-8080-exec-10] o.k.adapters.PreAuthActionsHandler : checkCorsPreflight http://localhost:8080/swagger-ui/index.html
2022-05-22 23:31:55.651 DEBUG 92263 --- [io-8080-exec-10] .k.a.t.AbstractAuthenticatedActionsValve : AuthenticatedActionsValve.invoke /swagger-ui/index.html
2022-05-22 23:31:55.651 DEBUG 92263 --- [io-8080-exec-10] o.k.a.AuthenticatedActionsHandler : AuthenticatedActionsValve.invoke http://localhost:8080/swagger-ui/index.html
2022-05-22 23:31:55.651 DEBUG 92263 --- [io-8080-exec-10] o.k.a.AuthenticatedActionsHandler : Origin: null uri: http://localhost:8080/swagger-ui/index.html
2022-05-22 23:31:55.651 DEBUG 92263 --- [io-8080-exec-10] o.k.a.AuthenticatedActionsHandler : cors validation not needed as we are not a secure session or origin header was null: http://localhost:8080/swagger-ui/index.html
2022-05-22 23:31:55.651 DEBUG 92263 --- [io-8080-exec-10] o.k.a.authorization.PolicyEnforcer : Policy enforcement is enabled. Enforcing policy decisions for path [http://localhost:8080/swagger-ui/index.html].
2022-05-22 23:31:55.917 DEBUG 92263 --- [io-8080-exec-10] o.k.a.authorization.PolicyEnforcer : Policy enforcement result for path [http://localhost:8080/swagger-ui/index.html] is : DENIED
2022-05-22 23:31:55.917 DEBUG 92263 --- [io-8080-exec-10] o.k.a.authorization.PolicyEnforcer : Returning authorization context with permissions:
2022-05-22 23:31:55.917 DEBUG 92263 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : Securing GET /error
2022-05-22 23:31:55.917 DEBUG 92263 --- [io-8080-exec-10] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-05-22 23:31:55.917 DEBUG 92263 --- [io-8080-exec-10] o.k.adapters.PreAuthActionsHandler : adminRequest http://localhost:8080/error
2022-05-22 23:31:55.917 DEBUG 92263 --- [io-8080-exec-10] o.k.adapters.PreAuthActionsHandler : checkCorsPreflight http://localhost:8080/error
2022-05-22 23:31:55.917 TRACE 92263 --- [io-8080-exec-10] f.KeycloakAuthenticationProcessingFilter : Did not match request to Or [Ant [pattern='/sso/login'], RequestHeaderRequestMatcher [expectedHeaderName=Authorization, expectedHeaderValue=null], org.keycloak.adapters.springsecurity.filter.QueryParamPresenceRequestMatcher#1eab2ee7, org.keycloak.adapters.springsecurity.filter.AdapterStateCookieRequestMatcher#2ad76210]
2022-05-22 23:31:55.918 DEBUG 92263 --- [io-8080-exec-10] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2022-05-22 23:31:55.918 DEBUG 92263 --- [io-8080-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor : Failed to authorize filter invocation [GET /error] with attributes [authenticated]
2022-05-22 23:31:55.918 DEBUG 92263 --- [io-8080-exec-10] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
My policy enforcement to swagger links here is my keycloak YAML file
keycloak:
realm: phelix
auth-server-url: https://keycloak-server-url/auth
ssl-required: none
resource: orders
use-resource-role-mappings: true
bearer-only: true
cors-exposed-headers: X-Total-Count
cors: true
principal-attribute: preferred_username
credentials:
secret: 111-111-111.....
policy-enforcer-config:
enforcement-mode: ENFORCING
lazy-load-paths: true
paths:
- path: /swagger-ui/*.html
enforcement-mode: DISABLED
- path: /actuator/*
enforcement-mode: DISABLED
- path: /swagger-ui/*
enforcement-mode: DISABLED
- path: /swagger-ui.html
enforcement-mode: DISABLED
- path: /v3/api-docs/*
enforcement-mode: DISABLED
Security config class which extends keycloak adapter
#KeycloakConfiguration
#ConditionalOnProperty(name = "security.config.use-keycloak", havingValue = "true", matchIfMissing = true)
#ConfigurationProperties(prefix = "keycloak")
#PropertySource(value = "classpath:keycloak-configs.yml", factory = YamlPropertySourceFactory.class)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
private static final String[] WHITELIST_URLS = {
"/v3/api-docs/**",
"/swagger-ui/**",
"/swagger-ui.html",
"/actuator/**",
};
public KeycloakClientRequestFactory keycloakClientRequestFactory;
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable()
.formLogin().disable()
.httpBasic().disable()
.logout().disable()
.authorizeRequests()
.antMatchers(WHITELIST_URLS).permitAll()
.anyRequest().authenticated();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider authenticationProvider = keycloakAuthenticationProvider();
SimpleAuthorityMapper mapper = new SimpleAuthorityMapper();
mapper.setPrefix("");
authenticationProvider.setGrantedAuthoritiesMapper(mapper);
auth.authenticationProvider(authenticationProvider);
}
#Bean
#Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new NullAuthenticatedSessionStrategy(); //for bearer-only services
}
#Bean
public KeycloakDeployment keycloakDeploymentBuilder(KeycloakSpringBootProperties configuration) {
return KeycloakDeploymentBuilder.build(configuration);
}
#Bean
#Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public KeycloakRestTemplate keycloakRestTemplate() {
return new KeycloakRestTemplate(keycloakClientRequestFactory);
}
#Bean
#Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public AccessToken getAccessToken() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication.getPrincipal() instanceof KeycloakPrincipal) {
return ((KeycloakPrincipal) authentication.getPrincipal()).getKeycloakSecurityContext().getToken();
} else {
return new AccessToken();
}
}
}
Dependencies:
'springboot': '2.7.0'
'keycloakVersion': '16.1.0'
'springdoc-openapi-ui': '1.6.8'
Any thoughts ?

Wrong Header of the API versioning of the Post Request does not come to handleNoHandlerFoundException?

I am using Spring Boot v2.1.7 + HATEOAS + Spring Rest + Spring Security. When consumer doesn't pass the correct Custom Header in the request, say passes X-Accept-Version=v5, it gives me below error.
Error:
2020-03-26 15:44:48.201 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : POST "/employee-catalog-api/reference-types", parameters={}
2020-03-26 15:44:48.216 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2020-03-26 15:44:48.217 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] .m.c.d.m.p.s.SAMLUserIdentityServiceImpl : Trying to get UserId from Security Context
2020-03-26 15:44:48.224 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
2020-03-26 15:44:48.234 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2020-03-26 15:44:48.234 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] 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#5c85f23b
2020-03-26 15:44:48.234 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2020-03-26 15:44:48.254 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2020-03-26 15:44:48.254 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
2020-03-26 15:44:48.258 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2020-03-26 15:44:48.258 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
Code:
#PostMapping(path = "/employee-types", headers = {X-Accept-Version=v1})
public ResponseEntity<Integer> saveEmployeeType(#Valid #RequestBody EmployeeDto employeeDto) {
.....
......
......
return new ResponseEntity<>(HttpStatus.OK);
}
Why its not coming to handleNoHandlerFoundException of the #ControllerAdvice ?
#Override
protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers,
HttpStatus status, WebRequest request) {
...................
return handleExceptionInternal(ex, error, getHeaders(), HttpStatus.BAD_REQUEST, request);
}
I was able to solve this issue by taking a reference from : How to set default value of exported as false in rest resource spring data rest.
By adding below logic, it works greatly.
#Component
public class SpringRestConfiguration extends RepositoryRestConfigurerAdapter {
#Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.setRepositoryDetectionStrategy(RepositoryDetectionStrategy.RepositoryDetectionStrategies.ANNOTATED);
config.setExposeRepositoryMethodsByDefault(false);
}
}

Spring boot rest api not failed in case of invalid Endpoint

I am writing a RESTful web services using spring boot. I am using jwt bearer token for authentication an authorisation.
Below is my RestController
#RestController("api/v1/users")
public class UserController {
#Autowired
UserService userService;
#PostMapping
public User saveUser(#RequestBody User user) {
return userService.saveUser(user);
}
#GetMapping
public List<User> getUsers(#RequestParam(required = false) String pageNumber, String pageSize, String role, String status) {
return userService.findAll(pageNumber, pageSize, role, status);
}
}
When I hit the api with request-url
http://localhost:8080/api/v1/users?pageNumber=0&pageSize=6&role=admin
Its work perfectly
but if I change the url endpoint to some invalid endpoint like
http://localhost:8080/api/v1/hhh?pageNumber=0&pageSize=6&role=admin
It still returning same results as per 1st correct endpoint.
Below are some logs statements from springframework debug logging
Checking match of request : '/api/v1/hhh'; against
'/api/test/secureTest'
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request :
'/api/v1/hhh'; against 'api/authenticate'
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request :
'/api/v1/hhh'; against '/api/v1/users/me'
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request :
'/api/v1/hhh'; against '/api/v1/student'
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request :
'/api/v1/hhh'; against '/api/v1/faculty'
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request :
'/api/v1/hhh'; against '/api/v1/admin'
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request :
'/api/v1/hhh'; against '/api/v1/users'
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.s.w.a.i.FilterSecurityInterceptor : Public object -
authentication not attempted
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.security.web.FilterChainProxy :
/api/v1/hhh?pageNumber=0&pageSize=6&role=admin reached end of
additional filter chain; proceeding with original chain
2019-12-28 19:16:47.602 TRACE 5591 --- [nio-8080-exec-5]
o.s.web.servlet.DispatcherServlet : GET
"/api/v1/hhh?pageNumber=0&pageSize=6&role=admin", parameters={masked},
headers={masked} in DispatcherServlet 'dispatcherServlet'
2019-12-28 19:16:47.602 TRACE 5591 --- [nio-8080-exec-5]
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance
of singleton bean 'api/v1/users'
2019-12-28 19:16:47.602 TRACE 5591 --- [nio-8080-exec-5]
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public
java.util.List
com.asset.app.user.UserController.getUsers(java.lang.String,java.lang.String,java.lang.String,java.lang.String)
2019-12-28 19:16:47.602 TRACE 5591 --- [nio-8080-exec-5]
.w.s.m.m.a.ServletInvocableHandlerMethod : Arguments: [0, 6, admin,
null]
I feel Spring cache the endpoint url and used if in case of no match found
Any Idea how to stop this?
if you read the api documentation for #RestController
You see that the annotation constructor takes in a value that is described as:
The value may indicate a suggestion for a logical component name, to
be turned into a Spring bean in case of an autodetected component.
So it is used to set a name for the Bean that vill be created.
It is not used to set a url-mapping like you have done.
#RestController("api/v1/users")
You need to annotate your class with #RequestMapping and also add mappings to the #PostMapping and #GetMapping.
#RestController
#RequestMapping("/api/v1") // Add request mapping
public class FooBar {
#PostMapping("/users") // Add mapping here
public User bar() {
...
}
#GetMapping("/users") // Add mapping here
public List<User> foo() {
...
}
}

Returning bad credential in oauth2 implemention using spring boot 1.5

As i am trying to create simple login in oauth2 implementation using spring boot. Unfortunately its not working, as i am newbie in spring
My configuration
ApplicationStarter.java
#SpringBootApplication
#EnableAutoConfiguration
public class ApplicationStarter extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ApplicationStarter.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(ApplicationStarter.class, args);
}
}
ResourceServerConfiguration.java
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "my_rest_api";
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID);
}
#Override
public void configure(HttpSecurity http) throws Exception {
System.out.println("Inside ResourceServerConfiguration");
http.
anonymous().disable()
.requestMatchers().antMatchers("/user/**")
.and().authorizeRequests()
.antMatchers("/user/**").access("hasRole('ADMIN')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
AuthorizationServerConfiguration.java
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private static String REALM="MY_OAUTH_REALM";
#Autowired
private TokenStore tokenStore;
#Autowired
private UserApprovalHandler userApprovalHandler;
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
System.out.println("Inside AuthorizationServerConfiguration");
clients.inMemory()
.withClient("my-trusted-client")
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust")
.secret("secret")
.accessTokenValiditySeconds(120).//Access token is only valid for 2 minutes.
refreshTokenValiditySeconds(600);//Refresh token is only valid for 10 minutes.
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.realm(REALM+"/client");
}
}
MethodSecurityConfig.java
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
#Autowired
private OAuth2SecurityConfiguration securityConfig;
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
OAuth2SecurityConfiguration.java
#Configuration
#ComponentScan
#EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private ClientDetailsService clientDetailsService;
#Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
System.out.println("inside OAuth2SecurityConfiguration : globalUserDetails()");
auth.inMemoryAuthentication()
.withUser("bill").password("abc123").roles("ADMIN").and()
.withUser("bob").password("abc123").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
System.out.println("inside OAuth2SecurityConfiguration : configure()");
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/oauth/token").permitAll();
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
System.out.println("inside OAuth2SecurityConfiguration : authenticationManagerBean()");
return super.authenticationManagerBean();
}
#Bean
public TokenStore tokenStore() {
System.out.println("inside OAuth2SecurityConfiguration : tokenStore()");
return new InMemoryTokenStore();
}
#Bean
#Autowired
public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){
System.out.println("inside OAuth2SecurityConfiguration : userApprovalHandler()");
TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
handler.setTokenStore(tokenStore);
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setClientDetailsService(clientDetailsService);
return handler;
}
#Bean
#Autowired
public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
System.out.println("inside OAuth2SecurityConfiguration : approvalStore()");
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
}
Please do correct me where i am went wrong? whether any more configuration needed or not?
as i followed
http://websystique.com/spring-security/secure-spring-rest-api-using-oauth2/
as reference.
spring boot log
2017-10-26 11:15:07.851 DEBUG 21456 --- [nio-8080-exec-5]
o.s.b.w.f.OrderedRequestContextFilter : Bound request context to
thread: org.apache.catalina.connector.RequestFacade#1f2fcd1 2017-10-26
11:15:07.851 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant
[pattern='/css/'] 2017-10-26 11:15:07.851 DEBUG 21456 ---
[nio-8080-exec-5] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking
match of request : '/oauth/token'; against '/css/' 2017-10-26
11:15:07.851 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant
[pattern='/js/'] 2017-10-26 11:15:07.851 DEBUG 21456 ---
[nio-8080-exec-5] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking
match of request : '/oauth/token'; against '/js/' 2017-10-26
11:15:07.851 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant
[pattern='/images/'] 2017-10-26 11:15:07.851 DEBUG 21456 ---
[nio-8080-exec-5] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking
match of request : '/oauth/token'; against '/images/' 2017-10-26
11:15:07.851 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant
[pattern='/webjars/'] 2017-10-26 11:15:07.851 DEBUG 21456 ---
[nio-8080-exec-5] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking
match of request : '/oauth/token'; against '/webjars/' 2017-10-26
11:15:07.851 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant
[pattern='//favicon.ico'] 2017-10-26 11:15:07.851 DEBUG 21456 ---
[nio-8080-exec-5] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking
match of request : '/oauth/token'; against '//favicon.ico'
2017-10-26 11:15:07.851 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant
[pattern='/error'] 2017-10-26 11:15:07.851 DEBUG 21456 ---
[nio-8080-exec-5] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking
match of request : '/oauth/token'; against '/error' 2017-10-26
11:15:07.851 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.web.util.matcher.OrRequestMatcher : No matches found 2017-10-26
11:15:07.851 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant
[pattern='/'] 2017-10-26 11:15:07.851 DEBUG 21456 ---
[nio-8080-exec-5] o.s.s.w.u.matcher.AntPathRequestMatcher : Request
'/oauth/token' matched by universal pattern '/' 2017-10-26
11:15:07.851 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.web.util.matcher.OrRequestMatcher : matched 2017-10-26
11:15:07.851 DEBUG 21456 --- [nio-8080-exec-5]
o.s.security.web.FilterChainProxy :
/oauth/token?grant_type=password&username=bill&password=abc123 at
position 1 of 11 in additional filter chain; firing Filter:
'WebAsyncManagerIntegrationFilter' 2017-10-26 11:15:07.851 DEBUG 21456
--- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : /oauth/token?grant_type=password&username=bill&password=abc123 at
position 2 of 11 in additional filter chain; firing Filter:
'SecurityContextPersistenceFilter' 2017-10-26 11:15:07.852 DEBUG 21456
--- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : /oauth/token?grant_type=password&username=bill&password=abc123 at
position 3 of 11 in additional filter chain; firing Filter:
'HeaderWriterFilter' 2017-10-26 11:15:07.852 DEBUG 21456 ---
[nio-8080-exec-5] o.s.security.web.FilterChainProxy :
/oauth/token?grant_type=password&username=bill&password=abc123 at
position 4 of 11 in additional filter chain; firing Filter:
'LogoutFilter' 2017-10-26 11:15:07.852 DEBUG 21456 ---
[nio-8080-exec-5] o.s.s.web.util.matcher.OrRequestMatcher : Trying to
match using Ant [pattern='/logout', GET] 2017-10-26 11:15:07.852 DEBUG
21456 --- [nio-8080-exec-5] o.s.s.w.u.matcher.AntPathRequestMatcher :
Request 'POST /oauth/token' doesn't match 'GET /logout 2017-10-26
11:15:07.852 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant
[pattern='/logout', POST] 2017-10-26 11:15:07.852 DEBUG 21456 ---
[nio-8080-exec-5] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking
match of request : '/oauth/token'; against '/logout' 2017-10-26
11:15:07.852 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant
[pattern='/logout', PUT] 2017-10-26 11:15:07.869 DEBUG 21456 ---
[nio-8080-exec-5] o.s.s.w.u.matcher.AntPathRequestMatcher : Request
'POST /oauth/token' doesn't match 'PUT /logout 2017-10-26 11:15:07.869
DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant
[pattern='/logout', DELETE] 2017-10-26 11:15:07.869 DEBUG 21456 ---
[nio-8080-exec-5] o.s.s.w.u.matcher.AntPathRequestMatcher : Request
'POST /oauth/token' doesn't match 'DELETE /logout 2017-10-26
11:15:07.869 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.web.util.matcher.OrRequestMatcher : No matches found 2017-10-26
11:15:07.869 DEBUG 21456 --- [nio-8080-exec-5]
o.s.security.web.FilterChainProxy :
/oauth/token?grant_type=password&username=bill&password=abc123 at
position 5 of 11 in additional filter chain; firing Filter:
'BasicAuthenticationFilter' 2017-10-26 11:15:07.869 DEBUG 21456 ---
[nio-8080-exec-5] o.s.s.w.a.www.BasicAuthenticationFilter : Basic
Authentication Authorization header found for user 'my-trusted-client'
2017-10-26 11:15:07.869 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.authentication.ProviderManager : Authentication attempt
using
org.springframework.security.authentication.dao.DaoAuthenticationProvider
2017-10-26 11:15:07.869 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.a.dao.DaoAuthenticationProvider : User 'my-trusted-client'
not found 2017-10-26 11:15:07.869 DEBUG 21456 --- [nio-8080-exec-5]
o.s.s.w.a.www.BasicAuthenticationFilter : Authentication request for
failed:
org.springframework.security.authentication.BadCredentialsException:
Bad credentials 2017-10-26 11:15:07.869 DEBUG 21456 ---
[nio-8080-exec-5] 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#1ff799
2017-10-26 11:15:07.869 DEBUG 21456 --- [nio-8080-exec-5]
s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now
cleared, as request processing completed 2017-10-26 11:15:07.869 DEBUG
21456 --- [nio-8080-exec-5] o.s.b.w.f.OrderedRequestContextFilter :
Cleared thread-bound request context:
org.apache.catalina.connector.RequestFacade#1f2fcd1 2017-10-26
11:15:07.870 DEBUG 21456 --- [nio-8080-exec-5]
o.s.web.servlet.DispatcherServlet : DispatcherServlet with name
'dispatcherServlet' processing POST request for [/auth/error]
2017-10-26 11:15:07.870 DEBUG 21456 --- [nio-8080-exec-5]
s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method
for path /error 2017-10-26 11:15:07.870 DEBUG 21456 ---
[nio-8080-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning
handler method [public
org.springframework.http.ResponseEntity>
org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)]
2017-10-26 11:15:07.870 DEBUG 21456 --- [nio-8080-exec-5]
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance
of singleton bean 'basicErrorController' 2017-10-26 11:15:07.874 DEBUG
21456 --- [nio-8080-exec-5] o.s.w.s.m.m.a.HttpEntityMethodProcessor :
Written [{timestamp=Thu Oct 26 11:15:07 IST 2017, status=401,
error=Unauthorized, message=Bad credentials, path=/auth/oauth/token}]
as "application/json" using
[org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#32886a]
2017-10-26 11:15:07.874 DEBUG 21456 --- [nio-8080-exec-5]
o.s.web.servlet.DispatcherServlet : Null ModelAndView returned
to DispatcherServlet with name 'dispatcherServlet': assuming
HandlerAdapter completed request handling 2017-10-26 11:15:07.874
DEBUG 21456 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet
: Successfully completed request
gradle.build
> /* * This build file was generated by the Gradle 'init' task. * *
> This generated file contains a sample Java Library project to get you
> started. * For more details take a look at the Java Libraries chapter
> in the Gradle * user guide available at
> https://docs.gradle.org/3.5/userguide/java_library_plugin.html */
> buildscript {
> ext { springBootVersion = '1.5.7.RELEASE' }
> repositories { mavenCentral() }
> dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
> } } // Apply the java-library plugin to add support for Java Library
> apply plugin: 'java' apply plugin: 'eclipse' apply plugin:
> 'org.springframework.boot' apply plugin: 'war'
>
>
> sourceCompatibility = 1.8 // In this section you declare where to find
> the dependencies of your project repositories {
> // Use jcenter for resolving your dependencies.
> // You can declare any Maven/Ivy/file repository here. // jcenter() mavenCentral() }
>
> dependencies {
> // This dependency is exported to consumers, that is to say found on their compile classpath.
> //api 'org.apache.commons:commons-math3:3.6.1'
> //providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat:1.5.2.RELEASE'
> // This dependency is used internally, and not exposed to consumers on their own compile classpath.
> implementation 'com.google.guava:guava:21.0'
>
> // Use JUnit test framework
> testImplementation 'junit:junit:4.12'
>
>
> // compile("org.springframework.boot:spring-boot-starter-security:1.4.1.RELEASE")
> // compile("org.springframework.security.oauth:spring-security-oauth2:2.0.2.RELEASE")
> //
> compile("org.springframework.security:spring-security-config:3.2.0.RELEASE")
> // compile("org.gitlab4j:gitlab4j-api:4.6.0")
> // compile("org.springframework.boot:spring-boot-starter-tomcat:1.5.2.RELEASE")
>
> compile('org.springframework.boot:spring-boot-starter-actuator')
> compile('org.springframework.boot:spring-boot-starter-security')
> compile('org.springframework.security.oauth:spring-security-oauth2')
> compile('org.springframework.security:spring-security-config')
> compile('org.springframework.boot:spring-boot-starter-web')
> providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
>
> testCompile('org.springframework.boot:spring-boot-starter-test') }
Change your authorization server config like that
AuthorizationServerConfiguration.java
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
System.out.println("Inside AuthorizationServerConfiguration");
clients.inMemory()
.withClient("my-trusted-client")
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust").resourceIds("my_rest_api")
.secret("secret")
.accessTokenValiditySeconds(120).//Access token is only valid for 2 minutes.
refreshTokenValiditySeconds(600);//Refresh token is only valid for 10 minutes.
}
Here changes is I put a resourceIds after scope and that resource id will be same as Resources server's RESOURCE_ID.
You declared in ResourceServerConfiguration such like that
private static final String RESOURCE_ID = "my_rest_api";
So putting the string in authorization server can solve your problem I believe.
Thanks.

Resources