Spring Security + Hibernate XML示例

Spring休眠徽标

在本教程中,我们将向您展示如何在Spring Security XML配置示例中集成Hibernate 4。

注意
对于注释版本,请阅读此Spring Security + Hibernate注释示例

使用的技术:

  1. 春天3.2.8。发布
  2. Spring Security 3.2.3发布
  3. 休眠4.2.11.Final
  4. MySQL服务器5.6
  5. JDK 1.6
  6. Maven 3
  7. Eclipse 4.3

快速笔记

  1. 使用hibernate4.LocalSessionFactoryBean创建一个会话工厂
  2. 将会话工厂注入UserDao
  3. 要与Spring Security集成,请创建一个实现UserDetailsService接口的类,并使用UserDao加载User
  4. 必须声明事务管理器,否则Hibernate在Spring中将无法工作

1.项目目录

最终项目目录结构。

Spring安全休眠目录

2.项目依赖性

POM文件中项目的依赖项列表。

pom.xml
<properties>
		<spring.version>3.2.8.RELEASE</spring.version>
		<spring.security.version>3.2.3.RELEASE</spring.security.version>
		<jstl.version>1.2</jstl.version>
		<mysql.connector.version>5.1.30</mysql.connector.version>
		<logback.version>1.1.2</logback.version>
		<slf4j.version>1.7.6</slf4j.version>
		<hibernate.version>4.2.11.Final</hibernate.version>
		<dbcp.version>1.4</dbcp.version>
		<servletapi.version>2.5</servletapi.version>
	</properties>

	<dependencies>

		<!-- database pool -->
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>${dbcp.version}</version>
		</dependency>

		<!-- Hibernate ORM -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>${hibernate.version}</version>
		</dependency>

		<!-- Spring 3 dependencies -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
			<exclusions>
			  <exclusion>
				<groupId>commons-logging</groupId>
				<artifactId>commons-logging</artifactId>
			  </exclusion>
			</exclusions>
		</dependency>

		<!-- Spring MVC -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- Spring + aspects -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- ORM integration, e.g Hibernate -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- Spring Security -->
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>${spring.security.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-config</artifactId>
			<version>${spring.security.version}</version>
		</dependency>

		<!-- Spring Security JSP Taglib -->
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-taglibs</artifactId>
			<version>${spring.security.version}</version>
		</dependency>

		<!-- jstl for jsp page -->
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
			<version>${jstl.version}</version>
		</dependency>

		<!-- MySql Driver -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.connector.version}</version>
		</dependency>

		<!-- logging, slf4j -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${slf4j.version}</version>
		</dependency>

		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>${logback.version}</version>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>${servletapi.version}</version>
			<scope>provided</scope>
		</dependency>

	</dependencies>

3.用户表

创建表以存储用户和用户角色的SQL脚本。

mysql.sql
CREATE  TABLE users (
  username VARCHAR(45) NOT NULL ,
  password VARCHAR(60) NOT NULL ,
  enabled TINYINT NOT NULL DEFAULT 1 ,
  PRIMARY KEY (username));

CREATE TABLE user_roles (
  user_role_id int(11) NOT NULL AUTO_INCREMENT,
  username varchar(45) NOT NULL,
  role varchar(45) NOT NULL,
  PRIMARY KEY (user_role_id),
  UNIQUE KEY uni_username_role (role,username),
  KEY fk_username_idx (username),
  CONSTRAINT fk_username FOREIGN KEY (username) REFERENCES users (username));

INSERT INTO users(username,password,enabled)
VALUES ('mkyong','$2a$10$04TVADrR6/SPLBjsK0N30.Jf5fNjBugSACeGv1S69dZALR7lSov0y', true);
INSERT INTO users(username,password,enabled)
VALUES ('alex','$2a$10$04TVADrR6/SPLBjsK0N30.Jf5fNjBugSACeGv1S69dZALR7lSov0y', true);

INSERT INTO user_roles (username, role)
VALUES ('mkyong', 'ROLE_USER');
INSERT INTO user_roles (username, role)
VALUES ('mkyong', 'ROLE_ADMIN');
INSERT INTO user_roles (username, role)
VALUES ('alex', 'ROLE_USER');

4.用户模型+ Hibernate XML映射

模型类及其XML映射文件。

User.java
package com.mkyong.users.model;

import java.util.HashSet;
import java.util.Set;

public class User {
	
	private String username;
	private String password;
	private boolean enabled;
	private Set<UserRole> userRole = new HashSet<UserRole>(0);
	
	//getter and setter methods
}
UserRole.java
package com.mkyong.users.model;

public class UserRole{

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

	//getter and setter methods
}
Users.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.mkyong.users.model.User" table="users" catalog="test">
        <id name="username" type="string">
            <column name="username" length="45" />
            <generator class="assigned" />
        </id>
        <property name="password" type="string">
            <column name="password" length="60" not-null="true" />
        </property>
        <property name="enabled" type="boolean">
            <column name="enabled" not-null="true" />
        </property>
        <set name="userRole" table="user_roles" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="username" length="45" not-null="true" />
            </key>
            <one-to-many class="com.mkyong.users.model.UserRole" />
        </set>
    </class>
</hibernate-mapping>
UserRoles.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.mkyong.users.model.UserRole" table="user_roles" catalog="test">
        <id name="userRoleId" type="java.lang.Integer">
            <column name="user_role_id" />
            <generator class="identity" />
        </id>
        <many-to-one name="user" class="com.mkyong.users.model.User" fetch="select">
            <column name="username" length="45" not-null="true" />
        </many-to-one>
        <property name="role" type="string">
            <column name="role" length="45" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

