java - Spring Security 与 hibernate 和 mysql 登录

标签 java spring hibernate spring-mvc spring-security

我的项目基于 Spring 和 Hibernate,现在我必须从数据库和 LDAP 实现身份验证和分析。 鉴于我是 Spring 的新人,我想从数据库身份验证的实现开始,然后我会考虑配置文件和 LDAP。 我遵循了本指南 spring security annotation但是当我调用我的网页时,它的工作方式与以前一样,没有调用任何身份验证。 这些是我的配置类:

SpringSecurity初始化器

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

    public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {

    }

SpringMvc初始化器

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

公共(public)类 SpringMvcInitializer 扩展 AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class[] { AppConfig.class };
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return null;
}

@Override
protected String[] getServletMappings() {
    return new String[] { "/" };
}   
}

安全配置

@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;
    }

}

应用配置

    @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;

    }
}

我的用户详细信息服务

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;
    }

}

主 Controller

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配置文件。 哪里有问题?如果有人有关于 Spring Security 与 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>

最佳答案

我不是 Spring-security 方面的专家,但在这一行:

http.authorizeRequests().antMatchers("/admin/**")
    .access("hasRole('ROLE_ADMIN')").and().formLogin()
    .loginPage("/login").failureUrl("/login?error")

您的意思是只有经过身份验证且角色为“ROLE_ADMIN”的人才能请求“/admin/**”。 但你的 Controller 只有“/”和“/welcome”的路由 所以你永远不会在“/admin/”内询问任何内容

如果你想尝试你的 spring-security 配置是否有效,请将你的 Controller 更改为:

@Controller

公共(public)类MainControllerImpl {

@RequestMapping(value = { "/admin/welcome" }, method = RequestMethod.GET)
public String singleUpload(){
    return "index";
}

}

关于java - Spring Security 与 hibernate 和 mysql 登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34309995/

相关文章:

java - 将 yaml 文件标记为已弃用

java - 清理重复设置和清理 Java(JDBC) 代码

Java:泛型继承

spring注释错误找不到类型: java. lang.Double的验证器

java - 您可以在没有外键的情况下以一对一关系链接两个实体吗?

java - 将 Java 代码转换为 JRuby

java - JSP 不在 Spring 中显示模型中的对象

java - Spring 安全许可证全部不起作用

php - 在 CakePHP 中烘焙每张 table ?

mysql - Hibernate,如何建模这种关系