Keycloak integration with SpringDoc and spring boot - 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 ?

Related

Spring Boot Security Basic auth access denied

I'm trying to make an authenticated GET request on one of the resources:
http://user:psw#localhost:8090/devices
This works fine from the browser. But from National Instrument GWeb I keep getting Code 401 (Unauthorized).
SecurityConfiguration.java:
#Configuration
#EnableWebSecurity
class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final DatabaseUserDetailsService databaseUserDetailsService;
public SecurityConfiguration(DatabaseUserDetailsService databaseUserDetailsService) {
super();
this.databaseUserDetailsService = databaseUserDetailsService;
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors().and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
#Bean
public AuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder());
provider.setUserDetailsService(this.databaseUserDetailsService);
return provider;
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://rog-valerio", "http://localhost:8090"));
configuration.setAllowedMethods(Arrays.asList("GET","POST", "OPTIONS"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
From the configure() method:
httpSecurity.cors().and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
I'm I am not wrong this should mean that any request should be able to authenticate.
By enabling spring security debug, when I try to make the authenticated request I get the following:
2022-03-09 10:37:00.520 DEBUG 27408 --- [nio-8090-exec-5] o.s.security.web.FilterChainProxy : Securing GET /devices
2022-03-09 10:37:00.520 DEBUG 27408 --- [nio-8090-exec-5] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-03-09 10:37:00.521 DEBUG 27408 --- [nio-8090-exec-5] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2022-03-09 10:37:00.521 DEBUG 27408 --- [nio-8090-exec-5] o.s.s.w.a.i.FilterSecurityInterceptor : Failed to authorize filter invocation [GET /devices] with attributes [authenticated]
2022-03-09 10:37:00.522 DEBUG 27408 --- [nio-8090-exec-5] o.s.s.w.s.HttpSessionRequestCache : Saved request http://localhost:8090/devices to session
2022-03-09 10:37:00.523 DEBUG 27408 --- [nio-8090-exec-5] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]
2022-03-09 10:37:00.523 DEBUG 27408 --- [nio-8090-exec-5] s.w.a.DelegatingAuthenticationEntryPoint : No match found. Using default entry point org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint#30dfc62d
2022-03-09 10:37:00.523 DEBUG 27408 --- [nio-8090-exec-5] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
2022-03-09 10:37:00.523 DEBUG 27408 --- [nio-8090-exec-5] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
2022-03-09 10:37:00.523 DEBUG 27408 --- [nio-8090-exec-5] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
2022-03-09 10:37:00.523 DEBUG 27408 --- [nio-8090-exec-5] o.s.security.web.FilterChainProxy : Securing GET /error
2022-03-09 10:37:00.524 DEBUG 27408 --- [nio-8090-exec-5] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-03-09 10:37:00.524 DEBUG 27408 --- [nio-8090-exec-5] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2022-03-09 10:37:00.524 DEBUG 27408 --- [nio-8090-exec-5] o.s.security.web.FilterChainProxy : Secured GET /error
2022-03-09 10:37:00.525 DEBUG 27408 --- [nio-8090-exec-5] a.DefaultWebInvocationPrivilegeEvaluator : filter invocation [/error] denied for AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=05282221D24CA222616679CE3049C092], Granted Authorities=[ROLE_ANONYMOUS]]
org.springframework.security.access.AccessDeniedException: Access is denied
And access is denied. Username and password are correct. Why am I getting the request rejected? Maybe there is some configuration that I am missing?
I found the answer, configuration was fine. But, as stated here https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization#examples , I added "Authorization" header with base64 encoded username and password. Now it works.
I'll not delete the question because maybe it'll be useful to somebody

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 oauth2 - cannot obtain access token when use Basic Auth

