我正在尝试配置Spring Security,但我的自定义UserDetailsService存在一个问题。每当我尝试登录时,我都会被重定向到我的失败页面。这是服务的代码:
@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;
}
}
正如您在代码中看到的那样,一些记录器从未打印过,这有点奇怪......
这是我的用户模型,其存储库及其服务类:
@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);
}
}
我的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>
我的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>
最后,我之前运行的代码是为了添加测试用户:
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);
我做错了什么?
修改
由于未知原因,userService为null,因此未进行自动装配。我不确定哪个可能是问题所在。这项服务在控制器内部运行良好。
答案 0 :(得分:1)
将autowire="byType"
添加到userDetailsService bean的xlm定义
从类中删除服务注释,否则你将有两个实例。