如何使用SpringSecurity3和Hibernate4将SpringSecurityXML配置hibernate转换为java配置
我刚刚学习了spring安全性,并希望使用JavaHibernate配置连接到数据库,但我发现很少有示例或教程。通过使用xml配置,我发现了更多。我在这里使用Spring4.0.2、SpringSecurity3.2.0和Hibernate4.3.2 我的问题是: 以下xml如何转换为java配置?如何使用SpringSecurity3和Hibernate4将SpringSecurityXML配置hibernate转换为java配置,java,hibernate,login,configuration,spring-security,Java,Hibernate,Login,Configuration,Spring Security,我刚刚学习了spring安全性,并希望使用JavaHibernate配置连接到数据库,但我发现很少有示例或教程。通过使用xml配置,我发现了更多。我在这里使用Spring4.0.2、SpringSecurity3.2.0和Hibernate4.3.2 我的问题是: 以下xml如何转换为java配置? <authentication-manager> <authentication-provider user-service-ref="customUserDetailsS
<authentication-manager>
<authentication-provider user-service-ref="customUserDetailsService">
<password-encoder hash="plaintext">
</password-encoder></authentication-provider>
</authentication-manager>
我将SecurityConfiguration.java放在Initializer.java上,如下所示
package com.whatever.svtest.init;
import javax.servlet.Filter;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class Initializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
// return null;
return new Class[] { SecurityConfiguration.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebAppConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected Filter[] getServletFilters() {
return new Filter[] { new DelegatingFilterProxy("springSecurityFilterChain") };
}
}
当我运行我的网络应用程序时,我得到了这个。(我把图片放在这里)
我还(在某处)读到了关于创建AuthenticationProvider.java的自定义实现的内容,但我不知道该把这段代码放在哪里
package com.whatever.svtest.init;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import com.whatever.svtest.dao.UserDao;
import com.whatever.svtest.model.User;
public class MyAuthProvider implements AuthenticationProvider {
@Autowired
private UserDao userDao;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String name = authentication.getName();
String password = authentication.getCredentials().toString();
User user = userDao.getByUsername(name);
authentication.setAuthenticated(user != null && password.equals(user.getPassword()));
return authentication;
}
@Override
public boolean supports(Class<?> authentication) {
return (MyAuthProvider.class.isAssignableFrom(authentication));
}
}
package com.whatever.svtest.init;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.security.authentication.AuthenticationProvider;
导入org.springframework.security.core.Authentication;
导入org.springframework.security.core.AuthenticationException;
导入com.whater.svtest.dao.UserDao;
导入com.whatever.svtest.model.User;
公共类MyAuthProvider实现AuthenticationProvider{
@自动连线
私有UserDao UserDao;
@凌驾
公共身份验证(身份验证)引发AuthenticationException{
String name=authentication.getName();
字符串密码=authentication.getCredentials().toString();
User=userDao.getByUsername(名称);
authentication.setAuthenticated(user!=null&&password.equals(user.getPassword());
返回认证;
}
@凌驾
公共布尔支持(类身份验证){
返回(MyAuthProvider.class.isAssignableFrom(身份验证));
}
}
配置不一致?
<authentication-manager>
<authentication-provider user-service-ref="customUserDetailsService">
<password-encoder hash="plaintext">
</password-encoder></authentication-provider>
</authentication-manager>
你发布的配置对我来说不太合理。具体如下:
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new UserServiceImpl()).passwordEncoder(NoOpPasswordEncoder.getInstance());
}
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(uds());
}
@Autowired
private UserDao userDao;
@Bean
public CustomUserDetailsService uds() {
return new CustomUserDetailsService(userDao);
}
解决方案
您似乎没有定义UserServiceImpl,但定义了CustomUserDetailsService(这可能是应该传入的参数。但是,为了使bean自动连接,您需要将其创建为bean。因此,您应该更改配置:
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(uds());
}
@Bean
public CustomUserDetailsService uds() {
return new CustomUserDetailsService();
}
通过将CustomUserDetailsService作为@Bean返回,您可以确保Spring正确地自动连接它
还有几点需要注意:
- 您不需要自定义AuthenticationProvider。这是因为您正在使用用户名/密码进行身份验证,UserDetails服务很好。如果您希望使用用户名/密码以外的内容进行身份验证,则可以创建自定义AuthenticationProvider
- 无需指定无操作密码编码器,因为这是默认值
@Service
@Transactional(readOnly = true)
public class CustomUserDetailsService implements UserDetailsService {
private UserDao userDao;
@Autowired
public CustomUserDetailsService(UserDao userDao) {
this.userDao = userDao;
}
然后,您的配置可以如下所示:
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new UserServiceImpl()).passwordEncoder(NoOpPasswordEncoder.getInstance());
}
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(uds());
}
@Autowired
private UserDao userDao;
@Bean
public CustomUserDetailsService uds() {
return new CustomUserDetailsService(userDao);
}
根据新错误进行更新
您还需要确保您的UserDao是作为Bean获取的。例如:
@Bean
public UserDao userDao() {
return new UserDao(...);
}
注意:确保正确初始化UserDao(即确保其所有依赖项都已初始化。如果在UserDao上使用Autowired,请确保这些依赖项也是@Bean
。[SOLVED]
经过两天的努力,我终于找到了解决方案
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = SecurityConfiguration.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService);
}
}
我不需要创建新的bean。我只需要将UserService对象传递到userDetailsService方法中,将自动连线,当然还要将@ComponentScan用于当前类。UserService类已经有了一个UserDao,我实现了它其中的用户详细信息服务
@Service("userService")
@Transactional(readOnly = true)
public class UserServiceImpl implements UserService, UserDetailsService {
@Autowired
private UserDao userDao;
// other method
@Override
public User getByUsername(String username) {
return userDao.getByUsername(username);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = getByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("user not found");
} else {
List<GrantedAuthority> listAuthorities = new ArrayList<GrantedAuthority>();
listAuthorities.add(new SimpleGrantedAuthority("ROLE_USER"));
return new org.springframework.security.core.userdetails.User(username, user.getPassword(), true, true, true, true, listAuthorities);
}
}
}
@Service(“用户服务”)
@事务(只读=真)
公共类UserServiceImpl实现UserService、UserDetailsService{
@自动连线
私有UserDao UserDao;
//其他方法
@凌驾
公共用户getByUsername(字符串用户名){
返回userDao.getByUsername(用户名);
}
@凌驾
public UserDetails loadUserByUsername(字符串用户名)引发UsernameNotFoundException{
User User=getByUsername(用户名);
if(user==null){
抛出新的UsernameNotFoundException(“未找到用户”);
}否则{
List ListAuthories=new ArrayList();
添加(新的SimpleGrantedAuthority(“角色用户”);
返回新的org.springframework.security.core.userdetails.User(username,User.getPassword(),true,true,true,listAuthories);
}
}
}
感谢Rob Winch提供的线索。我能知道您为什么特别寻找注释来配置spring安全性吗?至少对于spring安全性来说,将其作为xml配置具有更大的优势,这样可以在不接触现有代码的情况下灵活地对其进行更改。您可以在是link hi Jay,我没有理由“为什么”。我是spring framework的新手。我从3周前开始学习spring framework。最近我看到了很多变化。所有内容都从xml转换为java配置。所以,为什么我不学习最新的一个呢谢谢你的回答。我按照你的指示去做。但是它仍然不起作用。我发现了错误我找到了这个链接()它解决了我的问题虽然它不使用hibernate,但是正如你说的“我不需要自定义”AuthenticationProvider它让我更加困惑。你的UserDao也需要被定义为一个Bean。查看我的更新