Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
package com.phynart.cloud.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(AuthorizationServerConfig.class);
static final String CLIEN_ID = "devglan-client";
static final String CLIENT_SECRET = "devglan-secret";
static final String GRANT_TYPE_PASSWORD = "password";
static final String AUTHORIZATION_CODE = "authorization_code";
static final String REFRESH_TOKEN = "refresh_token";
static final String IMPLICIT = "implicit";
static final String SCOPE_READ = "read";
static final String SCOPE_WRITE = "write";
static final String TRUST = "trust";
static final int ACCESS_TOKEN_VALIDITY_SECONDS = 1*60*60;
static final int FREFRESH_TOKEN_VALIDITY_SECONDS = 6*60*60;
#Autowired
private AuthenticationManager authenticationManager;
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
logger.debug("in access token converter");
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("as466gf");
return converter;
}
#Bean
public TokenStore tokenStore() {
logger.debug("tokenStore");
return new JwtTokenStore(accessTokenConverter());
}
#Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
logger.debug("ClientDetailsServiceConfigurer");
configurer
.inMemory()
.withClient(CLIEN_ID)
.secret(CLIENT_SECRET)
.authorizedGrantTypes(GRANT_TYPE_PASSWORD, AUTHORIZATION_CODE, REFRESH_TOKEN, IMPLICIT )
.scopes(SCOPE_READ, SCOPE_WRITE, TRUST)
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS)
.refreshTokenValiditySeconds(FREFRESH_TOKEN_VALIDITY_SECONDS);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
logger.debug("AuthorizationServerEndpointsConfigurer");
endpoints.tokenStore(tokenStore())
.authenticationManager(authenticationManager)
.accessTokenConverter(accessTokenConverter());
}
}
package com.phynart.cloud.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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.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 ResourceServerConfig extends ResourceServerConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(ResourceServerConfig.class);
private static final String RESOURCE_ID = "resource_id";
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
logger.debug("ResourceServerSecurityConfigurer");
resources.resourceId(RESOURCE_ID).stateless(false);
}
#Override
public void configure(HttpSecurity http) throws Exception {
logger.debug("HttpSecurity resource");
http.
anonymous().disable()
.authorizeRequests()
.antMatchers("/users/**").access("hasRole('ADMIN')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
package com.phynart.cloud.config;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
#Resource(name = "UserService")
private UserDetailsService userDetailsService;
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
logger.debug("inside authentication manager");
return super.authenticationManagerBean();
}
#Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
logger.debug("password encoder");
auth.userDetailsService(userDetailsService)
.passwordEncoder(encoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
logger.debug("HttpSecurity");
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/api-docs/**").permitAll();
}
#Bean
public BCryptPasswordEncoder encoder(){
logger.debug("inside password encoder");
// return new BCryptPasswordEncoder();
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
logger.debug("bCryptPasswordEncoder -" + bCryptPasswordEncoder);
return bCryptPasswordEncoder;
}
#Bean
public FilterRegistrationBean corsFilter() {
logger.debug("corsFilter");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
package com.phynart.cloud.controller;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.phynart.cloud.model.User;
import com.phynart.cloud.service.UserService;
import java.security.Principal;
#RestController
#RequestMapping("/users")
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
#Autowired
private UserService userService;
#RequestMapping(value="/user", method = RequestMethod.GET)
public Iterable<User> listUser(){
logger.debug("inside controller");
return userService.findAll();
}
#RequestMapping(value = "/user", method = RequestMethod.POST)
public User create(#RequestBody User user){
return userService.save(user);
}
#RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
public String delete(#PathVariable(value = "id") Long id){
userService.delete(id);
return "success";
}
}
package com.phynart.cloud.service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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.phynart.cloud.dao.UserDao;
import com.phynart.cloud.model.User;
#Service(value = "UserService")
public class UserServiceImpl implements UserDetailsService {
private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
#Autowired
private UserDao userDao;
public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException {
logger.debug("loadUserByUsername");
User user = userDao.findByUsername(userId);
if(user == null){
throw new UsernameNotFoundException("Invalid username or password.");
}
logger.debug("before returning user");
logger.debug("username -" + user.getUsername());
logger.debug("password -" + user.getPassword());
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), getAuthority());
}
private List getAuthority() {
return Arrays.asList(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
public List findAll() {
logger.debug("findAll");
List list = new ArrayList<>();
userDao.findAll().iterator().forEachRemaining(list::add);
return list;
}
}
package com.phynart.cloud.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import com.phynart.cloud.dao.UserDao;
import com.phynart.cloud.model.User;
#Service
public class UserService {
#Autowired
UserDao userDao;
public Iterable<User> findAll() {
return userDao.findAll();
}
public User save(User user) {
return userDao.save(user);
}
public void delete(Long id) {
// TODO Auto-generated method stub
}
}
I am getting bad credentials "Handling error: InvalidGrantException, Bad credentials", even If i comment the BCryptPasswordEncoder portion and use plain password in database still am facing issue, could anyone please help me out? i am not finding any solution and I am new to oauth implementation,
i have added the AuthorizartionServerConfig, ResourceServerConfig, SecurityConfig, UserServiceImpl, UserController - I have pulled the code from site - https://www.devglan.com/spring-security/spring-boot-oauth2-jwt-example
basic auth from postman
Body in postman for user credetial
database credential of the user
data entered from the site i coded - https://www.devglan.com/spring-security/spring-boot-oauth2-jwt-example
I think you have a typo in parameters for user credentials.
body in postman for user credentials
passowrd
instead of
password
Related
I have code work ok with Spring 2.x . Source code of Spring 2.x
File CustomFilter.java
package com.example.security;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import org.springframework.web.filter.GenericFilterBean;
import java.io.IOException;
public class CustomFilter extends GenericFilterBean {
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
}
File AuthEntryPointJwt.java
package com.example.security.jwt;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
#Component
public class AuthEntryPointJwt implements AuthenticationEntryPoint {
private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class);
#Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
logger.error("Unauthorized error: {}", authException.getMessage());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
final Map<String, Object> body = new HashMap<>();
body.put("status", HttpServletResponse.SC_UNAUTHORIZED);
body.put("error", "Unauthorized");
body.put("message", authException.getMessage());
body.put("path", request.getServletPath());
final ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(response.getOutputStream(), body);
}
}
File AuthTokenFilter.java
package com.example.security.jwt;
import com.example.security.services.UserDetailsServiceImpl;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
public class AuthTokenFilter extends OncePerRequestFilter {
private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class);
#Autowired
private JwtUtils jwtUtils;
#Autowired
private UserDetailsServiceImpl userDetailsService;
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
String jwt = parseJwt(request);
if (jwt != null && jwtUtils.validateJwtToken(jwt)) {
String username = jwtUtils.getUserNameFromJwtToken(jwt);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (Exception e) {
logger.error("Cannot set user authentication: {}", e);
}
filterChain.doFilter(request, response);
}
private String parseJwt(HttpServletRequest request) {
String headerAuth = request.getHeader("Authorization");
if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {
return headerAuth.substring(7);
}
return null;
}
}
File JwtUtils.java
package com.example.security.jwt;
import com.example.security.services.UserDetailsImpl;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import java.util.Date;
#Component
public class JwtUtils {
private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
#Value("${app.jwtSecret}")
private String jwtSecret;
#Value("${app.jwtExpirationMs}")
private int jwtExpirationMs;
public String generateJwtToken(Authentication authentication) {
UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
return Jwts.builder().setSubject((userPrincipal.getUsername())).setIssuedAt(new Date()).setExpiration(new Date((new Date()).getTime() + jwtExpirationMs)).signWith(SignatureAlgorithm.HS512, jwtSecret).compact();
}
public String getUserNameFromJwtToken(String token) {
return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateJwtToken(String authToken) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
return true;
} catch (SignatureException e) {
logger.error("Invalid JWT signature: {}", e.getMessage());
} catch (MalformedJwtException e) {
logger.error("Invalid JWT token: {}", e.getMessage());
} catch (ExpiredJwtException e) {
logger.error("JWT token is expired: {}", e.getMessage());
} catch (UnsupportedJwtException e) {
logger.error("JWT token is unsupported: {}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("JWT claims string is empty: {}", e.getMessage());
}
return false;
}
}
File UserDetailsImpl.java
package com.example.security.services;
import com.example.models.User;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class UserDetailsImpl implements UserDetails {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
private String email;
#JsonIgnore
private String password;
private Collection<? extends GrantedAuthority> authorities;
public UserDetailsImpl(Long id, String username, String email, String password, Collection<? extends GrantedAuthority> authorities) {
this.id = id;
this.username = username;
this.email = email;
this.password = password;
this.authorities = authorities;
}
public static UserDetailsImpl build(User user) {
List<GrantedAuthority> authorities = user.getRoles().stream().map(role -> new SimpleGrantedAuthority(role.getName().name())).collect(Collectors.toList());
return new UserDetailsImpl(user.getId(), user.getUsername(), user.getEmail(), user.getPassword(), authorities);
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
public Long getId() {
return id;
}
public String getEmail() {
return email;
}
#Override
public String getPassword() {
return password;
}
#Override
public String getUsername() {
return username;
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
#Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
UserDetailsImpl user = (UserDetailsImpl) o;
return Objects.equals(id, user.id);
}
}
File UserDetailsServiceImpl.java
package com.example.security.services;
import com.example.models.User;
import com.example.repository.UserRepository;
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 org.springframework.transaction.annotation.Transactional;
// Original.
#Service
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
UserRepository userRepository;
#Override
#Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + username));
return UserDetailsImpl.build(user);
}
}
file WebSecurityConfig.java
package com.example.security;
import com.example.security.jwt.AuthEntryPointJwt;
import com.example.security.jwt.AuthTokenFilter;
import com.example.security.services.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(
// securedEnabled = true,
// jsr250Enabled = true,
prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsServiceImpl userDetailsService;
#Autowired
private AuthEntryPointJwt unauthorizedHandler;
#Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
#Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
// Nếu id gửi lên != id của tenant của user đó trong database, thì không cho đi tiếp.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
//.authorizeRequests().antMatchers("/api/auth/**", "/swagger-ui/**").permitAll()
.authorizeRequests().antMatchers("/api/auth/**", "/swagger-ui/**", "/v3/api-docs/**").permitAll()
.antMatchers("/app/**").permitAll()
.antMatchers("/api/test/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
//;
// .addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class); // VyDN 2022_07_22 // https://www.baeldung.com/spring-security-custom-filter
}
}
// Add filter before, after: https://stackoverflow.com/a/59000469
Now, I am using Java / JDK 19, Spring Boot 3.0.0 . After upgrade to Spring Boot 3.0.0 , it causes syntax error.
How to fix error of WebSecurityConfigurerAdapter when upgrade to Spring Boot 3.0.0? Specific to my configuration. Please guide me rewrite file WebSecurityConfig.java
On Spring Boot 3 WebSecurityConfigurerAdapter is deprecated. So in your case the WebSecurityConfig class should not extend any class and most be implemented by itself. You can implement the userDetailsService by yourself as a #Bean and also set the AuthenticationManager, not just return the super.
I had the same problem and my solution was just to add #SuppressWarnings("deprecation")
before the #Configuration annotation in the class.
replace .antMatchers -> .requestMatchers (it will work in spring 3.0.0 )
WebSecurityConfigurerAdapter is deprecated and should use component-based security configuration. You'll have to create a SecurityFilterChain bean for HTTPSecurity and shouldn't extend WebSecurityConfigurerAdapter as other answer suggested. Please refer https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter for more details.
I have Security class as following:
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
#RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/api/v1/**").permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
and I have also Login Rest API as following:
import com.company.blog.data.dto.request.LoginRequestDto;
import com.company.blog.enums.ErrorCase;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/api/auth")
#RequiredArgsConstructor
public class AuthController {
private final AuthenticationManager authenticationManager;
#PostMapping("/signin")
public ResponseEntity<String> signIn(#RequestBody LoginRequestDto loginRequestDto) {
Authentication authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequestDto.getUsernameOrEmail(), loginRequestDto.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authenticate);
return new ResponseEntity<>(ErrorCase.SUCCESS_LOGIN.getMessage(), HttpStatus.OK);
}
}
as you see , I didn't any antMatchers path configuration for Login Rest API. In that case it has to give me the following error in the POSTMAN.
{
"timestamp":"",
"status":401,
"error":Unautorized",
"message":"Unautorized",
"path":"/api/auth/signin"
}
but login operation successfully processed. I also tried to runing debug mode, everything work fine. I couldn't understand what happened.
I am also sharing some of my security related classes below.
import com.company.blog.data.entity.Role;
import com.company.blog.data.entity.User;
import com.company.blog.data.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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 java.util.Set;
import java.util.stream.Collectors;
import static com.company.blog.enums.ErrorCase.USER_NOT_FOUND;
#Service
#RequiredArgsConstructor
public class CustomUserDetailService implements UserDetailsService {
private final UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String usernameOrEmail) throws UsernameNotFoundException {
User user = userRepository.findByUsernameOrEmail(usernameOrEmail, usernameOrEmail).orElseThrow(() -> new UsernameNotFoundException(USER_NOT_FOUND.getMessage()));
return new UserDetail(user.getUsername(), user.getPassword(), mapToGrantedAuthority(user.getRoles()));
}
private Set<GrantedAuthority> mapToGrantedAuthority(Set<Role> roles) {
return roles.stream().map(role -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toSet());
}
}
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import java.util.Collection;
public class UserDetail extends User {
public UserDetail(String username, String password, Collection<? extends GrantedAuthority> authorities) {
super(username, password, authorities);
}
}
Hello I'm totally new to Spring Framework. I wanted to #Autowired the JdbcTemplate inside MasterDaoImpl but it returns NullPointerException.
I believe #Autowired objects are created after constructor.
It returns an address if i tried to print in one of the Configuration classes. I don't know what to do ? What should i do in order to make the
JdbcTemplate work inside of MasterDaoImpl.
Can anyone explain why this is happening ? Any Suggestions with the Configurations are appreciated.
AppConfig.java
package com.upeg.requisition.config;
import org.apache.log4j.Logger;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan("com.upeg.requisition")
public class AppConfig implements WebMvcConfigurer {
private static final Logger logger = Logger.getLogger(AppConfig.class);
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer tilesConfigurer = new TilesConfigurer();
tilesConfigurer.setDefinitions(new String[] { "/WEB-INF/tiles.xml", "/WEB-INF/loginTiles.xml" });
tilesConfigurer.setCheckRefresh(true);
return tilesConfigurer;
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
// registry.jsp("/WEB-INF/pages/", ".jsp");
TilesViewResolver tilesViewResolver = new TilesViewResolver();
registry.viewResolver(tilesViewResolver);
}
#Bean("messageSource")
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("languages/messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
#Bean
public LocaleResolver localeResolver() {
return new CookieLocaleResolver();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
registry.addInterceptor(localeChangeInterceptor);
}
}
AppInitialiser.java
package com.upeg.requisition.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SecurityConfig.class,AppConfig.class,DatabaseConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
DatabaseConfig.java
package com.upeg.requisition.config;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#PropertySource(value = { "classpath:application.properties" })
#EnableTransactionManagement
#ComponentScan("com.upeg.requisition")
public class DatabaseConfig {
private static final Logger logger = Logger.getLogger(DatabaseConfig.class);
#Autowired
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getRequiredProperty("jdbc.url"));
dataSource.setUsername(env.getRequiredProperty("jdbc.username"));
dataSource.setPassword(env.getRequiredProperty("jdbc.password"));
return dataSource;
}
#Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource());
jdbcTemplate.setResultsMapCaseInsensitive(true);
return jdbcTemplate;
}
}
SecurityConfig.java
package com.upeg.requisition.config;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#Configuration
#EnableWebSecurity
#ComponentScan("com.upeg.requisition")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CustomSuccesHandler customSuccesHandler;
private static final Logger logger = Logger.getLogger(SecurityConfig.class);
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**", "/css/**", "/javascript/**", "/images/**", "/fonts/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/login").permitAll().antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/**").hasRole("USER").anyRequest().authenticated().and().formLogin().loginPage("/login")
.usernameParameter("username").passwordParameter("password").successHandler(customSuccesHandler).and()
.httpBasic().and().logout().invalidateHttpSession(true).clearAuthentication(true)
.logoutSuccessUrl("/login").permitAll().and().csrf().disable();
http.sessionManagement().maximumSessions(1);
http.exceptionHandling().accessDeniedPage("/denied");
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user#user.com").password("{noop}Password1234!").roles("USER").and()
.withUser("approver#approver.com").password("{noop}Password1234!").roles("ADMIN");
}
}
MasterTableDao.java
public interface MasterTableDao {
List<MasterCategory> getCategory();
}
MasterDaoImpl.java
package com.upeg.requisition.daoimpl;
import java.util.List;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.upeg.requisition.config.AppConfig;
import com.upeg.requisition.config.CustomRowMapper;
import com.upeg.requisition.dao.MasterTableDao;
import com.upeg.requisition.model.MasterCategory;
#Repository
public class MasterDaoImpl implements MasterTableDao {
private static final Logger logger = Logger.getLogger(MasterDaoImpl.class);
#Autowired
JdbcTemplate jdbcTemplate;
#Override
public List<MasterCategory> getCategory() {
return jdbcTemplate.query("select * from category",new CustomRowMapper());
}
}
```[enter image description here][1]
[1]: https://i.stack.imgur.com/xTSc4.png
#Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(datasource);
jdbcTemplate.setResultsMapCaseInsensitive(true);
return jdbcTemplate;
}
jdbcTemplate.setDataSource(datasource); can be more appropriate but that's not the answer so you can put DatabaseConfig to AppIntializer
return new Class[]{SecurityConfig.class,AppConfig.class, DatabaseConfig.class};
I guess ComponentScan didn't work.
I just made these changes and it worked just gave my Bean a name and worked :)
#Bean("dataSource")
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl(" jdbc:postgresql://localhost:5432/test");
dataSource.setUsername("postgres");
dataSource.setPassword("sillicon");
return dataSource;
}
#Bean("jdbcTemplate")
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
i'm building a Java SpringBoot(Back-End),Vuejs(front)aplication , and im on this part of seting the web security application.
On my User Class the constructor might be like this :
package com.miniAmazon;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.security.core.GrantedAuthority;
import javax.persistence.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO,generator = "native")
#GenericGenerator(name="native",strategy="native")
private Long id;
#OneToMany(mappedBy = "users",fetch= FetchType.EAGER)
Set<Product> productsSet= new HashSet<>();
#OneToMany(mappedBy="users", fetch=FetchType.EAGER)
Set<Purchase> purchaseSet=new HashSet<>();
private String userRole;
private String userName;
private String userEmail;
private String userPassword;
public User(){}
public User( String userEmail,String userName,String userPassword,String userRole){
this.userName=userName;
this.userEmail=userEmail;
this.userPassword=userPassword;
this.userRole=userRole;
}
public void addPurchase(Purchase purchase){ purchaseSet.add(purchase);}
public Set<Purchase>getUserPurchaseSet(){
return purchaseSet;
}
////////////////////////////////////////////setter/////////////////////////////////////////////
///////////////////////////////////////////getters////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
#Override
xxxxx
}
}
user repository like this:
package com.miniAmazon;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
#RepositoryRestResource
public interface UserRepository extends JpaRepository<User,String> {
User findByuserName (String usertName);
}
and the web security application code was settled in this way:
package com.miniAmazon;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.GlobalAuthenticationConfigurerAdapter;
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.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Arrays;
import java.util.Date;
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Bean
public PasswordEncoder passwordEncoder(){
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
#Bean
public CommandLineRunner initData(ProductRepository productRepository, UserRepository userRepository, PurchaseRepository purchaseRepository){
return(args)->{
User user1=new User("lolo#gmail.com","lolo gomex",passwordEncoder().encode("24"),"buyer");
User user2=new User("jhony#gmail.com","Jack Ripper",passwordEncoder().encode("mole"),"buyer");
User user3=new User("gothic#gmail.com","demo gago",passwordEncoder().encode("adu"),"seller");
User user4=new User("grau#gmail.com","grau gomex",passwordEncoder().encode("24"),"seller");
User user5=new User("goiy#gmail.com","divan Ripper",passwordEncoder().encode("mole"),"buyer");
User user6=new User("gatti#gmail.com","guti gago",passwordEncoder().encode("adu"),"admin");
userRepository.save(user1);
userRepository.save(user2);
userRepository.save(user3);
userRepository.save(user4);
userRepository.save(user5);
userRepository.save(user6);
};
}
}
#Configuration
#EnableWebSecurity
class WebSecurityConfiguration extends GlobalAuthenticationConfigurerAdapter {
#Autowired
UserRepository userRepository;
#Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(inputName-> {
User user =userRepository.findByuserName(inputName);
if (user != null) {
return new User(user.getUserName(), user.getUserPassword(),
AuthorityUtils.createAuthorityList("USER"));--------------------ERROR
} else {
throw new UsernameNotFoundException("Unknown user: " + inputName);
}
});
}
}
#Configuration
#EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
// http.cors();///de heroku tambien
http.authorizeRequests()
.antMatchers("/mini/all_products").permitAll()
.antMatchers("mini/all_products/user_dashboard/purchase/{id}").permitAll()
.antMatchers("/mini/all_product/registering").permitAll()
.antMatchers("/h2-console/**").permitAll()
.antMatchers("/rest/**").hasAuthority("ADMIN")
.antMatchers("/**").hasAuthority("USER")
.anyRequest().fullyAuthenticated();
/////Autorizaciones y permisos para los distintos niveles de seguridad que tendria el usuario segun su casificacion
http.formLogin()
.usernameParameter("name")
.passwordParameter("password")
.loginPage("/api/login");
//
http.logout().logoutUrl("/api/logout");
http.csrf().disable();
http.exceptionHandling().authenticationEntryPoint((req, res, exc) -> res.sendError(HttpServletResponse.SC_UNAUTHORIZED));
http.formLogin().successHandler((req, res, auth) -> clearAuthenticationAttributes(req));
http.formLogin().failureHandler((req, res, exc) -> res.sendError(HttpServletResponse.SC_UNAUTHORIZED));
http.logout().logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler());
// http.headers().frameOptions().disable();
http.headers().frameOptions().sameOrigin();
}
private void clearAuthenticationAttributes(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
}
}
}
but keeps throwing me an error in the first WebSecurityConfiguration in the cosntructor of the new User, saying once i hover it
Cannot resolve constructor 'User(java.lang.String, java.lang.String, java.util.List<org.springframework.security.core.GrantedAuthority>)'
Any idea about why this is happening .Really sorry for having exposed all this code!!.
And thanks in advance!!!
I have checked your code. In your WebSecurityConfig class
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(inputName-> {
User user =userRepository.findByuserName(inputName);
if (user != null) {
return new User(user.getUserName(), user.getUserPassword(),
AuthorityUtils.createAuthorityList("USER"));--------------------ERROR
}
});
}
You are returning user object like this :
return new User(user.getUserName(),
user.getUserPassword(),
AuthorityUtils.createAuthorityList("USER"));
which is wrong.
Because you have created constructor with different argument:
public User(String userEmail,
String userName,
String userPassword,
String userRole);
So pass arguments correctly. It will work.
You can also return like this:
return new User(null, user.getUserName(), user.getUserPassword(),
AuthorityUtils.createAuthorityList("USER"));
You should return org.springframework.security.core.userdetails.User instead of your com.miniAmazon.User:
if (user != null) {
return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getUserPassword(),
AuthorityUtils.createAuthorityList("USER"));
} else {
throw new UsernameNotFoundException("Unknown user: " + inputName);
}
since the loadUserByUsername method from UserDetailsService return a org.springframework.security.core.userdetails.UserDetails instance and org.springframework.security.core.userdetails.User implements org.springframework.security.core.userdetails.UserDetails.
public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
I wrote a DAL following this guide. In particular this is my DALConfig.java configuration file
package my.pack;
import java.util.Properties;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.hibernate.ejb.HibernatePersistence;
import org.hibernate.jpa.HibernatePersistenceProvider;
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.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.repository.Repository;
import org.springframework.orm.hibernate4.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#ComponentScan(basePackages = { "my.pack" })
#PropertySource("classpath:dbconnection.properties")
#EnableJpaRepositories("my.pack.repository")
#EnableTransactionManagement
public class DALConfig {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver_class";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_POOL_INITIAL_SIZE = "pool.initialsize";
private static final String PROPERTY_NAME_POOL_MAX_IDLE = "pool.maxidle";
private static final String PROPERTY_NAME_DAL_CLASSES_PACKAGE = "entities.packages_to_scan";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.showsql";
private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
#Resource
private Environment environment;
#Bean
public DataSource dataSource()
{
Properties props = new Properties();
props.put("driverClassName", environment.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
props.put("url", environment.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
props.put("username", environment.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
props.put("password", environment.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
props.put("initialSize", environment.getRequiredProperty(PROPERTY_NAME_POOL_INITIAL_SIZE));
props.put("maxIdle", environment.getRequiredProperty(PROPERTY_NAME_POOL_MAX_IDLE));
BasicDataSource bds = null;
try {
bds = BasicDataSourceFactory.createDataSource(props);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bds;
}
#Bean
public PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor()
{
PersistenceExceptionTranslationPostProcessor b = new PersistenceExceptionTranslationPostProcessor();
return b;
}
#Bean
public HibernateExceptionTranslator hibernateExceptionTranslator(){
return new HibernateExceptionTranslator();
}
#Bean
public PlatformTransactionManager transactionManager() throws ClassNotFoundException {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws ClassNotFoundException {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPackagesToScan(environment.getRequiredProperty(PROPERTY_NAME_DAL_CLASSES_PACKAGE));
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
Properties jpaProterties = new Properties();
jpaProterties.put(PROPERTY_NAME_HIBERNATE_DIALECT, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
jpaProterties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
jpaProterties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
entityManagerFactoryBean.setJpaProperties(jpaProterties);
return entityManagerFactoryBean;
}
}
This is the Repository I wrote
package my.pack.repository;
import my.pack.entity.User;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface IUserRepository extends CrudRepository<User, String>{
}
Finally this is the test I run
package my.pack.tests;
import static org.junit.Assert.assertTrue;
import futureservice.UserService;
import my.pack.DALConfig;
import my.pack.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#ContextConfiguration(classes = { DALConfig.class})
#RunWith(SpringJUnit4ClassRunner.class)
public class DALTest {
#Autowired
UserService userService;
#Test
public void testGetUser() {
User user = null;
user = userService.findOne("mrossi");
assertTrue(null != user);
}
}
When I run the test I get the following exception stack and the test fails.
...
Caused by: org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'entityManager' threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.setMappingContext(Lorg/springframework/data/mapping/context/MappingContext;)V
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:108)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:62)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1489)
... 41 more
It seems like the JpaRepositoryFactoryBean misses the setMappingContext method but as you can see from the documentation the method is supported. I'm using the 1.5.1.RELEASE version of spring-data-jpa artifact.
What can be the issue?
Thank you