invalid_token:Cannot convert access token to JSON - spring-boot

I get error while refreshing the token(grant_type=refresh_token). It seems that user did not use the application for long time and both access token as well as refresh token expired. When app now tried to refresh token, it gets the error
{
"error": "invalid_token",
"error_description": "Cannot convert access token to JSON"
}
I saw many posts on this issue but I am still facing this error. I tried to use setVerifierKey. But no luck. Here is the code:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Value("${security.signing-key}")
private String signingKey;
#Value("${security.encoding-strength}")
private Integer encodingStrength;
#Value("${security.security-realm}")
private String securityRealm;
#Autowired
private UserDetailsService userDetailsService;
#Bean
#Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
// .passwordEncoder(new ShaPasswordEncoder(encodingStrength));
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.httpBasic()
.realmName(securityRealm)
.and()
.csrf()
.disable();
}
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(signingKey);
return converter;
}
#Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
#Bean
#Primary //Making this primary to avoid any accidental duplication with another token service instance of the same name
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
}
//AuthorizationServerConfig
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Value("${security.jwt.client-id}")
private String clientId;
#Value("${security.jwt.client-secret}")
private String clientSecret;
#Value("${security.jwt.grant-type}")
private String grantType;
#Value("${security.jwt.scope-read}")
private String scopeRead;
#Value("${security.jwt.scope-write}")
private String scopeWrite = "write";
#Value("${security.jwt.resource-ids}")
private String resourceIds;
#Autowired
private TokenStore tokenStore;
#Autowired
private JwtAccessTokenConverter accessTokenConverter;
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private UserDetailsService userDetailsService;
#Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
configurer
.inMemory()
.withClient(clientId)
.secret(clientSecret)
.authorizedGrantTypes("client_credentials", "password", "refresh_token", "authorization_code")
.scopes(scopeRead, scopeWrite)
// .accessTokenValiditySeconds(60)
// .refreshTokenValiditySeconds(2000)
.resourceIds(resourceIds);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
enhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter));
endpoints.tokenStore(tokenStore)
.accessTokenConverter(accessTokenConverter)
.tokenEnhancer(enhancerChain).userDetailsService(userDetailsService)
.authenticationManager(authenticationManager);
}
}
I expect that token will be refreshed but I get the error as mentioned above. my config properties are:
security.oauth2.resource.filter-order=3
security.signing-key=ZMaasazkSjmaasw
security.encoding-strength=256
security.security-realm=Spring Boot JWT Example Realm
security.jwt.grant-type=password security.jwt.scope-read=read
security.jwt.scope-write=write
security.jwt.resource-ids=testjwtresourceid
Any Help appreciated!!

Related

Spring ouath2Authserver oauth/token returns internal server Error for grant client_credentials

