我刚刚了解了 spring security,并想使用 java hibernate 配置连接到数据库,但我发现很少有示例或教程。我通过使用 xml 配置找到了更多信息。我在这里使用 Spring 4.0.2、Spring-Security 3.2.0 和 Hibernate 4.3.2
我的问题是: 下面的xml如何转换成java配置?
<authentication-manager>
<authentication-provider user-service-ref="customUserDetailsService">
<password-encoder hash="plaintext">
</password-encoder></authentication-provider>
</authentication-manager>
其中CustomUserDetailsService.java
package com.whatever.svtest.service.impl;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
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;
import com.whatever.svtest.dao.UserDao;
@Service
@Transactional(readOnly = true)
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
com.whatever.svtest.model.User domainUser = userDao.getByUsername(username);
if (domainUser == null) {
throw new UsernameNotFoundException("user not found");
}
List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("USER"));
return new User(username, domainUser.getPassword(), true, true, true, true, authorities);
}
}
在SecurityConfig.java上,我使用spring创建的默认登录表单。我正在尝试自己弄清楚如何将 xml 配置转换为 java 配置。
package com.whatever.svtest.init;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import com.whatever.svtest.service.impl.UserServiceImpl;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new UserServiceImpl()).passwordEncoder(NoOpPasswordEncoder.getInstance());
}
}
我将 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") };
}
}
WebAppConfig.java
package com.whatever.svtest.init;
import javax.annotation.Resource;
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.context.support.ResourceBundleMessageSource;
import org.springframework.core.env.Environment;
import org.springframework.web.servlet.ViewResolver;
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.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
@Import({ DatabaseConfig.class })
@ComponentScan(basePackages = { "com.whatever.svtest.controller" })
@PropertySource({ "classpath:persistence-mysql.properties" })
public class WebAppConfig extends WebMvcConfigurerAdapter {
@Resource
private Environment env;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/assets/**").addResourceLocations("/assets/");
}
@Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasename("messages");
source.setUseCodeAsDefaultMessage(true);
return source;
}
@Bean
public ViewResolver setupViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".jsp");
return resolver;
}
}
当我运行我的网络应用程序时,我得到了这个。 (我把图片放在这里/image/Mssrc.jpg)
我还(在某处)阅读了有关创建 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));
}
}
最佳答案
配置不一致?
您发布的配置对我来说不太有意义。具体如下:
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new UserServiceImpl()).passwordEncoder(NoOpPasswordEncoder.getInstance());
}
解决方案
看来您还没有定义 UserServiceImpl,但您已经定义了 CustomUserDetailsService (这可能是应该传入的参数。但是,为了 Autowiring bean,您需要将其创建为 bean。所以您应该这样更改您的配置:
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(uds());
}
@Bean
public CustomUserDetailsService uds() {
return new CustomUserDetailsService();
}
通过将 CustomUserDetailsService 作为 @Bean 返回,您可以确保 Spring 正确地 Autowiring 它。
一些附加说明:
- 您不需要自定义 AuthenticationProvider。这是因为您使用用户名/密码进行身份验证,UserDetailsService 就可以了。如果您想使用用户名/密码以外的其他内容进行身份验证,您可以创建一个自定义的 AuthenticationProvider
- 无需指定无操作密码编码器,因为这是默认值。
改进 CustomUserDetailsService
在当前的实现中需要指出的一件事是,虽然您可以直接 @Autowire 字段,但它会更容易犯错误,因此您可能应该更改 CustomUserDetailsService 以具有允许注入(inject) UserDao 的构造函数。这也使得单元测试更加容易(因此您不需要使用反射来设置 UserDao)。因此,您可以将 CustomUserDetailsService 更新为:
@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(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
。
关于java - 如何使用 Spring-Security 3 和 Hibernate 4 将 spring security xml 配置 hibernate 转换为 java 配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22176693/