PROBLEM WITH required a bean of type 'org.springframework.security.core.userdetails.UserDetailsService' that could not be found - spring

When launching with mvn spring-boot:run or even with gradle returns that issue.
***************************
APPLICATION FAILED TO START
***************************
Description:
Field userDetailsService in com.ess.study.jwt.integration.config.SecurityConfig required a bean of type 'org.springframework.security.core.userdetails.UserDetailsService' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
The following candidates were found but could not be injected:
- Bean method 'inMemoryUserDetailsManager' in 'UserDetailsServiceAutoConfiguration' not loaded because #ConditionalOnMissingBean (types: org.springframework.security.authentication.AuthenticationManager,org.springframework.security.authentication.AuthenticationProvider,org.springframework.security.core.userdetails.UserDetailsService; SearchStrategy: all) found beans of type 'org.springframework.security.authentication.AuthenticationManager' authenticationManager
Action:
Consider revisiting the entries above or defining a bean of type 'org.springframework.security.core.userdetails.UserDetailsService' in your configuration.
Here are the main classes, all the requirements looks ok to me, I am using the org.springframework.boot release 2.0.6.RELEASE.RELEASE
package com.ess.study.jwt.integration.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Primary;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
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;
#Configuration
#EnableWebSecurity // Habilita la seguridad de Spring y consejos Spring Boot para aplicar todos los
// valores predeterminados sensibles
#EnableGlobalMethodSecurity(prePostEnabled = true) // Nos permite tener control de acceso a nivel de método.
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 BCryptPasswordEncoder(encodingStrength));
}
#Autowired
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;
}
//Nuevo metodo de decodificación.
#Bean
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
}
and:
package com.ess.study.jwt.integration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class StudySecuredApplication {
public static void main(String[] args) {
SpringApplication.run(StudySecuredApplication.class, args);
}
}
Using maven or gradle it returns the same issue. All annotations and packages names seems to be as required.
Thanks! :)

UserDetailsService is an interface and you have to create its implementation. Example:
#Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
private UsersRepository usersRepository;
#Transactional(readOnly = true)
#Override
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
try {
User user = usersRepository.findByLogin(login).get();
return new UserPrincipal(usersRepository.findByLogin(login).get());
} catch (NoSuchElementException e) {
throw new UsernameNotFoundException("User " + login + " not found.", e);
}
}
}

Related

Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through field 'securityService'

SecurityConfig
package com.book.entity.security.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
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.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private Environment env;
#Autowired
private SecurityService securityService;
private BCryptPasswordEncoder passwordEncoder() {
return SecurityUtility.passwordEncoder();
}
private static final String[] PUBLIC_MATCHERS = { "/css/**", "/js/**", "/image/**", "/", "/myAccount" };
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().
/* antMatchers("/**"). */
antMatchers(PUBLIC_MATCHERS).permitAll().anyRequest().authenticated();
http.csrf().disable().cors().disable().formLogin().failureUrl("/login?error").defaultSuccessUrl("/")
.loginPage("/login").permitAll().and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/?logout")
.deleteCookies("remember-me").permitAll().and().rememberMe();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(securityService).passwordEncoder(passwordEncoder());
}
}
SecurityUtility
package com.book.entity.security.impl;
import java.security.SecureRandom;
import java.util.Random;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
#Component
public class SecurityUtility {
private static final String SALT = "salt"; // Salt should be protected carefully
#Bean
public static BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12, new SecureRandom(SALT.getBytes()));
}
#Bean
public static String randomPassword() {
String SALTCHARS = "ABCEFGHIJKLMNOPQRSTUVWXYZ1234567890";
StringBuilder salt = new StringBuilder();
Random rnd = new Random();
while (salt.length() < 18) {
int index = (int) (rnd.nextFloat() * SALTCHARS.length());
salt.append(SALTCHARS.charAt(index));
}
String saltStr = salt.toString();
return saltStr;
}
}
UserRepository
package com.book.entity.security.impl;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.book.entity.User;
#Repository
public interface UserRepository extends JpaRepository<User, Long>{
User findByUsername(String userName);
}
SecurityService
package com.book.entity.security.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.book.entity.User;
#Service
public class SecurityService implements UserDetailsService {
#Autowired
private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
User user = userRepository.findByUsername(userName);
if (null == user) {
throw new UsernameNotFoundException("Username not found");
}
return user;
}
}
Error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through field 'securityService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityService': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract com.book.entity.User com.book.entity.security.impl.UserRepository.findByUsername(java.lang.String)! Unable to locate Attribute with the the given name [username] on this ManagedType [com.book.entity.User]