5. DAO类

创建一个UserDao类,以通过Hibernate从数据库中加载用户。

UserDao.java
package com.mkyong.users.dao;

import com.mkyong.users.model.User;

public interface UserDao {

	User findByUserName(String username);

}
UserDaoImpl.java
package com.mkyong.users.dao;

import java.util.ArrayList;
import java.util.List;
import org.hibernate.SessionFactory;

import com.mkyong.users.model.User;

public class UserDaoImpl implements UserDao {

	private SessionFactory sessionFactory;

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

		List<User> users = new ArrayList<User>();

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

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

	}

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

}

6. UserDetailsS​​ervice

创建一个自定义UserDetailsService ,从UserDao加载用户,然后构建用户的权限。

注意
示例是从此Spring的JdbcDaoImpl中引用的

MyUserDetailsService.java
package com.mkyong.users.service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

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

public class MyUserDetailsService implements UserDetailsService {

	private UserDao userDao;

	@Override
	public UserDetails loadUserByUsername(final String username) 
               throws UsernameNotFoundException {

		com.mkyong.users.model.User user = userDao.findByUserName(username);
		List<GrantedAuthority> authorities = buildUserAuthority(user.getUserRole());

		return buildUserForAuthentication(user, authorities);
		

	}

	// Converts com.mkyong.users.model.User user to
	// org.springframework.security.core.userdetails.User
	private User buildUserForAuthentication(com.mkyong.users.model.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.getRole()));
		}

		List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);

		return Result;
	}

	public UserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

}

7. Spring Security XML

阅读评论,应该不言自明。

spring-security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:beans="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.0.xsd
	http://www.springframework.org/schema/security
	http://www.springframework.org/schema/security/spring-security-3.2.xsd">

	<!-- enable use-expressions -->
	<http auto-config="true" use-expressions="true">
		<intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')" />

		<!-- access denied page -->
		<access-denied-handler error-page="/403" />
		<form-login 
		    login-page="/login" 
		    default-target-url="/welcome"
			authentication-failure-url="/login?error" 
			username-parameter="username"
			password-parameter="password" />
		<logout logout-success-url="/login?logout" />
		<!-- enable csrf protection -->
		<csrf />
	</http>

	<authentication-manager>
		<authentication-provider user-service-ref="myUserDetailsService" >
			<password-encoder hash="bcrypt" />    
		</authentication-provider>
	</authentication-manager>

</beans:beans>
spring-database.xml
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
	http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

	<!-- MySQL data source -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">

		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost:3306/test" />
		<property name="username" value="root" />
		<property name="password" value="password" />
	</bean>

	<!-- Hibernate session factory -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="mappingResources">
			<list>
				<value>orm/Users.hbm.xml</value>
				<value>orm/UserRoles.hbm.xml</value>
			</list>
		</property>
		<property name="hibernateProperties">
		    <props>
			<prop key="hibernate.dialect">
                           org.hibernate.dialect.MySQL5Dialect
                        </prop>
			<prop key="hibernate.format_sql">true</prop>
			<prop key="hibernate.show_sql">true</prop>
		    </props>
		</property>
	</bean>

	<bean id="userDao" class="com.mkyong.users.dao.UserDaoImpl">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>

	<bean id="myUserDetailsService" 
                class="com.mkyong.users.service.MyUserDetailsService">
		<property name="userDao" ref="userDao" />
	</bean>

	<!-- MUST have transaction manager, using aop and aspects  -->
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>

	<tx:advice id="txAdvice" transaction-manager="transactionManager">
	    <tx:attributes>
		<tx:method name="get*" read-only="true" />
		<tx:method name="find*" read-only="true" />
		<tx:method name="*" />
	    </tx:attributes>
	</tx:advice>

	<aop:config>
	    <aop:pointcut id="userServicePointCut"
		expression="execution(* com.mkyong.users.service.*Service.*(..))" />
	    <aop:advisor advice-ref="txAdvice" pointcut-ref="userServicePointCut" />
	</aop:config>

</beans>

做完了

注意
那些JSP,web.xml和控制器文件被省略,这是一个标准的代码,如果您对此感兴趣,请在文章末尾下载完整的源代码。

8.项目演示

以下视频演示用于使用JDBC教程登录Spring Security数据库 。 由于本教程生成了相同的输出,但是使用了Hibernate来加载User,因此可以重用视频演示。

8.1进入密码保护页面:http:// localhost:8080 / spring-security-hibernate / admin,显示登录页面。

Spring安全冬眠1

8.2输入用户“ mkyong”和密码“ 123456”。

Spring安全冬眠2

8.3尝试使用用户“ alex”和密码“ 123456”访问/admin页面,将显示403页面。

Spring安全冬眠3

下载源代码

下载它– spring-security-hibernate.zip (30 KB)

参考文献

  1. SpringORM –休眠
  2. Spring Hibernate4 LocalSessionFactoryBean JavaDoc
  3. Spring Hibernate3 LocalSessionFactoryBean JavaDoc
  4. Spring交易管理
  5. Hibernate ORM文档
  6. 使用JDBC和数据库使用Spring Security Form登录
  7. Hibernate:找不到当前线程的会话

翻译自: https://mkyong.com/spring-security/spring-security-hibernate-xml-example/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值