Im trying to implement Authorisation server with password and client_credentials grant
#Configuration
#EnableAuthorizationServer
public class OAuthConfiguration extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
public PasswordEncoder passwordEncoder;
#Autowired
private DataSource dataSource;
#Autowired
private TokenStore jwtTokenStore;
#Autowired
private JwtAccessTokenConverter jwtAccessTokenConverter;
#Autowired
private TokenEnhancer jwtTokenEnhancer;
#Bean
public TokenEnhancer jwtTokenEnhancer(){
return new JWTokenEnhancer();
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
enhancerChain.setTokenEnhancers(Arrays.asList(jwtTokenEnhancer(), jwtAccessTokenConverter));
endpoints
.authenticationManager(authenticationManager)
.tokenStore(jwtTokenStore)
.accessTokenConverter(jwtAccessTokenConverter)
.tokenEnhancer(enhancerChain);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
JdbcClientDetailsServiceBuilder jcsb = clients.jdbc(dataSource);
jcsb.passwordEncoder(passwordEncoder);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
oauthServer.passwordEncoder(passwordEncoder)
.tokenKeyAccess("permitAll()")
.checkTokenAccess("permitAll()");
}
}
web config file
Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Resource(name = "userService")
private UserDetailsService userDetailsService;
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public BCryptPasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
#Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(encoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/api-docs/**").permitAll();
}
#Override
public void configure(WebSecurity web) throws Exception {
// Allow eureka client to be accessed without authentication
web.ignoring().antMatchers("/*/")//
.antMatchers("/eureka/**")//
.antMatchers(HttpMethod.OPTIONS, "/**"); // Request type options should be allowed.
}
}
#Configuration
public class JwtTokenConfig {
#Bean
public TokenStore jwtTokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
#Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
accessTokenConverter.setSigningKey("dev");
return accessTokenConverter;
}
}
i have configured client details to pick up from database -
When i try to get access token based on password grant im able to get the access token
but when i try to get access token based on grnat_type client credentials - im getting internal server error .
Please help to check on what is wrong with my implementation.
enter image description here
In your class OAuthConfiguration, check client configuration present in configure(ClientDetailsServiceConfigurer clients) method. It appears that the JDBC client details service is not able to find any client details.
JdbcClientDetailsService jdbcClientDetailsService = new JdbcClientDetailsService(dataSource);
jdbcClientDetailsService.listClientDetails(); // This probably would be empty.
If so, configure JDBC client details service something like this:
clients.jdbc(dataSource).withClient(CLIEN_ID)
.secret(encoder.encode(CLIENT_SECRET))
.authorizedGrantTypes("password", "refresh_token", "client_credentials")
.scopes("read", "write")
.resourceIds(RESOURCE_ID).and().build();
Found the Issue .
public class JWTokenEnhancer implements TokenEnhancer{
#Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
Map<String, Object> info = new HashMap<>();
info.put("user-info", "user additional information...");
// User user = (User) authentication.getPrincipal();
// info.put("isAdmin", user.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()).contains("ROLE_ADMIN"));
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);
return accessToken;
}
The commented line was causing the issue as there was no user in case of client_credentials

SpringBoot OAuth2 error "Full authentication is required to access this resource"

I am trying to implement OAuth2 - SpringBoot authentication.
I have configured a path with permitAll(), but even though it is configured, it shows error
{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
}
I am using postman to test and simply trying to fetch all users in DB. When I call, the control is not coming to RestController. I would like to just get the users list and permitAll() is provided.
Can anyone please help ?
I am posting the code below.
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
DataSource dataSource;
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().
antMatchers(HttpMethod.POST, "/api/**").permitAll().
antMatchers(HttpMethod.POST,"/admin/**").hasAnyRole("ADMIN").
anyRequest().authenticated();
}
#Override
public void configure(AuthenticationManagerBuilder builder) throws Exception{
builder.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select usrnam,usrpwd, case when usrsta='A' then true else false end from chsusrmst where usrnam=?")
.authoritiesByUsernameQuery("select usrnam,usrtyp from chsusrmst where usrnam=?");
}
}
#RestController
#RequestMapping("/api")
public class UserController {
#Autowired
private BCryptPasswordEncoder passwordEncoder;
#Autowired
private UserRepository userRepository;
#PostMapping("/user/register")
public String register(#RequestBody User user) {
String encodedPassword = passwordEncoder.encode(user.getUserPassword());
user.setUserPassword(encodedPassword);
userRepository.save(user);
return "User created";
}
#PostMapping("/admin/findUser")
public User findUser(#RequestBody User user) {
return userRepository.findByUserName(user.getUserName());
}
#PostMapping("/user/findAllUsers")
public List<User> findAllUsers() {
return userRepository.findAll();
}
}
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
private final AuthenticationManager authenticationManager;
private final PasswordEncoder passwordEncoder;
private final UserDetailsService userDetailsService;
#Value("${jwt.clientId:client}")
private String clientId;
#Value("${jwt.client-secret:secret}")
private String clientSecret;
#Value("${jwt.signing-key:123}")
private String jwtSigningKey;
#Value("${jwt.accessTokenValidititySeconds:43200}") // 12 hours
private int accessTokenValiditySeconds;
#Value("${jwt.authorizedGrantTypes:password,authorization_code,refresh_token}")
private String[] authorizedGrantTypes;
#Value("${jwt.refreshTokenValiditySeconds:2592000}") // 30 days
private int refreshTokenValiditySeconds;
public AuthorizationServerConfig(AuthenticationManager authenticationManager, PasswordEncoder passwordEncoder, UserDetailsService userDetailsService) {
this.authenticationManager = authenticationManager;
this.passwordEncoder = passwordEncoder;
this.userDetailsService = userDetailsService;
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(clientId)
.secret(passwordEncoder.encode(clientSecret))
.accessTokenValiditySeconds(accessTokenValiditySeconds)
.refreshTokenValiditySeconds(refreshTokenValiditySeconds)
.authorizedGrantTypes(authorizedGrantTypes)
.scopes("read", "write")
.resourceIds("api");
}
#Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.accessTokenConverter(accessTokenConverter())
.userDetailsService(userDetailsService)
.authenticationManager(authenticationManager);
}
#Bean
JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
return converter;
}
}
#Configuration
#EnableResourceServer
public class ResourceServer extends ResourceServerConfigurerAdapter {
#Override
public void configure(ResourceServerSecurityConfigurer serverSecurityConfigurer) {
serverSecurityConfigurer.resourceId("api");
}
}
Thanks for your consideration. I found the issue. HttpSecurity configuration was missing in Resource server and it has been resolved by adding below section.
http
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/user**").permitAll()
.antMatchers("/user/**").permitAll()
.antMatchers("/admin**").hasAuthority("ADMIN")
.antMatchers("/api/**").authenticated()
.anyRequest().authenticated();

