通过MySQL-LDAP-Thymeleaf登录弹簧安全性

时间:2015-09-15 09:33:30

标签: spring login spring-security ldap thymeleaf

这是我第一次使用Spring和Ldap,所以我有几个难以登录网站。我阅读了很多样本​​,指南和文档,但现在我对几种类型的实现感到困惑。 我第一次有一个登录页面,用户自己输入用户名和密码,如果用户和密码正确,我会检查数据库。如果不是,我必须使用Ldap来验证用户并将数据添加到数据库。 我找到了最好的方法,在我的项目中我使用Spring for REst webservice和数据库,所以我想使用spring甚至用ldap登录。我找到了几个文件,但彼此不同,有些是xml文件,有些是我喜欢的类和注释。我从来没有使用过spring,ldap和login机制,有这方面的例子吗?我该怎么办? 这是我的项目结构:

enter image description here

有什么想法吗?谢谢

直到现在我将这个项目从零开始,然后,如果它有效,将它放入我的项目中:

package service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

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 dao.UserDao;

@Service
@Transactional(readOnly=true)
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserDao UserDao;    

    public UserDetails loadUserByUsername(String login)
            throws UsernameNotFoundException {

        model.User domainUser = UserDao.getUser(login);

        boolean enabled = true;
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;

        return new User(
                domainUser.getLogin(), 
                domainUser.getPassword(), 
                enabled, 
                accountNonExpired, 
                credentialsNonExpired, 
                accountNonLocked,
                getAuthorities(domainUser.getRole().getId())
        );
    }

    public Collection<? extends GrantedAuthority> getAuthorities(Integer role) {
        List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role));
        return authList;
    }

    public List<String> getRoles(Integer role) {

        List<String> roles = new ArrayList<String>();

        if (role.intValue() == 1) {
            roles.add("ROLE_MODERATOR");
            roles.add("ROLE_ADMIN");
        } else if (role.intValue() == 2) {
            roles.add("ROLE_MODERATOR");
        }
        return roles;
    }

    public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(role));
        }
        return authorities;
    }

}

apllicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
    <!-- Security (authentication and authorization) configuration -->
    <import resource="applicationContext-security.xml" />
</beans>

的applicationContext-安全

    <?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                                 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                                 http://www.springframework.org/schema/security
                                 http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <!-- Authentication using a memory user list -->
        <beans:bean id='customUserDetailsService' class='com.service.CustomUserDetailsService'>
        </beans:bean>
    <authentication-manager alias="authenticationManager">
        <authentication-provider user-service-ref="customUserDetailsService">
            <password-encoder hash="md5"/>
        </authentication-provider>
    </authentication-manager>
    <http auto-config="true" use-expressions="true">
        <!-- Login pages -->
        <!-- <form-login login-page="/user-login.html" default-target-url="/success-login.html" authentication-failure-url="/error-login.html">
        <logout logout-success-url="/index.html">

        </logout></form-login></intercept-url></intercept-url></http> -->

        <form-login login-page="/login.html" authentication-failure-url="/login-error.html" />
        <logout />
        <!-- Security zones -->
        <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
        <intercept-url pattern="/user/**" access="hasRole('ROLE_USER')" />
        <intercept-url pattern="/shared/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
    </http>

</beans:beans>

springServlet

    <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc
                           http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
                           http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context-3.1.xsd">


    <!-- Use spring servlet for all requests, including static resources -->
    <mvc:default-servlet-handler/>


    <!-- Use @MVC annotations -->
    <mvc:annotation-driven />


    <!-- User @Controller, @Service... annotations -->
    <context:component-scan base-package="com" />


    <!-- Thymeleaf template engine -->
    <bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
        <property name="prefix" value="/WEB-INF/templates/" />
        <property name="templateMode" value="HTML5" />
        <property name="characterEncoding" value="UTF-8" />
        <!-- Template cache is true by default. Set to false if you want -->
        <!-- templates to be automatically updated when modified.        -->
        <property name="cacheable" value="true" />
    </bean>

    <bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
        <property name="templateResolver" ref="templateResolver" />
        <property name="additionalDialects">
            <set>
                <bean class="org.thymeleaf.extras.springsecurity3.dialect.SpringSecurityDialect" />
            </set>
        </property>
    </bean>

    <bean id="viewResolver" class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
        <property name="templateEngine" ref="templateEngine" />
        <property name="characterEncoding" value="UTF-8" />
    </bean>

