Upgrading to spring-boot 1.4.1 - OAuth2 Security integration tests pass but client apps cannot log in - spring-boot

I have just upgraded an app from spring-boot 1.3.5 to spring-boot 1.4.1
For some reason, all my integration tests pass using oauth2. The test client can register users and perform operations with them during the maven integration test phase.
However when I start up my API server (which also contains the resource and authorization servers currently) clients can no longer get a bearer token.
My ClientDetailsService is never called on client login - but is registered with
#Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
on application startup.
Any ideas anyone?
Here is the relevant code:
Authorization Server Config:
import javax.inject.Inject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import blablabla.api.security.ClientDetailsServiceImpl;
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
#Inject
private AuthenticationManager authenticationManager;
#Inject
private ClientDetailsServiceImpl clientDetailsService;
#Inject
private UserDetailsService userDetailsService;
public AuthorizationServerConfiguration() {
System.out.println("loaded");
}
// beans
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
final JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
// FIXME: Include a more secure key in the java token store
accessTokenConverter.setSigningKey("3434343434");
return accessTokenConverter;
}
#Bean
public TokenStore tokenStore() {
//return new InMemoryTokenStore();
return new JwtTokenStore(accessTokenConverter());
}
// config
#Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager).accessTokenConverter(accessTokenConverter());
endpoints.userDetailsService(userDetailsService);
}
#Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
}
Resource Server Config:
import javax.inject.Inject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import blablabla.security_lib.config.UserDetailsServiceImpl;
#Configuration
#EnableResourceServer
#EnableWebSecurity
#ComponentScan("blablabla.api.security")
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Inject
private UserDetailsServiceImpl userDetailsService;
#Inject
private TokenStore tokenStore;
// Beans
#Bean
public TokenStore tokenStore() {
//return new InMemoryTokenStore();
return new JwtTokenStore(accessTokenConverter());
}
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
final JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
accessTokenConverter.setSigningKey("3434343434");
return accessTokenConverter;
}
// global security concerns
#Bean
public AuthenticationProvider authProvider() {
final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
return authProvider;
}
#Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authProvider());
}
#Primary
#Bean
public ResourceServerTokenServices getTokenServices () {
DefaultTokenServices services = new DefaultTokenServices();
services.setSupportRefreshToken(true);
services.setTokenStore(tokenStore);
return services;
}
// http security concerns
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll().and().csrf().disable();
/*http
.authorizeRequests().regexMatchers("^/members").anonymous()
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf()
.disable();*/
}
}
A few things I've also noticed - this all might mean something to somebody.
When login does not work (starting up the api and using a client)
The org.springframework.security.web.access.expression.WebExpressionVoter is passed a Collection containing one attribute of type org.springframework.security.web.access.expression.WebExpressionConfigAttribute with the value of
"#oauth2.throwOnError(authenticated)"
When login does work (running an acceptance test)
The org.springframework.security.web.access.expression.WebExpressionVoter is passed a Collection containing one attribute of type org.springframework.security.web.access.expression.WebExpressionConfigAttribute with the value of
"[fullyAuthenticated]"

So this turned out to not be a spring-boot issue at all, but instead some kind of issue that was caused in our gateway server when upgrading from spring-cloud Brixton.M2 release train to Brixton.RELEASE. This is sort of an unhelpful answer to an unhelpful question, so - happy to see this removed from SO.

Related

AuthorizationServerConfigurerAdapter cannot be resolved to a type

I have a Spring boot application v 1.5.10 with oauth version 2.0.14
I want to create a configuration file to implement AuthorizationServerConfigurerAdapter interface to generate access token from
package com.razzanati.oauth2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
#Configuration
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("client")
.secret(passwordEncoder().encode("password"))
.scopes("all")
.authorizedGrantTypes("client_credentials")
.and()
.withClient("client_b")
.secret(passwordEncoder().encode("password_b"));
}
#Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
#Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder(4);
}
}
This is what I've got:
The import org.springframework.security.oauth2 cannot be resolved
AuthorizationServerConfigurerAdapter cannot be resolved to a type
Any idea?

Problems with Spring-security [duplicate]