I have problem to get access token from my spring-boot server v.2.0.3.RELEASE. I use spring-security-oauth v.2.3.3.RELEASE.
When I use postman I can get access token and in log I see that BasicAuthenticateFilter is match. But when use angularjs/react, BasicAuthenticateFilter is ommited and I got 401 without any message.
AuthenticationServer
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
static final String CLIENT_ID = "client";
static final String CLIENT_SECRET = "$2a$04$AMTwWHtjscVAHH4gPHx04.82v/W80KVJptp0l/QUWrlkiWU7g7wbe";
static final String GRANT_TYPE = "password";
static final String AUTHORIZATION_CODE = "authorization_code";
static final String REFRESH_TOKEN = "refresh_token";
static final String IMPLICIT = "implicit";
static final String SCOPE_READ = "read";
static final String SCOPE_WRITE = "write";
static final String TRUST = "trust";
static int ACCESS_TOKEN_VALIDITY_SECONDS = 2*60*60;
static final int REFRESH_TOKEN_VALIDITY_SECONDS = 6*60*60;
#Autowired
private TokenStore tokenStore;
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient(CLIENT_ID)
.secret(CLIENT_SECRET)
.authorizedGrantTypes(GRANT_TYPE, AUTHORIZATION_CODE, REFRESH_TOKEN, IMPLICIT)
.scopes(SCOPE_READ, SCOPE_WRITE, TRUST)
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS)
.refreshTokenValiditySeconds(REFRESH_TOKEN_VALIDITY_SECONDS);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore)
.authenticationManager(authenticationManager);
}
#Bean
public static PropertySourcesPlaceholderConfigurer properties() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
return propertySourcesPlaceholderConfigurer;
}
}
SecurityConfig
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Resource(name = "userService")
private UserDetailsService userDetailsService;
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(encoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/oauth/token").permitAll()
.anyRequest().authenticated();
}
#Bean
public BCryptPasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
#Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
#Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(50);
return bean;
}
}
ResourceServer
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "resource_id";
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/h2-console/**").permitAll()
.antMatchers("/user/register","/user/login").permitAll()
.antMatchers("/**").authenticated()
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler())
.and().headers().frameOptions().disable();
}
}
angularjs code
angular.module('myApp.view1', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
});
}])
.controller('View1Ctrl', ['$http','$httpParamSerializer', function($http, $httpParamSerializer) {
var ctrl = this;
this.data = {
grant_type:"password",
username: "",
password: "",
client_id: "client"
};
this.encoded = btoa("client:secret");
this.login = function() {
var req = {
method: 'POST',
url: "http://localhost:8080/api/oauth/token",
headers: {
"Authorization": "Basic " + ctrl.encoded,
"Content-type": "application/x-www-form-urlencoded; charset=utf-8"
},
data: $httpParamSerializer(ctrl.data)
}
$http(req).then(function(data){
console.log(data);
$http.defaults.headers.common.Authorization =
'Bearer ' + data.data.access_token;
$cookies.put("access_token", data.data.access_token);
window.location.href="index";
}, function(error) {
console.log(error);
});
}
}]);
This is my log from spring-boot
2018-06-22 19:01:45.134 INFO 23778 --- [nio-8080-exec-3] o.a.c.c.C.[Tomcat].[localhost].[/api] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-06-22 19:01:45.134 INFO 23778 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2018-06-22 19:01:45.143 INFO 23778 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 9 ms
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/oauth/token']
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/oauth/token'
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : matched
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /oauth/token at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /oauth/token at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /oauth/token at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /oauth/token at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'OPTIONS /oauth/token' doesn't match 'GET /logout
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'OPTIONS /oauth/token' doesn't match 'POST /logout
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'OPTIONS /oauth/token' doesn't match 'PUT /logout
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'OPTIONS /oauth/token' doesn't match 'DELETE /logout
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /oauth/token at position 5 of 11 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2018-06-22 19:01:45.144 DEBUG 23778 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /oauth/token at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2018-06-22 19:01:45.145 DEBUG 23778 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /oauth/token at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2018-06-22 19:01:45.145 DEBUG 23778 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /oauth/token at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2018-06-22 19:01:45.145 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#64454d87: 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'
2018-06-22 19:01:45.145 DEBUG 23778 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /oauth/token at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
2018-06-22 19:01:45.145 DEBUG 23778 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /oauth/token at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2018-06-22 19:01:45.145 DEBUG 23778 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /oauth/token at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2018-06-22 19:01:45.145 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/oauth/token'
2018-06-22 19:01:45.145 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /oauth/token; Attributes: [fullyAuthenticated]
2018-06-22 19:01:45.145 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#64454d87: 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
2018-06-22 19:01:45.146 DEBUG 23778 --- [nio-8080-exec-3] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter#62efc6af, returned: -1
2018-06-22 19:01:45.153 DEBUG 23778 --- [nio-8080-exec-3] 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
I find out solution for my problem. Main problem was with send OPTIONS request to oauth/token. I change my CorsFilter and SecurityConfig.
SecurityConfig.java
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll();
}
SimpleCorsFilter.java
#Component
#Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter {
public SimpleCorsFilter() {
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
#Override
public void init(FilterConfig filterConfig) {
}
#Override
public void destroy() {
}
}
After this changes I got access token

Spring security login error page, access denied

When I login into my oauth2 protected form with invalid credentials, the redirect to the default login error page 'login?error' does not work. In my logs I can see:
2018-02-01 10:58:35.935 DEBUG 17600 --- [http-nio-8899-exec-8] w.a.UsernamePasswordAuthenticationFilter : Updated SecurityContextHolder to contain null Authentication
2018-02-01 10:58:35.935 DEBUG 17600 --- [http-nio-8899-exec-8] w.a.UsernamePasswordAuthenticationFilter : Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler#49d1bcfd
2018-02-01 10:58:35.935 DEBUG 17600 --- [http-nio-8899-exec-8] .a.SimpleUrlAuthenticationFailureHandler : Redirecting to /login?error
2018-02-01 10:58:35.935 DEBUG 17600 --- [http-nio-8899-exec-8] o.s.s.web.DefaultRedirectStrategy : Redirecting to '/uaa/login?error'
But after the redirect there is an 'Access denied' exception:
2018-02-01 10:58:35.943 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /login?error=; Attributes: [authenticated]
2018-02-01 10:58:35.943 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#6fa90ed4: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffc7f0c: RemoteIpAddress: 127.0.0.1; SessionId: 03550F34462ABD6D42B5E224A4C478F9; Granted Authorities: ROLE_ANONYMOUS
2018-02-01 10:58:35.943 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter#337e3785, returned: -1
2018-02-01 10:58:35.943 DEBUG 17600 --- [http-nio-8899-exec-10] 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
Followed by a redirect to the login page again '/login'
2018-02-01 10:58:35.943 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using Ant [pattern='/**', GET]
2018-02-01 10:58:35.943 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Request '/login' matched by universal pattern '/**'
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/**/favicon.ico']]
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/**/favicon.ico'
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager#27122376, matchingMediaTypes=[application/json], useEquals=false, ignoredMediaTypes=[*/*]]]
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher : httpRequestMediaTypes=[text/html, application/xhtml+xml, image/webp, image/apng, application/xml;q=0.9, */*;q=0.8]
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing text/html
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith text/html = false
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing application/xhtml+xml
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith application/xhtml+xml = false
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing image/webp
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith image/webp = false
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing image/apng
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith image/apng = false
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing application/xml;q=0.9
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith application/xml;q=0.9 = false
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing */*;q=0.8
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher : Ignoring
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher : Did not match any media types
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
2018-02-01 10:58:35.948 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]]
2018-02-01 10:58:35.948 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
2018-02-01 10:58:35.948 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.util.matcher.AndRequestMatcher : All requestMatchers returned true
2018-02-01 10:58:35.948 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.s.HttpSessionRequestCache : DefaultSavedRequest added to Session: DefaultSavedRequest[http://localhost:8765/uaa/login?error=]
2018-02-01 10:58:35.948 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.a.ExceptionTranslationFilter : Calling Authentication entry point.
2018-02-01 10:58:35.948 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.web.DefaultRedirectStrategy : Redirecting to 'http://localhost:8765/uaa/login'
Does someone have an idea whats going wrong?
Edit: Add security configuration
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
#Order(-20)
protected static class LoginConfig extends WebSecurityConfigurerAdapter {
...
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/static/**", "/images/**", "/fonts/**", "/health", "/info");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.authorizeRequests()
.antMatchers("/console/**", "/reset").permitAll()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.requestMatchers()
.antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access", "/reset")
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
// #formatter:on
}
}
Another edit: When I access the oauth2 server directly without going trough Zuul, the redirect to the login error page 'login?error' page works.
Zuul's security configuration is
#Override
public void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.logout()
.permitAll()
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK))
.and()
.authorizeRequests()
.antMatchers("/uaa/**", "/login", "/xxx/view3/**", "/*/view404", "/*/view403").permitAll()
.and()
.authorizeRequests()
.antMatchers("/xxx/**/*").hasAnyRole("USER", "ADMIN")
.antMatchers("/yyy/**/*").hasRole("ADMIN")
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
.csrf().requireCsrfProtectionMatcher(csrfRequestMatcher()).csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler());
// #formatter:on
}
Edit: Added trace of requests
HAR-Export from Chrome DEV-Tools: Just share it
Just paste it in here to visualize: HAR viewer
The solution is to add
.antMatchers("/console/**", "/reset", "/login").permitAll()
to the WebSecurityConfigurerAdapter of the uaa-service. Final working configuration
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.authorizeRequests()
.antMatchers("/console/**", "/reset", "/login").permitAll()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.requestMatchers()
.antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access", "/reset")
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
// #formatter:on
}
If someone could explain why this is necessary, this would be nice.

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