Springboot + Oauth2 - Failed to find access token

Am getting Failed to find access token for token 9ccc7637-04af-469d-93b8-209cbfac4e49 issue printed in a console when i call http://localhost:8081/oauth/token . Please find attached images for reference .
I gave my best but could find the issue .
Where i click oauth\token the token details are getting stored in database , but still throws error.
Unable to do API calls with access token created.
Please find below code and correct me .
Configuration
public class AppConfig {
#Value("${spring.datasource.url}")
private String datasourceUrl;
#Value("${spring.datasource.driver-class-name}")
private String dbDriverClassName;
#Value("${spring.datasource.username}")
private String dbUsername;
#Value("${spring.datasource.password}")
private String dbPassword;
#Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(dbDriverClassName);
dataSource.setUrl(datasourceUrl);
dataSource.setUsername(dbUsername);
dataSource.setPassword(dbPassword);
return dataSource;
}
#Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource());
}
}
#Configuration
#EnableAuthorizationServer
public class OAuthConfiguration extends AuthorizationServerConfigurerAdapter {
#Autowired
private final AuthenticationManager authenticationManager;
#Autowired
private final BCryptPasswordEncoder passwordEncoder;
#Autowired
private final UserDetailsService userService;
#Autowired
private TokenStore tokenStore;
public OAuthConfiguration(AuthenticationManager authenticationManager, BCryptPasswordEncoder passwordEncoder, UserDetailsService userService) {
this.authenticationManager = authenticationManager;
this.passwordEncoder = passwordEncoder;
this.userService = userService;
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("my-trusted-client")
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
.scopes("read","write","trust")
.resourceIds("oauth2-resource")
.accessTokenValiditySeconds(50)
.refreshTokenValiditySeconds(1000)
.secret(passwordEncoder.encode("secret"));
}
#Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.userDetailsService(userService)
.authenticationManager(authenticationManager)
.tokenStore(tokenStore);
}
#Bean
public OAuth2AccessDeniedHandler oauthAccessDeniedHandler() {
return new OAuth2AccessDeniedHandler();
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
}
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.requestMatchers().antMatchers("/**").and()
.authorizeRequests()
.antMatchers("/**").access("hasRole('ADMIN') or hasRole('USER')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsService userDetails;
#Autowired
DataSource dataSource;
#Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource).
usersByUsernameQuery("select username, password, enabled from users where username=?").
authoritiesByUsernameQuery("select username, roles from users where username=?");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/oauth/token").permitAll()
.antMatchers("/**").authenticated()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.csrf().disable();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder( bCryptPasswordEncoder() );
provider.setUserDetailsService(userDetails);
return provider;
}
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
/*
* #Autowired // here is configuration related to spring boot basic public void
* configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
* auth.inMemoryAuthentication() // static users
* .withUser("User").password(bCryptPasswordEncoder().encode("User")).
* roles("USER") .and()
* .withUser("Admin").password(bCryptPasswordEncoder().encode("Admin[")).
* roles("ADMIN"); }
*/
#Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetails)
.passwordEncoder(bCryptPasswordEncoder());
}
}
error in console :
enter image description here