Spring-boot Digest authentication failure using Digest filter

I am new to this technology . I have trying to implement Digest Authentication for my Springboot application . I am getting below error while I am trying to call my application :There is no PasswordEncoder mapped for the id \"null\"","path":"/countryId/"}* Closing connection 0
curl command I am using to invoke : curl -iv --digest -u test:5f4dcc3b5aa765d61d8327deb882cf99 -d {"CountryCode": "INDIA"} http://localhost:9090/countryId/
Classes Details :
package com.sg.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
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.UserCache;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.authentication.www.DigestAuthenticationFilter;
import org.springframework.stereotype.Component;
#Component
#Configuration
#EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
CustomDigestAuthenticationEntryPoint customDigestAuthenticationEntryPoint;
/*#Bean
public BCryptPasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}*/
#Bean
public UserDetailsService userDetailsServiceBean()
{
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("test").password("{noop}password").roles("USER").build());
return manager;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers("/hello/**").permitAll().anyRequest().authenticated()
.and().exceptionHandling().authenticationEntryPoint(customDigestAuthenticationEntryPoint).and()
.addFilter(digestAuthenticationFilter());
}
//#Bean
DigestAuthenticationFilter digestAuthenticationFilter() throws Exception {
DigestAuthenticationFilter digestAuthenticationFilter = new DigestAuthenticationFilter();
digestAuthenticationFilter.setUserDetailsService(userDetailsServiceBean());
digestAuthenticationFilter.setAuthenticationEntryPoint(customDigestAuthenticationEntryPoint);
return digestAuthenticationFilter;
}
}
package com.sg.config;
import org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint;
import org.springframework.stereotype.Component;
#Component
public class CustomDigestAuthenticationEntryPoint extends DigestAuthenticationEntryPoint {
#Override
public void afterPropertiesSet() throws Exception {
setRealmName("Digest-Realm");
setKey("MySecureKey");
setNonceValiditySeconds(300);
super.afterPropertiesSet();
}
}
I have resolved the issue. Let me explain what went wrong first, in current Spring security, you can not use a plain text password, so have to keep some encrypting logic. But unfortunately Digest doesn't work with a encrypted password.
I have found a work around, instead using a Bean (Bycrypt), I have directly implemented PasswordEncoder interface, in a way, it should able to hold plain text password.
#Bean
public PasswordEncoder passwordEncoder() {
return new PasswordEncoder() {
#Override
public String encode(CharSequence rawPassword) {
return rawPassword.toString();
}
#Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return rawPassword.toString().equals(encodedPassword);
}
};
}

How to get jwt token string on service layer when user request first time using jwt, Oauth2, spring security?

