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') }