我的项目基于Spring和Hibernate,现在我必须从数据库和LDAP实现身份验证和分析。 鉴于我在春天是新手,我想从数据库实现身份验证开始,然后我会想到配置文件和LDAP。 我遵循了这个指南spring security annotation,但当我调用我的网页时,它像以前一样工作,不会调用任何身份验证。 这些是我的配置类:
SpringSecurityInitializer
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
SpringMvcInitializer
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
公共类SpringMvcInitializer扩展AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
SecurityConfig
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("userDetailsService")
UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/**")
.access("hasRole('ROLE_ADMIN')").and().formLogin()
.loginPage("/login").permitAll();//.failureUrl("/login?error")
//.usernameParameter("username")
//.passwordParameter("password")
//.and().logout().logoutSuccessUrl("/login?logout")
//.and().csrf()
//.and().exceptionHandling().accessDeniedPage("/403");
}
@Bean
public PasswordEncoder passwordEncoder(){
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
}
的AppConfig
@EnableWebMvc
@Configuration
@PropertySource(value = { "classpath:application.properties" })
@ComponentScan({ "com.*" })
@EnableTransactionManagement
@Import({ SecurityConfig.class, SpringMvcInitializer.class})
@EnableJpaRepositories("com.repository")
public class AppConfig extends WebMvcConfigurerAdapter{
@Autowired
private Environment env;
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
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_HIBERNATE_DIALECT = "hibernate.dialect";
// private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
/**
* This and the next methods are used to avoid exception while jackson mapping the entity, so fields are setted with null value
* unless use Hibernate.initialize
* @return
*/
public MappingJackson2HttpMessageConverter jacksonMessageConverter(){
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = new ObjectMapper();
//Registering Hibernate4Module to support lazy objects
mapper.registerModule(new Hibernate4Module());
messageConverter.setObjectMapper(mapper);
return messageConverter;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//Here we add our custom-configured HttpMessageConverter
converters.add(jacksonMessageConverter());
super.configureMessageConverters(converters);
}
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
// properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
properties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
properties.put("hibernate.enable_lazy_load_no_trans",true);
return properties;
}
@Bean(name = "dataSource")
public BasicDataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
ds.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
ds.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
ds.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return ds;
}
@Bean
public ServletContextTemplateResolver TemplateResolver(){
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/templates/pages/");
resolver.setSuffix(".html");
resolver.setTemplateMode("LEGACYHTML5");
resolver.setCacheable(false);
return resolver;
/*ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
return resolver;*/
}
@Bean
public SpringTemplateEngine templateEngine(){
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(TemplateResolver());
return templateEngine;
}
@Bean
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setOrder(1);
resolver.setViewNames(new String[]{"*", "js/*", "template/*"});
return resolver;
}
/**
* Register multipartResolver for file upload
* @return
*/
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver=new CommonsMultipartResolver();
resolver.setDefaultEncoding("utf-8");
return resolver;
}
/**
* Allow use of bootstrap
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("/static/");
}
/**
* Allow use of JPA
*/
@Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setPackagesToScan(env.
getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
entityManagerFactoryBean.setJpaProperties(getHibernateProperties());
return entityManagerFactoryBean;
}
}
MyUserDetailsServices
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
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.domain.UserRole;
import com.services.dbservices.tables.UserServices;
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UserServices userServices;
@Transactional(readOnly=true)
@Override
public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
com.domain.User user = userServices.findById(username);
List<GrantedAuthority> authorities = buildUserAuthority(user.getUserRole());
return buildUserForAuthentication(user, authorities);
}
// Converts com.users.model.User user to
// org.springframework.security.core.userdetails.User
private User buildUserForAuthentication(com.domain.User user, List<GrantedAuthority> authorities) {
return new User(user.getUsername(), user.getPassword(), user.isEnabled(), true, true, true, authorities);
}
private List<GrantedAuthority> buildUserAuthority(Set<UserRole> userRoles) {
Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();
// Build user's authorities
for (UserRole userRole : userRoles) {
setAuths.add(new SimpleGrantedAuthority(userRole.getUserRoleKeys().getRole()));
}
List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);
return Result;
}
}
MainController
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class MainControllerImpl implements MainController{
@Override
@RequestMapping(value = { "/", "/welcome**" }, method = RequestMethod.GET)
public String mainPage(){
return "index";
}
@Override
@RequestMapping(value = { "/login" }, method = RequestMethod.GET)
public String loginPage(){
return "login";
}
}
你怎么看,我只使用没有任何xml配置文件的注释。 问题出在哪儿?如果有人对hibernate的弹簧安全有一个很好的指导,带有注释的Ldap我感谢他。 目前,仅用于测试,login.html
<div class="login-box-body">
<p class="login-box-msg">Sign in to start your session</p>
<form th:action="@{/login}" method="post">
<div th:if="${param.error}">
<script>
notifyMessage("Invalid username and password!", 'error');
</script>
</div>
<div th:if="${param.logout}">
<script>
notifyMessage("You have been logged out!", 'error');
</script>
</div>
<div class="form-group has-feedback">
<input id="username" name="username" type="text"
class="form-control" placeholder="Username"> <span
class="glyphicon glyphicon-user form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input id="password" name="password" type="password"
class="form-control" placeholder="Password"> <span
class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<div class="row">
<div class="col-xs-8">
<div class="checkbox icheck">
<label> <input type="checkbox"> Remember Me
</label>
</div>
</div>
<!-- /.col -->
<div class="col-xs-4">
<button id="signinButton" type="submit"
class="btn btn-primary btn-block btn-flat">Sign In</button>
</div>
<!-- /.col -->
</div>
</form>
<div class="social-auth-links text-center">
<p>- OR -</p>
<a href="#" class="btn btn-block btn-social btn-facebook btn-flat"><i
class="fa fa-facebook"></i> Sign in using Facebook</a> <a href="#"
class="btn btn-block btn-social btn-google btn-flat"><i
class="fa fa-google-plus"></i> Sign in using Google+</a>
</div>
<!-- /.social-auth-links -->
<a href="#">I forgot my password</a><br> <a href="register.html"
class="text-center">Register a new membership</a>
</div>
答案 0 :(得分:1)
我不是Spring-security的专家,但在这一行:
http.authorizeRequests().antMatchers("/admin/**")
.access("hasRole('ROLE_ADMIN')").and().formLogin()
.loginPage("/login").failureUrl("/login?error")
你说只有具有ROLE“ROLE_ADMIN”的认可的pereson可以请求“/ admin / **”。 但是你的控制器只有“/”和“/ welcome”的路由 所以你永远不会在“/ admin /”
里面要求任何东西如果您想尝试弹簧安全配置,请将控制器更改为:
@Controller
公共类MainControllerImpl {
@RequestMapping(value = { "/admin/welcome" }, method = RequestMethod.GET)
public String singleUpload(){
return "index";
}
}
答案 1 :(得分:0)
我必须在AppConfig中添加
@Bean
public SpringSecurityDialect springSecurityDialect() {
SpringSecurityDialect dialect = new SpringSecurityDialect();
return dialect;
}
和SecurityConfig
@Override
public void configure(WebSecurity web) throws Exception {
web
//Spring Security ignores request to static resources such as CSS or JS files.
.ignoring()
.antMatchers("/static/**");
}