Spring Boot disable security for tests - spring-mvc

I am trying to create a REST Api with Spring-Boot and I need to disable security for testing purposes. I want to be able to use PostMan without any security constrain.
I have tried several ways but nothing seems to work it's as if the AplicationTest configurations are never applied.
This is the code for my ApplicationTest class
#SpringBootApplication
#Configuration()
public class ApplicationTests {
public static void main(String[] args) {
SpringApplicationBuilder ab = new SpringApplicationBuilder(ApplicationTests.class);
Map<String, Object> properties = new HashMap<>();
properties.put("server.port", 9999);
properties.put("security.basic.enabled", false);
properties.put("security.enable-csrf", false);
ab.properties(properties);
ab.run(args);
}
#Configuration
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable();
http.authorizeRequests().antMatchers("/**").permitAll();
}
}
}
This is my SecurityConfig class
#Configuration
#ComponentScan("com.app")
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
#EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
AuthenticationService authenticationService;
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.httpBasic().and()
.authorizeRequests()
.antMatchers("/api/business/**").hasAnyRole("BUSINESS", "ADMIN")
.antMatchers("/api/users/**").hasAnyRole("USER", "ADMIN")
.antMatchers("/api/admins/**").hasRole("ADMIN")
.antMatchers("/**").permitAll()
.anyRequest().authenticated()
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
// #formatter:on
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
ShaPasswordEncoder encoder = new ShaPasswordEncoder();
auth.userDetailsService(authenticationService).passwordEncoder(encoder);
}
}

Related

After using custom login form , OAuth2 server not redirecting to client server

