Reputation: 4523
I'm trying to configure Spring Security but I have an extrange problem with my custom UserDetailsService. Everytime I try to login in I'm redirected to my failure page. This is the code of the service:
@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
private static final Logger logger = LoggerFactory.getLogger(CustomUserDetailsService.class);
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
logger.info("This is printed");
UserDetails userDetails = userService.findOne(username);
logger.info("This isn't printed");
if (userDetails == null) {
logger.info("This isn't printed");
throw new UsernameNotFoundException("No user found with username "
+ username);
}
return userDetails;
}
}
As you can see in the code, some of the loggers are never printed and that is a little weird...
This are my User model, its repository and its service classes:
@Entity
public class User implements UserDetails {
// more code
@Transactional(readOnly = true)
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
}
@Repository
@Transactional(readOnly = true)
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public List<User> findAll() {
return userRepository.findAll();
}
@Override
public User findOne(String username) {
return userRepository.findByUsername(username);
}
@Override
@Transactional
public User save(User user) {
return userRepository.save(user);
}
}
My web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- Spring Security filters -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- This is used to inject webroot property (used by persistence.xml) -->
<listener>
<listener-class>com.leakedbits.twicker.listener.WebAppPropertiesListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- The definition of the Root Spring Container shared by all Servlets
and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/security.xml
/WEB-INF/spring/root-context.xml
</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
My security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.1.xsd">
<http pattern="/resources" security="none" />
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/logout" access="permitAll" />
<intercept-url pattern="/denied" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/" access="permitAll" />
<intercept-url pattern="/user" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/init2" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')" />
<form-login login-page="/login" authentication-failure-url="/login/failure"
default-target-url="/" />
<access-denied-handler error-page="/denied" />
<logout invalidate-session="true" logout-success-url="/logout/success"
logout-url="/logout" />
</http>
<!-- This line must to be here because for some random reason the implementation
wasn't found without it -->
<beans:bean id="customUserDetailsService"
class="com.leakedbits.twicker.service.security.CustomUserDetailsService" />
<authentication-manager>
<authentication-provider user-service-ref="customUserDetailsService">
<password-encoder hash="sha" />
</authentication-provider>
</authentication-manager>
</beans:beans>
Finally, the code that I run previously to add a test user:
User user = new User();
user.setPassword("7c4a8d09ca3762af61e59520943dc26494f8941b"); // 123456
user.setUsername("davidmogar");
Set<GrantedAuthority> grantedAuthorities = new HashSet<GrantedAuthority>();
grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
user.setGrantedAuthorities(grantedAuthorities);
userService.save(user);
What I'm doing wrong?
EDIT
For an unknown reason, userService is null so is not being autowired. I'm not sure which could be the problem. This service is working well inside the controller.
Upvotes: 0
Views: 1116
Reputation: 120811
Add autowire="byType"
to the xlm definition of the userDetailsService bean
And remove the service annotation from the class, else you would have two instances of it.
Upvotes: 1