大多数时候,我们将需要在Web应用程序中配置自己的安全访问角色。 这在Spring Security中很容易实现。 在本文中,我们将看到最简单的方法。

首先,我们将在数据库中需要以下表格:

CREATE TABLE IF NOT EXISTS `mydb`.`security_role` (`id` INT(11) NOT NULL AUTO_INCREMENT ,`name` VARCHAR(50) NULL DEFAULT NULL ,PRIMARY KEY (`id`) )ENGINE = InnoDBAUTO_INCREMENT = 4DEFAULT CHARACTER SET = latin1;CREATE TABLE IF NOT EXISTS `mydb`.`user` (`id` INT(11) NOT NULL AUTO_INCREMENT ,`first_name` VARCHAR(45) NULL DEFAULT NULL ,`family_name` VARCHAR(45) NULL DEFAULT NULL ,`dob` DATE NULL DEFAULT NULL ,`password` VARCHAR(45) NOT NULL ,`username` VARCHAR(45) NOT NULL ,`confirm_password` VARCHAR(45) NOT NULL ,`active` TINYINT(1) NOT NULL ,PRIMARY KEY (`id`) ,UNIQUE INDEX `username` (`username` ASC) )ENGINE = InnoDBAUTO_INCREMENT = 9DEFAULT CHARACTER SET = latin1;CREATE TABLE IF NOT EXISTS `mydb`.`user_security_role` (`user_id` INT(11) NOT NULL ,`security_role_id` INT(11) NOT NULL ,PRIMARY KEY (`user_id`, `security_role_id`) ,INDEX `security_role_id` (`security_role_id` ASC) ,CONSTRAINT `user_security_role_ibfk_1`FOREIGN KEY (`user_id` )REFERENCES `mydb`.`user` (`id` ),CONSTRAINT `user_security_role_ibfk_2`FOREIGN KEY (`security_role_id` )REFERENCES `mydb`.`security_role` (`id` ))ENGINE = InnoDBDEFAULT CHARACTER SET = latin1;

显然,表用户将拥有用户,表security_role将拥有安全角色,而user_security_roles将拥有关联。 为了使实现尽可能简单,security_role表中的条目应始终以“ ROLE_”开头,否则我们将需要封装(本文将不涉及)。

因此,我们执行以下语句:

insert into security_role(name) values ('ROLE_admin');insert into security_role(name) values ('ROLE_Kennel_Owner');insert into security_role(name) values ('ROLE_User');insert into user (first_name,family_name,password,username,confirm_password,active)values ('ioannis','ntantis','123456','giannisapi','123456',1);insert into user_security_role (user_id,security_role_id) values (1,1);

因此,执行这些命令后,我们将得到以下内容:

三种不同的安全角色

一位用户名为“ giannisapi”的用户

我们已将角色“ ROLE_admin”赋予用户“ giannisapi”

现在,一切都已在数据库端完成,我们将移至Java端,看看需要做什么。

首先,我们将创建必要的DTO(有多种工具可以为您自动从数据库生成DTO):