Authentication and Authorization is working fine. But after successful login it not redirecting me to client side further it open source code of some .js file. While previous (without custom login form loginPage("/login")) it successfully redirecting me to last page clicked (client side) which called for authenticate.
My Server side code as below:
Authorization server
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("ClientId")
.secret("secret")
.authorizedGrantTypes("authorization_code")
.scopes("user_info")
.redirectUris("http://localhost:8082/ui/login")
.autoApprove(true);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
}
Resource Server
#Configuration
#EnableResourceServer
public class ResourceServer extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/api/**").and().authorizeRequests()
.antMatchers("/api/**").authenticated().and()
.antMatcher("/rest/hello/principal")
.authorizeRequests().anyRequest().authenticated();
}
My Security Config
#Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private CustomUserDetailsService userDetailsService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/login").permitAll().antMatchers("/oauth/token/revokeById/**").permitAll()
.antMatchers("/tokens/**").permitAll().anyRequest().authenticated().and()
.formLogin().loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.failureUrl("/login?error")
.defaultSuccessUrl("/").permitAll().and()
.csrf().disable();
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordencoder());
}
#Bean(name = "passwordEncoder")
public PasswordEncoder passwordencoder() {
return new CustomPasswordEncoder();
}
}
you need to create
SimpleUrlAuthenticationSuccessHandler implementation
public class RefererRedirectionAuthenticationSuccessHandler
extends SimpleUrlAuthenticationSuccessHandler
implements AuthenticationSuccessHandler {
public RefererRedirectionAuthenticationSuccessHandler() {
super();
setUseReferer(true);
}
}
and add one line to the WebSecurityConfiguration
.successHandler(new RefererRedirectionAuthenticationSuccessHandler())
And after that you method will look like as shown below
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/login").permitAll().antMatchers("/oauth/token/revokeById/**").permitAll()
.antMatchers("/tokens/**").permitAll().anyRequest().authenticated().and()
.formLogin().loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(new RefererRedirectionAuthenticationSuccessHandler())
.failureUrl("/login?error")
.defaultSuccessUrl("/").permitAll().and()
.csrf().disable();
}

Spring Boot OAuth2 Resource server configs not reflecting

Hi I am setting up spring boot Oauth2, for some reason the resource server configs are not being recognised.
I am able to generate the bearer token but when I try to hit any of the url the response is the login page from basic http spring security.
My guess I am missing some backend stuff the spring boot does by default.
I have used similar configs for a normal spring MVC project and it worked. Any pointers as to why this is happening will be helpful.
Like to add one more question spring seems to be finding these config classes earlier we needed to use #Import some one explain how spring does this or links to any documentation will also do.
AppStart.java
#SpringBootApplication(scanBasePackages = { "com.spr.*" })
public class AppStart extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(AppStart.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AppStart.class);
}
}
AuthorizationServer.java
#Configuration
#EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
#Autowired
private TokenStore tokenStore;
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Autowired
private DataSource dataSource;
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("confidential").secret("secret").authorizedGrantTypes("password").scopes("read",
"write");
// clients.jdbc(dataSource);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore).authenticationManager(authenticationManager);
}
#Bean
#Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(tokenStore);
return tokenServices;
}
}
AppSecurityConfigs.java
#Configuration
#EnableWebSecurity
public class AppSecurityConfigs extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource dataSource;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("asd").password("asd").authorities("USER");
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public TokenStore tokenStore() {
// return new JdbcTokenStore(dataSource);
return new InMemoryTokenStore();
}
}
ResourceServer
#Configuration
#EnableResourceServer
public class ResourceServer extends ResourceServerConfigurerAdapter {
#Override
public void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/private/**").hasAuthority("USER");
http.authorizeRequests().anyRequest().permitAll();
}
}

Spring/OAuth2 Error - InsufficientAuthenticationException, There is no client authentication. Try adding an appropriate authentication filter

I've been stuck for hours trying to figure out what in the world is going wrong with this Spring Security OAuth2 implementation.
The error occurs when I go to hit the /oauth/token endpoint:
localhost:8080/my-oauth-practice-app/oauth/token
Error: InsufficientAuthenticationException, There is no client authentication. Try adding an appropriate authentication filter.
AUTHORIZATION SERVER CONFIGURATION
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
#Qualifier("authenticationManagerBean")
AuthenticationManager authenticationManager;
#Autowired
DefaultTokenServices tokenServices;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
super.configure(endpoints);
endpoints.tokenServices(this.tokenServices).authenticationManager(this.authenticationManager);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
super.configure(security);
security.tokenKeyAccess("permitAll()");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("clientid").secret("clientpass").authorizedGrantTypes("password").scopes("read").autoApprove(true);
}
}
RESOURCE SERVER CONFIGURATION
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Autowired
DefaultTokenServices tokenServices;
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
super.configure(resources);
resources.tokenServices(this.tokenServices);
}
#Override
public void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests().anyRequest().hasRole("USER");
}
}
GENERAL WEB SECURITY CONFIGURATION
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Primary
#Bean
DefaultTokenServices tokenServices() {
DefaultTokenServices d = new DefaultTokenServices();
d.setAccessTokenValiditySeconds(600);
d.setRefreshTokenValiditySeconds(1000);
d.setTokenStore(new InMemoryTokenStore());
return d;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/**").hasRole("USER");
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
You should check WebSecurityConfigurerAdapter method like this:
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/webjars/**", "/oauth/**");
}
remove "/oauth/**" path. otherwise
TokenEndpoint.postAccessToken(Principal principal, #RequestParam Map<String, String> parameters)
principal will be null.

Spring Security configuration for Basic Authentication and Form Login

A Spring Bean methods in an application I'm working on are being called in two ways:
through AngularJS and
Spring MVC controller(Form login) or by using SOAP(Basic Authentication).
To allow this I have setup the following configuration for the CXF servlet:
#Configuration
public class CxfConfiguration {
#Autowired
private ApplicationContext applicationContext;
#Bean
public ServletRegistrationBean dispatcherServletSOAP() {
return new ServletRegistrationBean(new CXFServlet(), "/soap/*");
}
#Bean(name= Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
#Bean
public Endpoint documentEndpoint(){
Bus bus = (Bus) applicationContext.getBean(Bus.DEFAULT_BUS_ID);
DocumentService implementor = new DocumentServiceImpl();
EndpointImpl endpoint = new EndpointImpl(bus, implementor);
endpoint.publish("/document");
return endpoint;
}
and security configuration:
#Configuration
#Order(1)
public static class SOAPSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.httpBasic()
.and()
.antMatcher("/soap/**")
.authorizeRequests()
.anyRequest()
.hasRole("USER");
}
}
#Configuration
#Order(2)
public static class HTTPSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/soap/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
I realize that this isn't a very good configuration as there are several cases in which from the browser or SOAP UI, things don't work as expected.
My questions would be: what would be a good way to implement security based on these requirements and am I on the right track with this configuration?
Also, I'm using Spring Boot 1.3.2 and Apache CXF 3.1.4
I finally ended up with this configuration that works:
#Configuration
#EnableWebSecurity
public class MultiHttpSecurityConfig {
#Configuration
#Order(1)
public static class SOAPWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().ignoringAntMatchers("/soap/**")
.and()
.antMatcher("/soap/**")
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().requestCache().disable();
}
}
#Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.and()
.logout().permitAll();
}
}
}
You should try this, may be it will help you:
#Configuration
#EnableWebSecurity
#Profile("container")
public class SOAPSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AuthenticationProvider authenticationProvider;
#Autowired
private AuthenticationProvider authenticationProviderDB;
#Override
#Order(1)
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
#Order(2)
protected void ConfigureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProviderDB);
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/scripts/**","/styles/**","/images/**","/error/**");
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/rest/**").authenticated()
.antMatchers("/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.successHandler(new AuthenticationSuccessHandler() {
#Override
public void onAuthenticationSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication a) throws IOException, ServletException {
//To change body of generated methods,
response.setStatus(HttpServletResponse.SC_OK);
}
})
.failureHandler(new AuthenticationFailureHandler() {
#Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException ae) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
})
.loginProcessingUrl("/access/login")
.and()
.logout()
.logoutUrl("/access/logout")
.logoutSuccessHandler(new LogoutSuccessHandler() {
#Override
public void onLogoutSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication a) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
})
.invalidateHttpSession(true)
.and()
.exceptionHandling()
.authenticationEntryPoint(new Http403ForbiddenEntryPoint())
.and()
.csrf()//Disabled CSRF protection
.disable();
}
}

Spring OAuth2 2.0.9 upgrade

I'm trying to upgrade Spring Security OAuth2 from 2.0.3 to 2.0.9.
Below is my configuration.
#Configuration
public class SecurityConfig {
#Autowired
private ClientDetailsService clientDetailsService;
#Autowired
private RedisConnectionFactory redisConnectionFactory;
#Bean
public TokenStore tokenStore() {
return new RedisTokenStore(redisConnectionFactory);
}
#Primary
#Bean
public AuthorizationServerTokenServices tokenServices() throws Exception {
final DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setAccessTokenValiditySeconds(6000);
tokenServices.setClientDetailsService(clientDetailsService);
tokenServices.setTokenEnhancer(new RedrumTokenEnhancer());
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(tokenStore());
return tokenServices;
}
#Bean
public UserApprovalHandler userApprovalHandler() throws Exception {
RedrumUserApprovalHandler handler = new RedrumUserApprovalHandler();
handler.setApprovalStore(approvalStore());
handler.setClientDetailsService(clientDetailsService);
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setUseApprovalStore(true);
return handler;
}
#Bean
public ApprovalStore approvalStore() {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore());
return store;
}
#Configuration
#Order(Ordered.HIGHEST_PRECEDENCE)
#EnableWebSecurity
protected static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Value("${baseUrl}")
private String baseUrl;
#Autowired
private DataSource dataSource;
#Resource
private PasswordEncoder passwordEncoder;
#Bean
public ClientDetailsService clientDetailsService() throws Exception {
ClientDetailsServiceConfiguration serviceConfig = new ClientDetailsServiceConfiguration();
serviceConfig.clientDetailsServiceConfigurer().inMemory()
.withClient("xyz")
.secret("...................")
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "client_credentials")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("blah")
return serviceConfig.clientDetailsService();
}
#Bean
public UserDetailsService clientDetailsUserDetailsService() throws Exception {
return new ClientDetailsUserDetailsService(clientDetailsService());
}
#Bean
public ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter() throws Exception {
ClientCredentialsTokenEndpointFilter filter = new ClientCredentialsTokenEndpointFilter();
filter.setAuthenticationManager(authenticationManagerBean());
filter.afterPropertiesSet();
return filter;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder> jdbcUserDetail = new JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder>();
jdbcUserDetail.dataSource(dataSource);
jdbcUserDetail.passwordEncoder(passwordEncoder);
jdbcUserDetail.authoritiesByUsernameQuery("select a.username, r.role_name from account a, role r, account_role ar where a.id = ar.account_id and r.id = ar.role_id and a.username = ?");
jdbcUserDetail.usersByUsernameQuery("select a.username, a.password, a.enabled, a.email from account a where a.username = ?");
auth.apply(jdbcUserDetail);
auth.userDetailsService(clientDetailsUserDetailsService());
}
#Bean(name="authenticationManager")
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
protected AuthenticationEntryPoint authenticationEntryPoint() {
OAuth2AuthenticationEntryPoint entryPoint = new OAuth2AuthenticationEntryPoint();
entryPoint.setTypeName("Basic");
entryPoint.setRealmName("zzz/client");
return entryPoint;
}
#Override
public void configure(WebSecurity webSecurity) throws Exception {
webSecurity
.ignoring()
.antMatchers("/resources/**", "/swagger/**", "/copyright*", "/api-docs/**")
.antMatchers(HttpMethod.POST, "/api/**/account")
.and()
.debug(false);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.anonymous().disable()
.requiresChannel().anyRequest().requiresSecure();
http
.antMatcher("/oauth/token")
.authorizeRequests().anyRequest().authenticated()
.and()
.httpBasic().authenticationEntryPoint(authenticationEntryPoint())
.and()
.csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/token")).disable()
.exceptionHandling().accessDeniedHandler(oAuth2AccessDeniedHandler())
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http
.addFilterBefore(clientCredentialsTokenEndpointFilter(), BasicAuthenticationFilter.class);
// #formatter:on
}
#Bean
public OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler() {
return new OAuth2AccessDeniedHandler();
}
}
#Configuration
#EnableResourceServer
protected static class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Autowired
private ResourceServerTokenServices tokenServices;
#Autowired
private OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler;
#Autowired
private ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter;
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenServices(tokenServices);
resources.resourceId("My resource");
}
#Override
public void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.requiresChannel().anyRequest().requiresSecure();
// API calls
http
.anonymous().disable()
.authorizeRequests()
.antMatchers("/api/**", "/whatever")
.access("#oauth2.hasScope('blah') and (hasRole('ROLE_USER'))")
.and()
.addFilterBefore(clientCredentialsTokenEndpointFilter, BasicAuthenticationFilter.class)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.NEVER)
.and()
.exceptionHandling()
.accessDeniedHandler(oAuth2AccessDeniedHandler);
// #formatter:on
}
}
#Configuration
#EnableAuthorizationServer
protected static class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthorizationServerTokenServices tokenServices;
#Autowired
private ClientDetailsService clientDetailsService;
#Autowired
private UserApprovalHandler userApprovalHandler;
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.tokenServices(tokenServices)
.userApprovalHandler(userApprovalHandler);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients)
throws Exception {
clients.withClientDetails(clientDetailsService);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer)
throws Exception {
oauthServer.authenticationEntryPoint(authenticationEntryPoint)
.realm("zzz/clients");
}
}
}
This was working fine with 2.0.3 but now after upgrading to 2.0.9, I started getting "Unsupported grant type: password"
Here is the test;
curl -k -i -H "Accept: application/json" -X POST -d "grant_type=password&client_id=xyz&client_secret=zzzzzz&scope=blah&username=tester&password=121212" https://localhost:8443/myapp/oauth/token
and the result is;
{"error":"unsupported_grant_type","error_description":"Unsupported grant type: password"}
I'm on springframework.version 4.1.8.RELEASE and spring-security.version 3.2.8.RELEASE Really appreciate if I can get help on this.
The problem is that you are configuring to much.
Most of things, such as SessionCreationPolicy, OAuth2AccessDeniedHandler, AuthenticationEntryPoint, ClientCredentialsTokenEndpointFilter are already configured.
Do not confuse between ClientDetailsService and UserDetailsService. Try avoid to use ClientDetailsUserDetailsService if you don't know what it is.
Move #Bean declaration to right position, so they can wired up.
Care with #Order
Try this:
#Configuration
public class SecurityConfig {
#Configuration
#Order(4)
#EnableWebSecurity
protected static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Value("${baseUrl}")
private String baseUrl;
#Autowired
private DataSource dataSource;
#Resource
private PasswordEncoder passwordEncoder;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder> jdbcUserDetail = new JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder>();
jdbcUserDetail.dataSource(dataSource);
jdbcUserDetail.passwordEncoder(passwordEncoder);
jdbcUserDetail.authoritiesByUsernameQuery(
"select a.username, r.role_name from account a, role r, account_role ar where a.id = ar.account_id and r.id = ar.role_id and a.username = ?");
jdbcUserDetail.usersByUsernameQuery(
"select a.username, a.password, a.enabled, a.email from account a where a.username = ?");
auth.apply(jdbcUserDetail);
}
#Bean(name = "authenticationManager")
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
public void configure(WebSecurity webSecurity) throws Exception {
webSecurity
.ignoring()
.antMatchers("/resources/**", "/swagger/**", "/copyright*", "/api-docs/**")
.antMatchers(HttpMethod.POST, "/api/**/account")
.and()
.debug(false);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requiresChannel().anyRequest().requiresSecure();
// #formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
// TODO put CSRF protection back into this endpoint
.csrf()
.requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize")).disable()
;
// #formatter:on
}
}
#Configuration
#EnableResourceServer
protected static class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Autowired
private ResourceServerTokenServices tokenServices;
#Autowired
private OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler;
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenServices(tokenServices);
resources.resourceId("My resource");
}
#Override
public void configure(HttpSecurity http) throws Exception {
// #formatter:off
http.requiresChannel().anyRequest().requiresSecure();
// API calls
http
.requestMatchers()
.antMatchers("/api/**", "/whatever")
.and()
.authorizeRequests()
.anyRequest()
.access("#oauth2.hasScope('blah') and (hasRole('ROLE_USER'))");
// #formatter:on
}
}
#Configuration
#EnableAuthorizationServer
protected static class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private RedisConnectionFactory redisConnectionFactory;
#Bean
public TokenStore tokenStore() {
return new RedisTokenStore(redisConnectionFactory);
}
#Bean
public UserApprovalHandler userApprovalHandler() throws Exception {
RedrumUserApprovalHandler handler = new RedrumUserApprovalHandler();
handler.setApprovalStore(approvalStore());
handler.setClientDetailsService(clientDetailsService());
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService()));
handler.setUseApprovalStore(true);
return handler;
}
#Bean
public ApprovalStore approvalStore() {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore());
return store;
}
#Primary
#Bean
public DefaultTokenServices tokenServices() throws Exception {
final DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setAccessTokenValiditySeconds(6000);
tokenServices.setClientDetailsService(clientDetailsService());
tokenServices.setTokenEnhancer(new RedrumTokenEnhancer());
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(tokenStore());
return tokenServices;
}
#Bean
public ClientDetailsService clientDetailsService() throws Exception {
ClientDetailsServiceConfiguration serviceConfig = new ClientDetailsServiceConfiguration();
serviceConfig.clientDetailsServiceConfigurer().inMemory()
.withClient("xyz")
.secret("...................")
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "client_credentials")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("blah")
;
return serviceConfig.clientDetailsService();
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.tokenServices(tokenServices())
.userApprovalHandler(userApprovalHandler());
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.withClientDetails(clientDetailsService());
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer
.realm("zzz/clients")
.allowFormAuthenticationForClients();
}
}
}

Resources