This question already has answers here:
Spring Security circular bean dependency
(8 answers)
Closed 10 months ago.
I need your help with spring-security. I have a repository with the code of my application in which I want to try to make spring-sequrity for authorization and authentication. The fact is that when I run a project, the terminal gives this error:
The dependencies of some of the beans in the application context form a cycle:
sequrityConfiguration (field private org.springframework.security.core.userdetails.UserDetailsService com.social_app_backend.config.SequrityConfiguration.userDetailsService)
userServiceImpl defined in file [J:\backend_for_social_app\target\classes\com\social_app_backend\service\UserServiceImpl.class]
I used to run this code easily and it worked great. Tell me, what am I doing wrong, where is my mistake? Here is the repository, branch: connectingToDatabaseWithSequrity
SecurityConfiguration.java
package com.social_app_backend.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#Configuration
#EnableWebSecurity
public class SequrityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoauthenticationProvider());
}
#Bean
public AuthenticationProvider daoauthenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
return daoAuthenticationProvider;
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().cors().disable()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/registrate")
.anonymous()
.anyRequest().authenticated().and().httpBasic();
}
}
UserServiceImpl.java
package com.social_app_backend.service;
import com.social_app_backend.dao.UserDao;
import com.social_app_backend.dto.UserDto;
import com.social_app_backend.entity.User;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
#Service
#RequiredArgsConstructor
public class UserServiceImpl implements UserDetailsService, UserService {
private final UserDao userDao;
private final PasswordEncoder passwordEncoder;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userDao.findByUsername(username);
}
#Override
public String createUser(UserDto userDto) {
User user = new User();
user.setUsername(userDto.getUsername());
user.setPassword(passwordEncoder.encode(userDto.getPassword()));
user.setRole("ROLE_USER");
userDao.save(user);
return user.getUsername();
}
}
From the code, it seems that the Circular dependency is getting formed as you have used PasswordEncoder in UserServiceImpl as well as in SecurityConfig So, for creating SecurityConfig, Spring needs UserServiceImpl bean and UserServiceImpl needs PasswordEncoder defined in SecurityConfig.
To remove the cycle, create a separate Configuration class with #Configuration, shift the PasswordEncoder bean creation in that config, and autowire it in SequrityConfiguration as well as UserServiceImpl
Update:
You can do it Like below:
#Configuration
public class MyConfiguration{
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
In SecurityConfig class,
#Configuration
#EnableWebSecurity
public class SequrityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private PasswordEncoder passwordEncoder;
....
#Bean
public AuthenticationProvider daoauthenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
return daoAuthenticationProvider;
}
}

Spring Basic Auth not working using BCrypt Encoding - I am getting redirected to login popup again even after entering correct credentials