package org.intan.pedigree.form;import java.io.Serializable;import java.util.Collection;import java.util.Date;import java.util.Set;import javax.persistence.Basic;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.ManyToMany;import javax.persistence.NamedQueries;import javax.persistence.NamedQuery;import javax.persistence.Table;import javax.persistence.Temporal;import javax.persistence.TemporalType;/**** @author intan*/@Entity@Table(name = 'user', catalog = 'mydb', schema = '')@NamedQueries({@NamedQuery(name = 'UserEntity.findAll', query = 'SELECT u FROM UserEntity u'),@NamedQuery(name = 'UserEntity.findById', query = 'SELECT u FROM UserEntity u WHERE u.id = :id'),@NamedQuery(name = 'UserEntity.findByFirstName', query = 'SELECT u FROM UserEntity u WHERE u.firstName = :firstName'),@NamedQuery(name = 'UserEntity.findByFamilyName', query = 'SELECT u FROM UserEntity u WHERE u.familyName = :familyName'),@NamedQuery(name = 'UserEntity.findByDob', query = 'SELECT u FROM UserEntity u WHERE u.dob = :dob'),@NamedQuery(name = 'UserEntity.findByPassword', query = 'SELECT u FROM UserEntity u WHERE u.password = :password'),@NamedQuery(name = 'UserEntity.findByUsername', query = 'SELECT u FROM UserEntity u WHERE u.username = :username'),@NamedQuery(name = 'UserEntity.findByConfirmPassword', query = 'SELECT u FROM UserEntity u WHERE u.confirmPassword = :confirmPassword'),@NamedQuery(name = 'UserEntity.findByActive', query = 'SELECT u FROM UserEntity u WHERE u.active = :active')})public class UserEntity implements Serializable {private static final long serialVersionUID = 1L;@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Basic(optional = false)@Column(name = 'id')private Integer id;@Column(name = 'first_name')private String firstName;@Column(name = 'family_name')private String familyName;@Column(name = 'dob')@Temporal(TemporalType.DATE)private Date dob;@Basic(optional = false)@Column(name = 'password')private String password;@Basic(optional = false)@Column(name = 'username')private String username;@Basic(optional = false)@Column(name = 'confirm_password')private String confirmPassword;@Basic(optional = false)@Column(name = 'active')private boolean active;@JoinTable(name = 'user_security_role', joinColumns = {@JoinColumn(name = 'user_id', referencedColumnName = 'id')}, inverseJoinColumns = {@JoinColumn(name = 'security_role_id', referencedColumnName = 'id')})@ManyToManyprivate Set securityRoleCollection;public UserEntity() {}public UserEntity(Integer id) {this.id = id;}public UserEntity(Integer id, String password, String username, String confirmPassword, boolean active) {this.id = id;this.password = password;this.username = username;this.confirmPassword = confirmPassword;this.active = active;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getFirstName() {return firstName;}public void setFirstName(String firstName) {this.firstName = firstName;}public String getFamilyName() {return familyName;}public void setFamilyName(String familyName) {this.familyName = familyName;}public Date getDob() {return dob;}public void setDob(Date dob) {this.dob = dob;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getConfirmPassword() {return confirmPassword;}public void setConfirmPassword(String confirmPassword) {this.confirmPassword = confirmPassword;}public boolean getActive() {return active;}public void setActive(boolean active) {this.active = active;}public Set getSecurityRoleCollection() {return securityRoleCollection;}public void setSecurityRoleCollection(Set securityRoleCollection) {this.securityRoleCollection = securityRoleCollection;}@Overridepublic int hashCode() {int hash = 0;hash += (id != null ? id.hashCode() : 0);return hash;}@Overridepublic boolean equals(Object object) {// TODO: Warning - this method won't work in the case the id fields are not setif (!(object instanceof UserEntity)) {return false;}UserEntity other = (UserEntity) object;if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {return false;}return true;}@Overridepublic String toString() {return 'org.intan.pedigree.form.User[id=' + id + ']';}}
package org.intan.pedigree.form;import java.io.Serializable;import java.util.Collection;import javax.persistence.Basic;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.ManyToMany;import javax.persistence.NamedQueries;import javax.persistence.NamedQuery;import javax.persistence.Table;/**** @author intan*/@Entity@Table(name = 'security_role', catalog = 'mydb', schema = '')@NamedQueries({@NamedQuery(name = 'SecurityRoleEntity.findAll', query = 'SELECT s FROM SecurityRoleEntity s'),@NamedQuery(name = 'SecurityRoleEntity.findById', query = 'SELECT s FROM SecurityRoleEntity s WHERE s.id = :id'),@NamedQuery(name = 'SecurityRoleEntity.findByName', query = 'SELECT s FROM SecurityRoleEntity s WHERE s.name = :name')})public class SecurityRoleEntity implements Serializable {private static final long serialVersionUID = 1L;@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Basic(optional = false)@Column(name = 'id')private Integer id;@Column(name = 'name')private String name;@ManyToMany(mappedBy = 'securityRoleCollection')private Collection userCollection;public SecurityRoleEntity() {}public SecurityRoleEntity(Integer id) {this.id = id;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Collection getUserCollection() {return userCollection;}public void setUserCollection(Collection userCollection) {this.userCollection = userCollection;}@Overridepublic int hashCode() {int hash = 0;hash += (id != null ? id.hashCode() : 0);return hash;}@Overridepublic boolean equals(Object object) {// TODO: Warning - this method won't work in the case the id fields are not setif (!(object instanceof SecurityRoleEntity)) {return false;}SecurityRoleEntity other = (SecurityRoleEntity) object;if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {return false;}return true;}@Overridepublic String toString() {return 'org.intan.pedigree.form.SecurityRole[id=' + id + ']';}}

现在我们已经有了DTO,让我们创建必要的DAO类:

package org.intan.pedigree.dao;import java.util.List;import java.util.Set;import org.hibernate.SessionFactory;import org.intan.pedigree.form.SecurityRoleEntity;import org.intan.pedigree.form.UserEntity;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Repository;@Repositorypublic class UserEntityDAOImpl implements UserEntityDAO{@Autowiredprivate SessionFactory sessionFactory;public void addUser(UserEntity user) {try {sessionFactory.getCurrentSession().save(user);} catch (Exception e) {System.out.println(e);}}public UserEntity findByName(String username) {UserEntity user = (UserEntity) sessionFactory.getCurrentSession().createQuery('select u from UserEntity u where u.username = '' + username + ''').uniqueResult();return user;}public UserEntity getUserByID(Integer id) {UserEntity user = (UserEntity) sessionFactory.getCurrentSession().createQuery('select u from UserEntity u where id = '' + id + ''').uniqueResult();return user;}public String activateUser(Integer id) {String hql = 'update UserEntityset active = :active where id = :id';org.hibernate.Query query = sessionFactory.getCurrentSession().createQuery(hql);query.setString('active','Y');query.setInteger('id',id);int rowCount = query.executeUpdate();System.out.println('Rows affected: ' + rowCount);return '';}public String disableUser(Integer id) {String hql = 'update UserEntity set active = :active where id = :id';org.hibernate.Query query = sessionFactory.getCurrentSession().createQuery(hql);query.setInteger('active',0);query.setInteger('id',id);int rowCount = query.executeUpdate();System.out.println('Rows affected: ' + rowCount);return '';}public void updateUser(UserEntity user) {try {sessionFactory.getCurrentSession().update(user);} catch (Exception e) {System.out.println(e);}}public List listUser() {return sessionFactory.getCurrentSession().createQuery('from UserEntity').list();}public void removeUser(Integer id) {UserEntity user = (UserEntity) sessionFactory.getCurrentSession().load(UserEntity.class, id);if (null != user) {sessionFactory.getCurrentSession().delete(user);}}public Set getSecurityRolesForUsername(String username) {UserEntity user = (UserEntity) sessionFactory.getCurrentSession().createQuery('select u from UserEntity u where u.username = '' + username + ''').uniqueResult();if (user!= null) {Set roles = (Set) user.getSecurityRoleCollection();if (roles != null && roles.size() > 0) {return roles;}}return null;}}
package org.intan.pedigree.dao;import java.util.List;import org.hibernate.Criteria;import org.hibernate.SessionFactory;import org.hibernate.criterion.Restrictions;import org.intan.pedigree.form.Country;import org.intan.pedigree.form.Kennel;import org.intan.pedigree.form.SecurityRoleEntity;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Repository;@Repositorypublic class SecurityRoleEntityDAOImpl implements SecurityRoleEntityDAO{@Autowiredprivate SessionFactory sessionFactory;public void addSecurityRoleEntity(SecurityRoleEntity securityRoleEntity) {try {sessionFactory.getCurrentSession().save(securityRoleEntity);} catch (Exception e) {System.out.println(e);}}public List listSecurityRoleEntity() {Criteria criteria = sessionFactory.getCurrentSession().createCriteria(SecurityRoleEntity.class);criteria.add(Restrictions.ne('name','ROLE_ADMIN' ));return criteria.list();}public SecurityRoleEntity getSecurityRoleEntityById(Integer id) {Criteria criteria = sessionFactory.getCurrentSession().createCriteria(SecurityRoleEntity.class);criteria.add(Restrictions.eq('id',id));return (SecurityRoleEntity) criteria.uniqueResult();}public void removeSecurityRoleEntity(Integer id) {SecurityRoleEntity securityRoleEntity = (SecurityRoleEntity) sessionFactory.getCurrentSession().load(SecurityRoleEntity.class, id);if (null != securityRoleEntity) {sessionFactory.getCurrentSession().delete(securityRoleEntity);}}}

现在,我们将为上述DAO创建服务层。

package org.intan.pedigree.service;import java.util.List;import org.intan.pedigree.dao.SecurityRoleEntityDAO;import org.intan.pedigree.form.SecurityRoleEntity;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;@Servicepublic class SecurityRoleEntityServiceImpl implements SecurityRoleEntityService{@Autowiredprivate SecurityRoleEntityDAO securityRoleEntityDAO;@Transactionalpublic void addSecurityRoleEntity(SecurityRoleEntity securityRoleEntity) {securityRoleEntityDAO.addSecurityRoleEntity(securityRoleEntity);}@Transactionalpublic List listSecurityRoleEntity() {return securityRoleEntityDAO.listSecurityRoleEntity();}@Transactionalpublic void removeSecurityRoleEntity(Integer id) {securityRoleEntityDAO.removeSecurityRoleEntity(id);}@Transactionalpublic SecurityRoleEntity getSecurityRoleEntityById(Integer id) {return securityRoleEntityDAO.getSecurityRoleEntityById( id);}}

在下面的UserDetails的服务层中,请注意它是从org.springframework.security.core.userdetails.UserDetailsS​​ervice实现UserDetailsS​​ervice的。

package org.intan.pedigree.service;import org.intan.pedigree.dao.UserEntityDAO;import org.intan.pedigree.dao.UserEntityDAO;import org.intan.pedigree.form.UserEntity;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.dao.DataAccessException;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;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;@Service('userDetailsService')public class UserDetailsServiceImpl implements UserDetailsService {@Autowiredprivate UserEntityDAO dao;@Autowiredprivate Assembler assembler;@Transactional(readOnly = true)public UserDetails loadUserByUsername(String username)throws UsernameNotFoundException, DataAccessException {UserDetails userDetails = null;UserEntity userEntity = dao.findByName(username);if (userEntity == null)throw new UsernameNotFoundException('user not found');return assembler.buildUserFromUserEntity(userEntity);}}

您还在上面看到,loadUserByUsername方法返回assembler.buildUserFromUserEntity的结果。 简而言之,汇编程序的这种方法是从给定的UserEntity DTO构造一个org.springframework.security.core.userdetails.User对象。 下面给出了Assembler类的代码:

package org.intan.pedigree.service;import java.util.ArrayList;import java.util.Collection;import org.intan.pedigree.form.SecurityRoleEntity;import org.intan.pedigree.form.UserEntity;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.GrantedAuthorityImpl;import org.springframework.security.core.userdetails.User;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;@Service('assembler')public class Assembler {@Transactional(readOnly = true)User buildUserFromUserEntity(UserEntity userEntity) {String username = userEntity.getUsername();String password = userEntity.getPassword();boolean enabled = userEntity.getActive();boolean accountNonExpired = userEntity.getActive();boolean credentialsNonExpired = userEntity.getActive();boolean accountNonLocked = userEntity.getActive();Collection authorities = new ArrayList();for (SecurityRoleEntity role : userEntity.getSecurityRoleCollection()) {authorities.add(new GrantedAuthorityImpl(role.getName()));}User user = new User(username, password, enabled,accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);return user;}}

现在剩下要做的唯一事情就是定义applicationContext-Security.xml中必需的内容。 为此,创建一个具有以下内容的名为“ applicationContext-Security.xml”的新xml文件:

<?xml version='1.0' encoding='UTF-8'?>
<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'xmlns:context='http://www.springframework.org/schema/context'xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd'><beans:bean id='userDetailsService' class='org.intan.pedigree.service.UserDetailsServiceImpl'></beans:bean><context:component-scan base-package='org.intan.pedigree' /><http auto-config='true'><intercept-url pattern='/admin/**' access='ROLE_ADMIN' /><intercept-url pattern='/user/**' access='ROLE_REGISTERED_USER' /><intercept-url pattern='/kennel/**' access='ROLE_KENNEL_OWNER' /><!-- <security:intercept-url pattern='/login.jsp' access='IS_AUTHENTICATED_ANONYMOUSLY' />  --></http><beans:bean id='daoAuthenticationProvider'class='org.springframework.security.authentication.dao.DaoAuthenticationProvider'><beans:property name='userDetailsService' ref='userDetailsService' /></beans:bean><beans:bean id='authenticationManager'class='org.springframework.security.authentication.ProviderManager'><beans:property name='providers'><beans:list><beans:ref local='daoAuthenticationProvider' /></beans:list></beans:property></beans:bean><authentication-manager><authentication-provider user-service-ref='userDetailsService'><password-encoder hash='plaintext' /></authentication-provider></authentication-manager></beans:beans>

在您的web.xml中放入以下代码,以加载applicationContext-security.xml文件。

<context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/applicationContext-hibernate.xml/WEB-INF/applicationContext-security.xml</param-value></context-param>

最后,请原谅任何输入错误等,因为此代码只是从我完成的个人工作中复制和粘贴的内容,如果某些操作不起作用,请提出问题,我们将非常乐意为您提供帮助。

参考: Spring 3,Spring Security在Giannisapi博客上与我们的JCG合作伙伴 Ioannis Dadis 一起使用Hibernate实现自定义用户 详细信息 。

翻译自: https://www.javacodegeeks.com/2012/08/spring-security-implementing-custom.html

Spring Security使用Hibernate实现自定义UserDetails相关推荐

  1. 实现userdetails_Spring Security使用Hibernate实现自定义UserDetails

    实现userdetails 大多数时候,我们将要在Web应用程序中配置我们自己的安全访问角色. 这在Spring Security中很容易实现. 在本文中,我们将看到最简单的方法. 首先,我们将在数据 ...

  2. Spring Security 实战干货:自定义配置类入口 WebSecurityConfigurerAdapter

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 1. 前言 今天我们要进一步的的学习如何自定义配置 Sp ...

  3. Spring Security 实战干货:自定义异常处理

    Spring Security 实战干货:自定义异常处理 转自:https://www.cnblogs.com/felordcn/p/12142514.html 文章目录 1. 前言 2. Sprin ...

  4. Spring Security 进阶干货:自定义配置类入口WebSecurityConfigurerAdapter

    1. 前言 今天我们要进一步的的学习如何自定义配置 Spring Security 我们已经多次提到了 WebSecurityConfigurerAdapter ,而且我们知道 Spring Boot ...

  5. 看清spring security 认证流程,自定义认证方式

    一.文献参考 Spring Security认证与授权的原理(源码分析,超详细)_Zystem-CSDN博客_springsecurity认证原理 spring security为什么这么复杂? - ...

  6. 【Spring Security】五、自定义过滤器

    在之前的几篇security教程中,资源和所对应的权限都是在xml中进行配置的,也就在http标签中配置intercept-url,试想要是配置的对象不多,那还好,但是平常实际开发中都往往是非常多的资 ...

  7. Spring Security——SessionManagement中InvalidSessionStrategy自定义——简单跳过Fitter过滤刷新Session

    需求分析 解决方案 创建一个新的Session,并且重定向到原请求地址. /*** @author ShenTuZhiGang* @version 1.0.0* @date 2021-02-16 21 ...

  8. Spring Security 实战:实现自定义退出登录

    1. 前言 上一篇对 Spring Security 所有内置的 Filter 进行了介绍.今天我们来实战如何安全退出应用程序. 2. 我们使用 Spring Security 登录后都做了什么 这个 ...

  9. Spring MVC 4 + Spring Security 4 + Hibernate +JPA实战

    最近花了有三个星期把spring实战学了遍,同时也把maven,git,Hibernate给用上了,确实比较锻炼手.登陆,注册(我前端不是很好)是网上找得模版,(提前说下界面做的很挫,是用来练手的,还 ...

最新文章

  1. 微软nni_实践空间站 | 为微软官方开源项目贡献代码,你准备好了吗?
  2. Kubernetes安全之鉴权
  3. 服务器管理器运行添加角色向导,Windows Server 2008 服务器角色的添加与管理
  4. 【Tomcat】Tomcat配置与优化(内存、并发、管理)【自己配置】
  5. centos linux 内核升级,Centos系统的升级及Linux 内核升级
  6. Background-size完美兼容IE
  7. 从hadoop-0.20.2升级到hadoop-1.0.3
  8. 突然!华为P30 Pro真机上手视频曝光:屏幕指纹解锁秒开
  9. UIViewController的生命周期
  10. 7个免费的在线音频编辑网站推荐
  11. matlab 动态优化,基于Matlab的测控系统动态性能优化与仿真
  12. 港科夜闻|香港科大(广州)熊辉教授获委任为协理副校长(知识转移)
  13. Java 中代码优化的 30 个小技巧(下)
  14. 《菜菜的机器学习sklearn课堂(2),Java编程百度云
  15. Hive常用库表操作及知识汇总
  16. 文件拖到ads快捷方式打不开
  17. python三大器_python三大器(装饰器/生成器/迭代器)
  18. 【线程基础】多个线程,顺序输出
  19. 2012年全国通信行业职业水平考试结束
  20. 2021中行校招面试

热门文章

  1. maven项目 报错 java.lang.ClassNotFoundException: org.springframework.web.filter.HiddenHttpMethodFilter
  2. kafka mirror_SSL Kafka经纪人从Kafka Mirror Maker迁移到Brooklin的挑战
  3. neo4j 关系属性_Neo4j:特定关系与一般关系+属性
  4. java 程序增加 防盗_防盗Java EE –保护Java EE企业应用程序的安全
  5. jax-rs jax-ws_JAX-RS 2.x与Spring MVC:返回对象列表的XML表示
  6. spring 项目集成配置_Spring重试–与项目集成的方式
  7. jsr303自定义验证_JSR 310新日期/时间API的自定义JSR 303 Bean验证约束
  8. javabeans_(单元测试)JavaBeans的技巧
  9. java字节码_好的,每个接触Java字节码的人
  10. 带有Spring Cloud Config和JHipster的Java微服务