I am new in development of micro-services with jwt.
Here is my project structure:
First micro-service is used to authenticate users by jwt and Oauth2
using username and password. This microservice is called auth-service.
Login request url is like:
[http://localhost:9092/oauth/token?username=s#sawai.com&password=randomPassword&grant_type=password][1]
By calling this url we got jwt token like:
{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsib2F1dGgyX2lkIl0sInVzZXJfbmFtZSI6InNAc2F3YWkuY29tIiwic2NvcGUiOlsicmVhZCIsIndyaXRlIl0sInRlbmFudElkIjoic2F3YWkuY29tIiwic3lzdGVtR2VuZXJhdGVkUGFzc3dvcmQiOnRydWUsImlkIjoiNTYzOTFhYzAtZDc4OC00ODEyLThmYWMtODEwZTIyMjdjYmI1IiwiZXhwIjoxNTI0NzMxNzgwLCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6ImY0ZTNmNTM5LWRkNDgtNGMxMy05OTg5LTcwM2E1NWYxMjNlYyIsImVtYWlsIjoic0BzYXdhaS5jb20iLCJjbGllbnRfaWQiOiJ0cnVzdGVkLWFwcCJ9.AS1tXpUcPMgEw63FrvPP-xGBz7qCi14Eqe29rDzTXPg","token_type":"bearer","refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsib2F1dGgyX2lkIl0sInVzZXJfbmFtZSI6InNAc2F3YWkuY29tIiwic2NvcGUiOlsicmVhZCIsIndyaXRlIl0sImF0aSI6ImY0ZTNmNTM5LWRkNDgtNGMxMy05OTg5LTcwM2E1NWYxMjNlYyIsInRlbmFudElkIjoic2F3YWkuY29tIiwic3lzdGVtR2VuZXJhdGVkUGFzc3dvcmQiOnRydWUsImlkIjoiNTYzOTFhYzAtZDc4OC00ODEyLThmYWMtODEwZTIyMjdjYmI1IiwiZXhwIjoxNTI0NzQ2MTgwLCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6IjI1ZmJlY2IyLWRhODgtNDY1ZS1iM2I2LTFlN2NmYjBlYmVjMiIsImVtYWlsIjoic0BzYXdhaS5jb20iLCJjbGllbnRfaWQiOiJ0cnVzdGVkLWFwcCJ9.jSG5zUBzu9yGqnBueU7fkIZV6XhXD8oCkYCerwHkkOw","expires_in":14399,"scope":"read write","tenantId":"sawai.com","systemGeneratedPassword":true,"id":"56391ac0-d788-4812-8fac-810e2227cbb5","email":"s#sawai.com","jti":"f4e3f539-dd48-4c13-9989-703a55f123ec"}
On auth service database we just create a single table called users with following fields:
id varchar(255)
created_on datetime
last_modified_date datetime
email varchar(255)
enabled bit(1)
password varchar(255)
role varchar(255)
system_generated_password bit(1)
tenant_id varchar(255)
validate bit(1)
OK.
Now another micro-service is called company and in company service we have list of users(not same as auth service users, because auth service contains users for multiple micro-services like: Company, Candidate etc).
Now we want to maintain last_logged_on for company users. So admin can check when an user logged in last time.
What we try to do is: When user login using auth service and user type is company user then call company service and update users last_logged_on. For calling company service we need jwt-access-token because urls are secure on company side. So how can we get access token on auth service when we request to get jwt token.
Here is configuration for jwt with spring boot on auth side.
package com.cs.je.auth.config.jwt;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
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.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
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 com.cs.je.auth.enums.Role;
import com.cs.je.auth.model.User;
/**
* #author sawai
*
*/
#Configuration
#EnableAuthorizationServer
public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
#Value("${auth.token.time}")
private int accessTokenValiditySeconds;
#Value("${refresh.token.time}")
private int refreshTokenValiditySeconds;
#Value("${security.oauth2.resource.id}")
private String resourceId;
#Value("${trusted.app.name}")
private String trustedAppName;
#Value("${trusted.app.secret}")
private String trustedAppSecret;
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private CustomAccessTokenConverter customAccessTokenConverter;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(this.authenticationManager)
.tokenServices(tokenServices())
.tokenStore(tokenStore())
.accessTokenConverter(accessTokenConverter());
}
#Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer
// we're allowing access to the token only for clients with 'ROLE_TRUSTED_CLIENT' authority
//.tokenKeyAccess("permitAll()")
.tokenKeyAccess("hasAuthority('ROLE_TRUSTED_CLIENT')")
.checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(trustedAppName)
.authorizedGrantTypes("client_credentials", "password", "refresh_token")
.authorities("ROLE_TRUSTED_CLIENT")
.scopes("read", "write")
.resourceIds(resourceId)
// .accessTokenValiditySeconds(accessTokenValiditySeconds)
// .refreshTokenValiditySeconds(refreshTokenValiditySeconds)
.secret(trustedAppSecret);
}
#Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
System.out.println("3333333333333");
DefaultAccessTokenConverter tokenConverter = new DefaultAccessTokenConverter();
tokenConverter.setUserTokenConverter(new DefaultUserAuthenticationConverter() {
#Override
public Authentication extractAuthentication(Map<String, ?> map) {
Authentication authentication = super.extractAuthentication(map);
System.out.println("222222222222");
// User is my custom UserDetails class
User user = new User();
user.setTenantId(map.get("tenantId").toString());
user.setEmail(map.get("email").toString());
user.setId(map.get("id").toString());
//user.setPassword(map.get("password").toString());
//System.out.println("date " + );
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
authorities.addAll(authentication.getAuthorities());
user.setGrantedAuthorities(authorities);
user.setRole(Role.valueOf(authorities.iterator().next().toString()));
//user.setSpecialKey(map.get("specialKey").toString());
return new UsernamePasswordAuthenticationToken(user,
authentication.getCredentials(), authentication.getAuthorities());
}
});
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("key");
converter.setAccessTokenConverter(customAccessTokenConverter);
converter.setAccessTokenConverter(tokenConverter);
return converter;
}
#Bean
#Primary
public DefaultTokenServices tokenServices() {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter()));
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setAccessTokenValiditySeconds(accessTokenValiditySeconds);
defaultTokenServices.setRefreshTokenValiditySeconds(refreshTokenValiditySeconds);
defaultTokenServices.setReuseRefreshToken(false);
defaultTokenServices.setTokenEnhancer(tokenEnhancerChain);
return defaultTokenServices;
}
}
Here is Custom Token Enhance:
package com.cs.je.auth.config.jwt;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Component;
import com.cs.je.auth.enums.Role;
import com.cs.je.auth.model.User;
import com.cs.je.auth.rest.api.call.CustomRestTemplate;
import com.cs.je.auth.service.UserService;
import com.cs.je.auth.utils.EncTokenUtils;
import com.cs.je.auth.utils.UserUtils;
/**
* #author sawai
*
*/
#Component
public class CustomTokenEnhancer implements TokenEnhancer {
#Autowired
private UserService userService;
#Autowired
private CustomRestTemplate customRestTemplate;
#Value("${microservice.company.protocol}")
private String protocol;
#Value("${microservice.company.port}")
private String port;
#Value("${microservice.company.ip}")
private String ipAddress;
#Value("${microservice.company.user.api}")
private String userCreateUrl;
#Autowired
private TokenStore tokenStore;
#Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
Map<String, Object> additionalInfo = new HashMap<>();
if (authentication != null) {
User user = (User)authentication.getPrincipal();
additionalInfo.put("email", user.getEmail());
additionalInfo.put("tenantId", user.getTenantId());
additionalInfo.put("id", user.getId());
if (user.isSystemGeneratedPassword()) {
additionalInfo.put("systemGeneratedPassword", true);
}
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
System.out.println(accessToken.getRefreshToken());
System.out.println(accessToken.getRefreshToken().getValue());
System.out.println(accessToken.getTokenType());
/*if (user.getRole().equals(Role.ROLE_ADMIN) || user.getRole().equals(Role.ROLE_USER)) {
String token = accessToken.toString();
try {
System.out.println("before call");
//ResponseEntity<Object> responseEntity = customRestTemplate.exchange(protocol + "://" + ipAddress + ":" + port + userCreateUrl + "/" + user.getId() + "/last-loggedOn", token, EncTokenUtils.getEncToken(user.getEmail()), HttpMethod.PUT, null);
System.out.println("successfull");
} catch (Exception e) {
e.printStackTrace();
}
}*/
System.out.println("1111111111");
}
return accessToken;
}
}
Security Config
package com.cs.je.auth.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.cs.je.auth.constant.Constants;
import com.cs.je.auth.enums.Role;
import com.cs.je.auth.model.User;
import com.cs.je.auth.repository.UserRepository;
import com.cs.je.auth.service.UserService;
/**
* #author sawai
*
*/
#Configuration
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserService userService;
#Autowired
private UserRepository userRepository;
/*#Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers("/").permitAll()
.antMatchers(HttpMethod.POST ,"/user/**").hasAnyAuthority("ROLE_SUPER_USER", "ROLE_ADMIN")
.anyRequest().authenticated();
httpSecurity.csrf().disable();
httpSecurity.headers().frameOptions().disable();
httpSecurity.requestCache().requestCache(new NullRequestCache());
httpSecurity.httpBasic();
//httpSecurity.addFilterBefore(CORSFilter, ChannelProcessingFilter.class);
}*/
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
auth.userDetailsService(userService).passwordEncoder(passwordEncoder);
if (userRepository.count() < 1) {
User user = new User();
user.setEmail("jeAdmin#email.com");
user.setPassword("jeAdminUser");
user.setTenantId(Constants.JE_TENANT_ID);
user.setRole(Role.ROLE_SUPER_USER);
user.setValidate(true);
userService.create(user, null);
}
}
#Override
public void configure(WebSecurity webSecurity) {
webSecurity.ignoring().antMatchers("/api/candidate/**");
webSecurity.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
webSecurity.ignoring().antMatchers("/api/company/**");
webSecurity.ignoring().antMatchers("/api/forgotPassword/**");
//webSecurity.ignoring().antMatchers(HttpMethod.POST, "/oauth/**");
}
}
ResourceConfig.java
package com.cs.je.auth.config.jwt;
/**
* #author sawai
*
*/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
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.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.access.channel.ChannelProcessingFilter;
import org.springframework.security.web.savedrequest.NullRequestCache;
import com.cs.je.auth.filter.CORSFilter;
#Configuration
#EnableResourceServer
public class ResourceConfig extends ResourceServerConfigurerAdapter {
#Value("${security.oauth2.resource.id}")
private String resourceId;
// The DefaultTokenServices bean provided at the AuthorizationConfig
#Autowired
private DefaultTokenServices tokenServices;
// The TokenStore bean provided at the AuthorizationConfig
#Autowired
private TokenStore tokenStore;
#Autowired
private CORSFilter corsFilter;
// To allow the rResourceServerConfigurerAdapter to understand the token,
// it must share the same characteristics with AuthorizationServerConfigurerAdapter.
// So, we must wire it up the beans in the ResourceServerSecurityConfigurer.
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources
.resourceId(resourceId)
.tokenServices(tokenServices)
.tokenStore(tokenStore);
}
public void configure(WebSecurity webSecurity) {
webSecurity.ignoring().antMatchers("/api/candidate/**");
// webSecurity.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
// webSecurity.ignoring().antMatchers(HttpMethod.POST, "/oauth/**");
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/").permitAll().and().authorizeRequests().antMatchers("/console/**")
.permitAll().and().authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll().and()
// when restricting access to 'Roles' you must remove the "ROLE_" part role
// for "ROLE_USER" use only "USER"
//.antMatchers("/api/hello").access("hasAnyRole('USER')")
//.antMatchers("/api/admin").hasRole("ADMIN")
.authorizeRequests().antMatchers(HttpMethod.POST ,"/api/user/**").hasAnyAuthority("ROLE_SUPER_USER", "ROLE_ADMIN")
// restricting all access to /api/** to authenticated users
//.antMatchers("/**")
//.antMatchers("/api/**").authenticated();
.anyRequest().authenticated();
http.csrf().disable();
http.headers().frameOptions().disable();
http.requestCache().requestCache(new NullRequestCache());
http.httpBasic();
http.addFilterBefore(corsFilter, ChannelProcessingFilter.class);
}
}
All above config is on auth service side.
Now when user request for jwt token on auth, then we want to get access-token value on service layer, so i can call company service by secure url calling.
Please guide me how can we get access-token value when user request for jwt token. If you look in CustomTokenEnhancer then we tried to print access-token there by using following statements:
**System.out.println(accessToken.getRefreshToken());
System.out.println(accessToken.getRefreshToken().getValue());
System.out.println(accessToken.getTokenType());**
But values are similar to: 642e0cf2-9214-42d8-ae85-29e5cdfccef1
But we want actual token here.
Please guide me.
You can use that method
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String TOKEN_SEPERATOR = " ";
public static String getAccessToken(){
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes instanceof ServletRequestAttributes) {
HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
return Arrays.asList(request.getHeader(AUTHORIZATION_HEADER).split(TOKEN_SEPERATOR)).get(1);
}
return null;
}

How to get Neo4jTemplate in SDN4

I am using Spring Data Neo4j 4(SDN4) from the example project SDN4-northwind(https://github.com/amorgner/sdn4-northwind),when I try to get the Neo4jTemplate bean,I get the error message like this.
Does anyone know how to get the Neo4jTemplate bean from SDN4?
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.data.neo4j.template.Neo4jTemplate] is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:371)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:968)
at org.neo4j.example.northwind.Run.main(Run.java:34)
Here is the Configuration file
package org.neo4j.example.northwind;
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.server.Neo4jServer;
import org.springframework.data.neo4j.server.RemoteServer;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableNeo4jRepositories("org.neo4j.example.northwind.repository")
#EnableTransactionManagement
public class AppContext extends Neo4jConfiguration {
public static final String NEO4J_HOST = "http://localhost:";
public static final int NEO4J_PORT = 7474;
#Override
public SessionFactory getSessionFactory() {
System.setProperty("username", "neo4j");
System.setProperty("password", System.getProperty("password","osp"));
return new SessionFactory("org.neo4j.example.northwind.model");
}
#Bean
#Override
public Neo4jServer neo4jServer() {
return new RemoteServer(NEO4J_HOST + NEO4J_PORT);
}
#Bean
#Override
//#Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Session getSession() throws Exception {
return super.getSession();
}
}
Assdd
#Bean
public Neo4jOperations getNeo4jTemplate() throws Exception {
return new Neo4jTemplate(getSession());
}
to AppContext and then #Autowired Neo4jOperations neo4jTemplate;

Spring security 3.2.5 and token based authentication

I'm trying to secure a REST API using Spring security 3.2.5 and a java based configuration.
Actually i've found many examples developed with an "old" xml approach, but nothing with a complete java configuration.
Where can i find some useful tutorial?
The project creates a REST API and some jsp usesd to allow the admin to populate an underlyin DB (Hibernate is used as ORM):
Here is my Config class:
package com.idk.fantappapaback.spring;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.tomcat.dbcp.dbcp.BasicDataSource; import org.hibernate.SessionFactory; 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.Import; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; import org.springframework.orm.hibernate4.HibernateTransactionManager; import org.springframework.orm.hibernate4.LocalSessionFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.multipart.support.StandardServletMultipartResolver; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.JstlView; import org.springframework.web.servlet.view.UrlBasedViewResolver;
import com.google.common.base.Preconditions; import com.idk.fantappapaback.spring.security.SecurityConfig;
#Configuration #EnableWebMvc #EnableTransactionManagement #PropertySource({ "classpath:persistence-mysql.properties" }) #ComponentScan({ "com.idk.fantappapaback.persistence","com.idk.fantappapaback.rest","com.idk.fantappapaback.spring.controllers","com.idk.fantappapaback.spring.security" }) #Import({ SecurityConfig.class }) public class BackEndConfig extends WebMvcConfigurerAdapter{
#Autowired
private Environment env;
public BackEndConfig() {
super();
}
//l'application context estrae il session factory da questo bean
#Bean
public LocalSessionFactoryBean sessionFactory() {
final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(restDataSource());
sessionFactory.setPackagesToScan(new String[] { "com.idk.fantappapaback.persistence.model" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public DataSource restDataSource() {
final BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
return dataSource;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(final SessionFactory sessionFactory) {
final HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);
return txManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
final Properties hibernateProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
//***Proprieta per l'output delle query in sql che qui disabilito
// hibernateProperties.setProperty("hibernate.show_sql", "true");
// hibernateProperties.setProperty("hibernate.format_sql", "true");
// hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
return hibernateProperties;
}
#Bean
public UrlBasedViewResolver setupViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public StandardServletMultipartResolver multipartResolver(){
return new StandardServletMultipartResolver();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/"); // registry.addResourceHandler("/css/**") // .addResourceLocations("/css/"); // registry.addResourceHandler("/img/**") // .addResourceLocations("/img/");
registry.addResourceHandler("/js/**")
.addResourceLocations("/js/");
}
}
this is my very basic Security config that i use to have a form log in on the jsp views:
package com.idk.fantappapaback.spring.security;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; 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({ SecurityConfig.class }) nella BackEndConfig #Configuration #EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter{ #Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("masquenada").password("123456").roles("USER"); // auth.inMemoryAuthentication().withUser("masquenada").password("123456").roles("ADMIN"); auth.inMemoryAuthentication().withUser("masquenada").password("123456").roles("SUPERADMIN"); }
#Override protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() // .antMatchers("/players/**").access("hasRole('ROLE_USER')") .antMatchers("/createSeason/**").access("hasRole('ROLE_SUPERADMIN')") .and().formLogin().permitAll() .and().httpBasic();
} }
here is my SecurityWebApplicationInitializer :
package com.idk.fantappapaback.spring.security;
import org.springframework.security.web.context.*;
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
}
The main question is : how to add the token based autorization?
I've added Spring oAuth 2 and Spring integration to my pom but i need some hint about introducing spring oAuth keeping the form login.
You need to "configure" your SecurityWebApplicatioInitializer.
http://spring.io/blog/2013/07/03/spring-security-java-config-preview-web-security/

Resources