How to verify signature utilizing accessTokenConverter?

I need to verify signature at resource server. I am signing JWT with private key at auth.server and It is signed OK, but I cannot find a way, how to verify it using accessTokenConverter. In my previous project, I did not use JDBC, so I was using jwtTokenStore and It worked without a problem, but I cannot verify that signature with JDBCTokenStore. How to do that? So code at authorization server works, I need to verify it at resource server... .setVerifiedKey(publicKey) should be working, but I need to configure it with JDBCTokenStore...
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private TokenStore tokenStore;
// #Autowired
// private JwtAccessTokenConverter accessTokenConverter;
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private UserDetailsService userCustomService;
#Autowired
private JdbcTemplate jdbcTemplate;
#Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
configurer
.jdbc(jdbcTemplate.getDataSource());
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore)
.reuseRefreshTokens(false)
.accessTokenConverter(accessTokenConverter())
.authenticationManager(authenticationManager)
.userDetailsService(userCustomService);
;
}
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
final JwtAccessTokenConverter converter = new JwtAccessTokenConverter(){
#Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
if(authentication.getOAuth2Request().getGrantType().equalsIgnoreCase("password")) {
final Map<String, Object> additionalInfo = new HashMap<String, Object>();
additionalInfo.put("organization", "NEJAKA INFORMACE");
((DefaultOAuth2AccessToken) accessToken)
.setAdditionalInformation(additionalInfo);
}
accessToken = super.enhance(accessToken, authentication);
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(new HashMap<>());
return accessToken;
}
};
KeyStoreKeyFactory keyStoreKeyFactory =
new KeyStoreKeyFactory(new ClassPathResource("test.jks"), "password".toCharArray());
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("test"));
return converter;
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("hasAuthority('ROLE_TRUSTED_CLIENT')").checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')");
}
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Autowired
private ResourceServerTokenServices tokenServices;
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenServices(tokenServices); }
#Override
public void configure(HttpSecurity http) throws Exception {
http.
anonymous().disable()
.authorizeRequests()
.antMatchers("/documents/**").authenticated()
.antMatchers("/users/**").authenticated()
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Bean
public JwtAccessTokenConverter accessTokenConverterr() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
Resource resource = new ClassPathResource("public.txt");
String publicKey = null;
try {
publicKey = IOUtils.toString(resource.getInputStream());
} catch (final IOException e) {
throw new RuntimeException(e);
}
converter.setVerifierKey(publicKey);
return converter;
}
}
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// private String signingKey = "MaYzkSjmkzPC57L";
#Autowired
private UserDetailsService userCustomService;
#Autowired
private JdbcTemplate jdbcTemplate;
private PasswordEncoder encoder;
public SecurityConfig(){
this.encoder = new BCryptPasswordEncoder();
}
#Bean
#Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
#Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userCustomService).passwordEncoder(encoder);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.
STATELESS)
.and()
.httpBasic()
.and()
.csrf()
.disable();
}
#Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(jdbcTemplate.getDataSource());
}
#Bean
#Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
}