Below is my PasswordEncoder Class
package com.example.springsecuritybasic.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#Configuration
public class PasswordConfig {
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Below is my ApplicationSecurityConfig Class
package com.example.springsecuritybasic.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
#Configuration
#EnableWebSecurity
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter{
private final PasswordEncoder passwordEncoder;
#Autowired
public ApplicationSecurityConfig(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/","index","/css/*","/js/*")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
#Override
protected UserDetailsService userDetailsService() {
UserDetails annasmithUser = User.builder()
.username("anna")
.password(passwordEncoder.encode("password"))
.roles("STUDENT")
.build();
return new InMemoryUserDetailsManager(
annasmithUser
);
}
}
Below is my Main Class -
package com.example.springsecuritybasic;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringsecuritybasicApplication {
public static void main(String[] args) {
SpringApplication.run(SpringsecuritybasicApplication.class, args);
}
}
From the WebSecurityConfigurerAdapter#userDetailsService Javadoc:
Allows modifying and accessing the UserDetailsService from userDetailsServiceBean() without interacting with the ApplicationContext. Developers should override this method when changing the instance of userDetailsServiceBean().
To configure a custom user, you can register a UserDetailsService bean rather than overriding the method
#Bean
protected UserDetailsService userDetailsService() {
UserDetails annasmithUser = User.builder()
.username("anna")
.password(this.passwordEncoder.encode("password"))
.roles("STUDENT")
.build();
return new InMemoryUserDetailsManager(
annasmithUser
);
}

How to make spring-boot 1.5.0 support this oauth2 solution?

I am using spring boot 1.5.0 with java 7 and am using following classes for implementation of Oauth for securing REST API
1) AuthorizationServerConfiguration.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
import org.springframework.security.oauth2.provider.token.TokenStore;
#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 {
int accessTokenMinutesValidity = 60;
int refreshTokenMinutesValidity = 24 * 60;
clients.inMemory()
.withClient("my-trusted-client")
.authorizedGrantTypes("password", "client_credentials", "refresh_token")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust")
.secret("{noop}secret")
.accessTokenValiditySeconds(60 * accessTokenMinutesValidity ).//Access token is only valid for 60 minutes.
refreshTokenValiditySeconds(60 * refreshTokenMinutesValidity);//Refresh token is only valid for 24 hours
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer
.allowFormAuthenticationForClients()
.realm(REALM+"/client");
}
}
2) MethodSecurityConfig.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
#Autowired
private OAuth2SecurityConfiguration securityConfig;
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
3) OAuth2SecurityConfiguration.java
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
#SuppressWarnings("deprecation")
#Configuration
#EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private ClientDetailsService clientDetailsService;
#Autowired
private DataSource dataSource;
#Primary
#Bean
public DataSource customDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
//dataSource properties set here
return dataSource;
}
#Bean
#ConfigurationProperties("spring.datasource")
public DataSource ds() {
return customDataSource();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
{
PasswordEncoder encoder = NoOpPasswordEncoder.getInstance();
BCryptPasswordEncoder enc;
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select USERNAME, ENC_PASSWD as PASSWORD, IS_ACTIVE AS ENABLED FROM USER_MSTR WHERE USERNAME=?")
.authoritiesByUsernameQuery("select USERNAME, 'ROLE_CLIENT' as ROLE from USER_MSTR where USERNAME=?")
.passwordEncoder(NoOpPasswordEncoder.getInstance())
;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/oauth/token").permitAll();
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
#Bean
#Autowired
public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){
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 {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
}
4) ResourceServerConfiguration.java
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
#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).stateless(false);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.
anonymous().disable()
.requestMatchers()
.antMatchers("/category_mstr/**", "/equipment/**", "/param_mstr/**", "/chklist_txn/**", "/settings/**", "/user/**")
.and().authorizeRequests()
.antMatchers("/category_mstr/**", "/equipment/**", "/param_mstr/**", "/chklist_txn/**", "/settings/**", "/user/**")
.access("hasRole('ROLE_CLIENT')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
However when accessing /oauth/token , I am getting error message saying "bad credentials" even when provided proper credentials
However if I use java 8 and spring boot 2.1.5 for same issue, then it runs fine and works as expected.
The old versions it was not necessary to add {noop} then remove it, since the latest versions work by using the password encoder {noop}.

Get the user details while generating the token in spring security oauth2

I am using spring boot with spring security oauth2 for my project, i want to get the user details of the user who generates the token. And also i don't want to call separate API for getting the details.
This is the code what i used.
package authorization;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
import authorization.service.CustomUserDetailsService;
#Configuration
public class OAuth2ServerConfiguration {
private static final String RESOURCE_ID = "restservice";
#Configuration
#EnableResourceServer
protected static class ResourceServerConfiguration extends
ResourceServerConfigurerAdapter {
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources
.resourceId(RESOURCE_ID);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.fullyAuthenticated();
}
}
#Configuration
#EnableAuthorizationServer
public static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private TokenStore tokenStore = new InMemoryTokenStore();
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Autowired
private CustomUserDetailsService userDetailsService;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endPoints){
endPoints
.tokenStore(this.tokenStore)
.authenticationManager(this.authenticationManager)
.userDetailsService(userDetailsService);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("testuser")
.authorizedGrantTypes("password","refresh_token")
.authorities("USER")
.scopes("read","write")
.resourceIds(RESOURCE_ID)
.secret("testpassword");
}
#Bean
#Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(this.tokenStore);
return tokenServices;
}
}
}
I found the answer.
package authorization;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
import authorization.service.CustomUserDetailsService;
#Configuration
public class OAuth2ServerConfiguration {
private static final String RESOURCE_ID = "restservice";
#Configuration
#EnableResourceServer
protected static class ResourceServerConfiguration extends
ResourceServerConfigurerAdapter {
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources
.resourceId(RESOURCE_ID);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.fullyAuthenticated();
}
}
#Configuration
#EnableAuthorizationServer
public static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private TokenStore tokenStore = new InMemoryTokenStore();
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Autowired
private CustomUserDetailsService userDetailsService;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endPoints){
endPoints
.tokenStore(this.tokenStore)
.authenticationManager(this.authenticationManager)
.userDetailsService(userDetailsService);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("testuser")
.authorizedGrantTypes("password","refresh_token")
.authorities("USER")
.scopes("read","write")
.resourceIds(RESOURCE_ID)
.secret("testpassword");
}
#Bean
#Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(this.tokenStore);
tokenServices.setTokenEnhancer(tokenEnhancer());
return tokenServices;
}
// Some #Bean here like tokenStore
#Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
public class CustomTokenEnhancer implements TokenEnhancer {
#Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
User user = (User) authentication.getPrincipal();
final Map<String, Object> additionalInfo = new HashMap<>();
additionalInfo.put("User", userDetailsService.viewProfile(user.getUsername()));
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
return accessToken;
}
}
}
}

Resources