Spring Security Hibernate Annotation-Beispiel

Beispiel für Spring Security + Hibernate Annotation

spring-hibernate-logo

In diesem Lernprogramm wird das Beispiel des vorherigenSpring Security + Hibernate4 XMLwiederverwendet und in ein auf Anmerkungen basierendes Beispiel konvertiert.

Verwendete Technologien:

  1. Feder 3.2.8.FREIGABE

  2. Federsicherheit 3.2.3.FREIGABE

  3. Ruhezustand 4.2.11.Final

  4. MySQL Server 5.6

  5. Tomcat 7 (Servlet 3.x-Container)

Schnelle Notiz :

  1. Erstellen Sie eine Sitzungsfactory mitLocalSessionFactoryBuilder

  2. Injizieren Sie die Session Factory in ein UserDao

  3. Integrieren Sie UserDao in ein benutzerdefiniertesUserDetailsService, um Benutzer aus der Datenbank zu laden.

1. Projektverzeichnis

Eine endgültige Projektverzeichnisstruktur.

spring-security-hibernate-annotation-directory

2. Benutzermodell + Zuordnungsdatei

Modellklassen und die auf Anmerkungen basierende Zuordnungsdatei.

User.java

package com.example.users.model;

import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "users", catalog = "test")
public class User {

    private String username;
    private String password;
    private boolean enabled;
    private Set userRole = new HashSet(0);

    public User() {
    }

    public User(String username, String password, boolean enabled) {
        this.username = username;
        this.password = password;
        this.enabled = enabled;
    }

    public User(String username, String password,
        boolean enabled, Set userRole) {
        this.username = username;
        this.password = password;
        this.enabled = enabled;
        this.userRole = userRole;
    }

    @Id
    @Column(name = "username", unique = true,
        nullable = false, length = 45)
    public String getUsername() {
        return this.username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Column(name = "password",
        nullable = false, length = 60)
    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Column(name = "enabled", nullable = false)
    public boolean isEnabled() {
        return this.enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
    public Set getUserRole() {
        return this.userRole;
    }

    public void setUserRole(Set userRole) {
        this.userRole = userRole;
    }

}

UserRole.java

package com.example.users.model;

import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

@Entity
@Table(name = "user_roles", catalog = "test",
    uniqueConstraints = @UniqueConstraint(
        columnNames = { "role", "username" }))
public class UserRole{

    private Integer userRoleId;
    private User user;
    private String role;

    public UserRole() {
    }

    public UserRole(User user, String role) {
        this.user = user;
        this.role = role;
    }

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "user_role_id",
        unique = true, nullable = false)
    public Integer getUserRoleId() {
        return this.userRoleId;
    }

    public void setUserRoleId(Integer userRoleId) {
        this.userRoleId = userRoleId;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "username", nullable = false)
    public User getUser() {
        return this.user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Column(name = "role", nullable = false, length = 45)
    public String getRole() {
        return this.role;
    }

    public void setRole(String role) {
        this.role = role;
    }

}

3. DAO-Klasse

DAO-Klassen zum Laden von Daten aus der Datenbank über den Ruhezustand.

UserDao.java

package com.example.users.dao;

import com.example.users.model.User;

public interface UserDao {

    User findByUserName(String username);

}

UserDaoImpl.java

package com.example.users.dao;

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

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

import com.example.users.model.User;

@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private SessionFactory sessionFactory;

    @SuppressWarnings("unchecked")
    public User findByUserName(String username) {

        List users = new ArrayList();

        users = sessionFactory.getCurrentSession()
            .createQuery("from User where username=?")
            .setParameter(0, username)
            .list();

        if (users.size() > 0) {
            return users.get(0);
        } else {
            return null;
        }

    }

}

4. UserDetailsService

Verwendet@Transactional, um eine Transaktionsmethode zu deklarieren.

MyUserDetailsService.java

package com.example.users.service;

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.example.users.dao.UserDao;
import com.example.users.model.UserRole;

@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {

    //get user from the database, via Hibernate
    @Autowired
    private UserDao userDao;

    @Transactional(readOnly=true)
    @Override
    public UserDetails loadUserByUsername(final String username)
        throws UsernameNotFoundException {

        com.example.users.model.User user = userDao.findByUserName(username);
        List authorities =
                                      buildUserAuthority(user.getUserRole());

        return buildUserForAuthentication(user, authorities);

    }

    // Converts com.example.users.model.User user to
    // org.springframework.security.core.userdetails.User
    private User buildUserForAuthentication(com.example.users.model.User user,
        List authorities) {
        return new User(user.getUsername(), user.getPassword(),
            user.isEnabled(), true, true, true, authorities);
    }

    private List buildUserAuthority(Set userRoles) {

        Set setAuths = new HashSet();

        // Build user's authorities
        for (UserRole userRole : userRoles) {
            setAuths.add(new SimpleGrantedAuthority(userRole.getRole()));
        }

        List Result = new ArrayList(setAuths);

        return Result;
    }

}

5. Sicherheitsanmerkung für den Frühling

Erklärt und bindet alles mit Anmerkungen, lest die Kommentare, es sollte selbsterklärend sein.

SecurityConfig.java

package com.example.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@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("/admin/**")
        .access("hasRole('ROLE_ADMIN')").and().formLogin()
        .loginPage("/login").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;
    }

}

VerwendetLocalSessionFactoryBuilder, um eine Sitzungsfactory zu erstellen.

AppConfig.java

package com.example.config;

import java.util.Properties;
import org.apache.commons.dbcp.BasicDataSource;
import org.hibernate.SessionFactory;
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.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBuilder;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@EnableWebMvc
@Configuration
@ComponentScan({ "com.example.*" })
@EnableTransactionManagement
@Import({ SecurityConfig.class })
public class AppConfig {

        @Bean
        public SessionFactory sessionFactory() {
                LocalSessionFactoryBuilder builder =
            new LocalSessionFactoryBuilder(dataSource());
                builder.scanPackages("com.example.users.model")
                      .addProperties(getHibernateProperties());

                return builder.buildSessionFactory();
        }

    private Properties getHibernateProperties() {
                Properties prop = new Properties();
                prop.put("hibernate.format_sql", "true");
                prop.put("hibernate.show_sql", "true");
                prop.put("hibernate.dialect",
                    "org.hibernate.dialect.MySQL5Dialect");
                return prop;
        }

    @Bean(name = "dataSource")
    public BasicDataSource dataSource() {

        BasicDataSource ds = new BasicDataSource();
            ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/test");
        ds.setUsername("root");
        return ds;
    }

    //Create a transaction manager
    @Bean
        public HibernateTransactionManager txManager() {
                return new HibernateTransactionManager(sessionFactory());
        }

    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver
                             = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/pages/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

}

Erledigt.

6. Projekt Demo

Die folgende Video-Demo ist für das Tutorial vonSpring Security database login. Da dieses Tutorial die gleiche Ausgabe generiert, wird die Videodemo wiederverwendet.

6.1 Access a password protected page : http://localhost:8080/spring-security-hibernate-annotation/admin , a login page is displayed.

spring-security-hibernate-annotation1

6.2 Enter user “example” and password “123456”.

spring-security-hibernate-annotation2

6.3 Try access /admin page with user “alex” and password “123456”, a 403 page will be displayed.

spring-security-hibernate-annotation3

Quellcode herunterladen

Laden Sie es herunter -spring-security-hibernate-annotation.zip (35 KB)