How configure Spring boot CORS for Restful API?

I've used thi s guide (https://medium.com/emblatech/secure-your-spring-restful-apis-with-jwt-a-real-world-example-bfdd2679db5f) to secure RestFull API.
But now I've a CORS problem when I try to connect from a REACT JS app.
This is my configuration:
AuthorizationServerConfig
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Value("${security.jwt.client-id}")
private String clientId;
#Value("${security.jwt.client-secret}")
private String clientSecret;
#Value("${security.jwt.grant-type}")
private String grantType;
#Value("${security.jwt.grant-type-refresh}")
private String grantTypeRefresh;
#Value("${security.jwt.scope-read}")
private String scopeRead;
#Value("${security.jwt.scope-write}")
private String scopeWrite = "write";
#Value("${security.jwt.resource-ids}")
private String resourceIds;
#Autowired
private JwtAccessTokenConverter accessTokenConverter;
#Autowired
private AuthenticationManager authenticationManager;
#Qualifier("userDetailsServiceImpl")
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private DefaultTokenServices defaultTokenServices;
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient(clientId)
.secret("{noop}"+clientSecret)
.authorizedGrantTypes(grantType, grantTypeRefresh)
.scopes(scopeRead, scopeWrite)
.resourceIds(resourceIds);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenServices(defaultTokenServices).authenticationManager(authenticationManager)
.accessTokenConverter(accessTokenConverter).userDetailsService(userDetailsService);
}
}
ResourceServerConfig
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Autowired
ResourceServerTokenServices tokenServices;
#Value("${security.jwt.resource-ids}")
private String resourceIds;
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(resourceIds).tokenServices(tokenServices);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatchers()
.and()
.authorizeRequests()
.antMatchers("/actuator/**").permitAll()
.antMatchers("/oauth/**").authenticated();
}
}
SecurityConfig
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Value("${security.signing-key}")
private String signingKey;
#Value("${security.security-realm}")
private String securityRealm;
#Value("${security.jwt.token-validity-seconds}")
private int accessTokenValiditySeconds;
#Qualifier("userDetailsServiceImpl")
#Autowired
private UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.httpBasic()
.realmName(securityRealm)
.and()
.csrf().disable();
}
#Override
#Bean
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(signingKey);
return converter;
}
#Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
#Bean
public TokenEnhancerChain tokenEnhancerChain() {
final TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(new MyTokenEnhancer(), accessTokenConverter()));
return tokenEnhancerChain;
}
#Bean
#Primary
public DefaultTokenServices defaultTokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setTokenEnhancer(tokenEnhancerChain());
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setAccessTokenValiditySeconds(accessTokenValiditySeconds);
return defaultTokenServices;
}
private static class MyTokenEnhancer implements TokenEnhancer {
#Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
// TODO Auto-generated method stub
return accessToken;
}
}
}
In every call i do i receive this error:
GET http://localhost:8080/test 401
Access to XMLHttpRequest at 'http://localhost:8080/test' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I've also already tride some solution explained here for example: How to configure CORS in a Spring Boot + Spring Security application?
But nothing works for me.
Any help?
You need to add Cors Configuration to your application, so that it can accept AJAX requests from a different domain. Whether such requests are sent by react or angular or jquery, the server will still behave the same way.
The easiest way to accept CORS in your Spring Boot application is to add the following annotation to your Controller classes :
#CrossOrigin(origins="*")
Please beware, however, that when you use the wildcard (*), your service will accept Ajax requests from any domain, which is not secure. You might want to replace the wildcard by the specific domains that you want to accept requests from.
Repeating the annotation in all your controllers might be annoying and error-prone. Instead, you may use one the configuration solutions described in How to configure CORS in a Spring Boot + Spring Security application? or follow Spring documentation about CORS configuration

Resources