</beans>

的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="stsm" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <!-- Spring -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- Spring MVC front controller -->
    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!-- Spring security -->
    <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>
    <!-- Error pages -->
    <error-page>
        <exception-type>java.lang.Throwable</exception-type>
        <location>/error.html</location>
    </error-page>
    <error-page>
        <error-code>400</error-code>
        <location>/error.html</location>
    </error-page>
    <error-page>
        <error-code>401</error-code>
        <location>/error.html</location>
    </error-page>
    <error-page>
        <error-code>403</error-code>
        <location>/error.html</location>
    </error-page>
    <error-page>
        <error-code>404</error-code>
        <location>/error.html</location>
    </error-page>
    <error-page>
        <error-code>500</error-code>
        <location>/error.html</location>
    </error-page>
    <error-page>
        <error-code>503</error-code>
        <location>/error.html</location>
    </error-page>
</web-app>

userDAO的

package dao;

import model.User;

public interface UserDao {
     public User getUser(String login);
}

在UserDAOImpl

package dao;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import model.User;


@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private SessionFactory sessionFactory;

    private Session openSession() {
        return sessionFactory.getCurrentSession();
    }

    public User getUser(String login) {
        List<User> userList = new ArrayList<User>();
        Query query = openSession().createQuery("from User u where u.login = :login");
        query.setParameter("login", login);
        userList = query.list();
        if (userList.size() > 0)
            return userList.get(0);
        else
            return null;    
    }

}

HibernateConfiguration

   package com.configuration;

    import java.util.Properties;

    import javax.sql.DataSource;

    import org.hibernate.jpa.HibernatePersistenceProvider;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.core.env.Environment;
    import org.springframework.jdbc.datasource.DriverManagerDataSource;
    import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
    import org.springframework.orm.jpa.JpaTransactionManager;
    import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
    import org.springframework.transaction.annotation.EnableTransactionManagement;

    @Configuration
    @EnableTransactionManagement
    @ComponentScan({ "com" })
    @PropertySource(value = { "classpath:application.properties" })
    public class HibernateConfiguration {

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

        @Autowired
        private Environment env;

        @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(hibProperties());

            return entityManagerFactoryBean;
        }

        @Bean
        public DataSource dataSource() {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();

            dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
            dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
            dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
            dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));

            return dataSource;
        }

        private Properties hibProperties() {
            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));
            return properties;
        }

        @Bean
        public JpaTransactionManager transactionManager() {
            JpaTransactionManager transactionManager = new JpaTransactionManager();
            transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
            return transactionManager;
        }

            @Bean
        public LocalSessionFactoryBean sessionFactory() {
            LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
            sessionFactory.setDataSource(dataSource());
            sessionFactory.setPackagesToScan(new String[] { "com.websystique.spring.model" });
            sessionFactory.setHibernateProperties(hibProperties());
            return sessionFactory;
         }


    }

我的CustomUserDetailsS​​ervice存在问题,因为model.User domainUser = UserDao.getUser(login); UserDao为null 这是对的:

<!-- User @Controller, @Service... annotations -->
    <context:component-scan base-package="com" />

1 个答案:

答案 0 :(得分:0)

使用Spring引导,以下类足以提供基于Spring-Security LDAP的身份验证: -

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().fullyAuthenticated().and().httpBasic();
    } 

    @Configuration  
    protected static class AuthenticationConfig extends GlobalAuthenticationConfigurerAdapter {

        @Bean
        public LdapContextSource contextSource() {
            LdapContextSource ctx = new LdapContextSource();
            try {
                ctx.setUrl("aaa");
                ctx.setBase("bbb");
                ctx.setUserDn("ccc");
                ctx.setPassword("ddd");
                ctx.setReferral("follow");
                ctx.afterPropertySet();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return ctx;
        }

        @Override
        public void init(AuthenticationmanagerBuilder auth) throws Exception {
            auth.ldapAuthentication().contextSource(contextSource()).userSearchFilter("sAMAccountName={0}");
        }   
    }
}