前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Spring Security 4 Hibernate整合 注解和xml例子(带源码)

Spring Security 4 Hibernate整合 注解和xml例子(带源码)

作者头像
明明如月学长
发布于 2021-08-27 07:20:05
发布于 2021-08-27 07:20:05
1.1K00
代码可运行
举报
运行总次数:0
代码可运行

【相关已翻译的本系列其他文章,点击分类里面的spring security 4】

【 翻译by 明明如月 QQ 605283073】

上一篇文章:Spring Security 4 基于角色的登录例子(带源码)

下一篇文章:Spring Security 4 整合Hibernate Bcrypt密码加密(带源码)

原文地址: http://websystique.com/spring-security/spring-security-4-hibernate-annotation-example/

本教程通过注解和xml两种方式在Spring 4 MVC应用中,整合 Hibernate和Spring Security 4实现权限验证。

前面的文章都是in-memory authentication(基于内存的权限验证) 。

但是在实际的项目中证书都保存在数据库中或者LDAP中。本文将实现一个完整的 Spring security 和Hibernate整合实现权限验证。

和以前的内存式验证有何不同?

仅仅是验证方法本身发生了变化。

下面是以前的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("bill").password("abc123").roles("USER");
        auth.inMemoryAuthentication().withUser("admin").password("root123").roles("ADMIN");
        auth.inMemoryAuthentication().withUser("dba").password("root123").roles("ADMIN","DBA");
    }
...
...

将被下面的 database authentication(基于数据库的校验)所替换

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
    @Autowired
    @Qualifier("customUserDetailsService")
    UserDetailsService userDetailsService;
     
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

所有的证书都存在数据库中,将通过 Spring Security 中的

org.springframework.security.core.userdetails.UserDetailsService类实访问控制。

我们提供一个UserDetailsService实现,使用userService 来实现数据库访问。

其他的配置参考以前的文章。

下面是完整的实例代码。我们实现了分层方便管理。

-----------------------

涉及的技术和软件:

  • Spring 4.1.6.RELEASE
  • Spring Security 4.0.1.RELEASE
  • Hibernate 4.3.6.Final
  • MySQL Server 5.6
  • Maven 3
  • JDK 1.7
  • Tomcat 8.0.21
  • Eclipse JUNO Service Release 2

让我开始吧

第1步: 项目文件目录结构

下面是最终的项目目录结构

现在让我为你展示上面目录结构里面的内容和每个的详细介绍。

第2步: 更新 pom.xml 包含所需的依赖

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  4.0.0
 
  com.websystique.springsecurity
  SpringSecurityHibernateAnnotationExample
  1.0.0
  war
 
  SpringSecurityHibernateAnnotationExample
   
    
        4.1.6.RELEASE
        4.0.1.RELEASE
        4.3.6.Final
        5.1.31
    
 
    
     
        
        
            org.springframework
            spring-core
            ${springframework.version}
        
        
            org.springframework
            spring-web
            ${springframework.version}
        
        
            org.springframework
            spring-webmvc
            ${springframework.version}
        
        
            org.springframework
            spring-tx
            ${springframework.version}
        
        
            org.springframework
            spring-orm
            ${springframework.version}
        
         
 
        
        
            org.springframework.security
            spring-security-web
            ${springsecurity.version}
        
        
            org.springframework.security
            spring-security-config
            ${springsecurity.version}
        
 
        
        
            org.hibernate
            hibernate-core
            ${hibernate.version}
        
 
        
        
            mysql
            mysql-connector-java
            ${mysql.connector.version}
        
 
        
            javax.servlet
            javax.servlet-api
            3.1.0
        
        
            javax.servlet.jsp
            javax.servlet.jsp-api
            2.3.1
        
        
            javax.servlet
            jstl
            1.2
        
    
 
    
        
            
                
                    org.apache.maven.plugins
                    maven-compiler-plugin
                    3.2
                    
                        1.7
                        1.7
                    
                
                
                    org.apache.maven.plugins
                    maven-war-plugin
                    2.4
                    
                        src/main/webapp
                        SpringSecurityHibernateAnnotationExample
                        false
                    
                
            
        
        SpringSecurityHibernateAnnotationExample

Security 部分

------------------------------------------

第3步: 添加 Spring Security 配置类

添加spring security到我们应用中第一步是要创建Spring Security Java 配置类。

这个配置创建一个叫springSecurityFilterChain的Servlet过滤器,来对我们应用中所有的安全相关的事项(保护应用的所有url,验证用户名密码,表单重定向等)负责。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.configuration;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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;
 
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
    @Autowired
    @Qualifier("customUserDetailsService")
    UserDetailsService userDetailsService;
     
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }
     
    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http.authorizeRequests()
        .antMatchers("/", "/home").permitAll()
        .antMatchers("/admin/**").access("hasRole('ADMIN')")
        .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
        .and().formLogin().loginPage("/login")
        .usernameParameter("ssoId").passwordParameter("password")
        .and().csrf()
        .and().exceptionHandling().accessDeniedPage("/Access_Denied");
    }
}

正如前面提到的最为的变化是:由基于内存的权限验证变为 database authentication(基于数据库的校验)。

上面的配置对应的xml配置如下:

代码语言:javascript
代码运行次数:0
运行
复制
第4步: 注册springSecurityFilter

下面是定制初始化war包中的 springSecurityFilter(第三步中的) 注册类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.configuration;
 
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
 
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
 
}

上面配置对应的xml配置如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    springSecurityFilterChain
    org.springframework.web.filter.DelegatingFilterProxy

 

    springSecurityFilterChain
    /*
第 5步:定义 UserDetailsService 的实现

此service为 Authentication Manager(验证管理器)提供验证详情。

它实现了Spring的UserDetailsService接口只包含loadUserByUsername一个方法。

获取用户名[本例中是ssoId 然后返回一个 org.springframework.security.core.userdetails.User对象

我们将在UserService 中通过UserDao对象来获取。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.service;
 
import java.util.ArrayList;
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.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.websystique.springsecurity.model.User;
import com.websystique.springsecurity.model.UserProfile;
 
@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService{
 
    @Autowired
    private UserService userService;
     
    @Transactional(readOnly=true)
    public UserDetails loadUserByUsername(String ssoId)
            throws UsernameNotFoundException {
        User user = userService.findBySso(ssoId);
        System.out.println("User : "+user);
        if(user==null){
            System.out.println("User not found");
            throw new UsernameNotFoundException("Username not found");
        }
            return new org.springframework.security.core.userdetails.User(user.getSsoId(), user.getPassword(), 
                 user.getState().equals("Active"), true, true, true, getGrantedAuthorities(user));
    }
 
     
    private List getGrantedAuthorities(User user){
        List authorities = new ArrayList();
         
        for(UserProfile userProfile : user.getUserProfiles()){
            System.out.println("UserProfile : "+userProfile);
            authorities.add(new SimpleGrantedAuthority("ROLE_"+userProfile.getType()));
        }
        System.out.print("authorities :"+authorities);
        return authorities;
    }
     
}

SpringMVC 部分

------------------------------------------------------

第6步: 添加 Controller(控制器)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.controller;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
 
@Controller
public class HelloWorldController {
 
     
    @RequestMapping(value = { "/", "/home" }, method = RequestMethod.GET)
    public String homePage(ModelMap model) {
        model.addAttribute("greeting", "Hi, Welcome to mysite");
        return "welcome";
    }
 
    @RequestMapping(value = "/admin", method = RequestMethod.GET)
    public String adminPage(ModelMap model) {
        model.addAttribute("user", getPrincipal());
        return "admin";
    }
 
    @RequestMapping(value = "/db", method = RequestMethod.GET)
    public String dbaPage(ModelMap model) {
        model.addAttribute("user", getPrincipal());
        return "dba";
    }
 
    @RequestMapping(value = "/Access_Denied", method = RequestMethod.GET)
    public String accessDeniedPage(ModelMap model) {
        model.addAttribute("user", getPrincipal());
        return "accessDenied";
    }
 
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String loginPage() {
        return "login";
    }
 
    @RequestMapping(value="/logout", method = RequestMethod.GET)
    public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null){    
            new SecurityContextLogoutHandler().logout(request, response, auth);
        }
        return "redirect:/login?logout";
    }
 
    private String getPrincipal(){
        String userName = null;
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
 
        if (principal instanceof UserDetails) {
            userName = ((UserDetails)principal).getUsername();
        } else {
            userName = principal.toString();
        }
        return userName;
    }
 
 
}
第7步: 添加 SpringMVC 配置类
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.configuration;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
 
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.websystique.springsecurity")
public class HelloWorldConfiguration extends WebMvcConfigurerAdapter {
     
    @Bean(name="HelloWorld")
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");
 
        return viewResolver;
    }
 
    /*
     * Configure ResourceHandlers to serve static resources like CSS/ Javascript etc...
     *
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("/static/");
    }
}

---------译者增加 start---明明如月-------- 以上配置对应的xml配置如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /static/**" location="/static/" />

---------译者增加end---明明如月--------

第8步: 添加Initializer(初始化器)类
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.configuration;
 
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
 
public class SpringMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
 
    @Override
    protected Class[] getRootConfigClasses() {
        return new Class[] { HelloWorldConfiguration.class };
    }
  
    @Override
    protected Class[] getServletConfigClasses() {
        return null;
    }
  
    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
 
}

DAO, Model & Service部分

-------------------------------------------------------------------------

第9步:创建 Model(模型)类

一个用户可以有多种角色 [DBA,ADMIN,USER],一个角色也可以被分配给多个用户。

因此在UserProfile[role] 和User之间,这里有Many-To-Many 关系映射。

我们保持的是单向映射即[User 对UserProfile],

因为我们主要关心通过给定的用户查找角色。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.model;
 
import java.util.HashSet;
import java.util.Set;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
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.Table;
 
@Entity
@Table(name="APP_USER")
public class User {
 
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
 
    @Column(name="SSO_ID", unique=true, nullable=false)
    private String ssoId;
     
    @Column(name="PASSWORD", nullable=false)
    private String password;
         
    @Column(name="FIRST_NAME", nullable=false)
    private String firstName;
 
    @Column(name="LAST_NAME", nullable=false)
    private String lastName;
 
    @Column(name="EMAIL", nullable=false)
    private String email;
 
    @Column(name="STATE", nullable=false)
    private String state=State.ACTIVE.getState();
 
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "APP_USER_USER_PROFILE", 
             joinColumns = { @JoinColumn(name = "USER_ID") }, 
             inverseJoinColumns = { @JoinColumn(name = "USER_PROFILE_ID") })
    private Set userProfiles = new HashSet();
 
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
    public String getSsoId() {
        return ssoId;
    }
 
    public void setSsoId(String ssoId) {
        this.ssoId = ssoId;
    }
 
    public String getPassword() {
        return password;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
 
    public String getFirstName() {
        return firstName;
    }
 
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
 
    public String getLastName() {
        return lastName;
    }
 
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
 
    public String getEmail() {
        return email;
    }
 
    public void setEmail(String email) {
        this.email = email;
    }
 
    public String getState() {
        return state;
    }
 
    public void setState(String state) {
        this.state = state;
    }
 
    public Set getUserProfiles() {
        return userProfiles;
    }
 
    public void setUserProfiles(Set userProfiles) {
        this.userProfiles = userProfiles;
    }
 
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        result = prime * result + ((ssoId == null) ? 0 : ssoId.hashCode());
        return result;
    }
 
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof User))
            return false;
        User other = (User) obj;
        if (id != other.id)
            return false;
        if (ssoId == null) {
            if (other.ssoId != null)
                return false;
        } else if (!ssoId.equals(other.ssoId))
            return false;
        return true;
    }
 
    @Override
    public String toString() {
        return "User [id=" + id + ", ssoId=" + ssoId + ", password=" + password
                + ", firstName=" + firstName + ", lastName=" + lastName
                + ", email=" + email + ", state=" + state + ", userProfiles=" + userProfiles +"]";
    }
 
     
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.model;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
 
@Entity
@Table(name="USER_PROFILE")
public class UserProfile {
 
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id; 
 
    @Column(name="TYPE", length=15, unique=true, nullable=false)
    private String type = UserProfileType.USER.getUserProfileType();
     
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
    public String getType() {
        return type;
    }
 
    public void setType(String type) {
        this.type = type;
    }
 
 
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        result = prime * result + ((type == null) ? 0 : type.hashCode());
        return result;
    }
 
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof UserProfile))
            return false;
        UserProfile other = (UserProfile) obj;
        if (id != other.id)
            return false;
        if (type == null) {
            if (other.type != null)
                return false;
        } else if (!type.equals(other.type))
            return false;
        return true;
    }
 
    @Override
    public String toString() {
        return "UserProfile [id=" + id + ",  type=" + type  + "]";
    }
     
 
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.model;
 
public enum UserProfileType {
    USER("USER"),
    DBA("DBA"),
    ADMIN("ADMIN");
     
    String userProfileType;
     
    private UserProfileType(String userProfileType){
        this.userProfileType = userProfileType;
    }
     
    public String getUserProfileType(){
        return userProfileType;
    }
     
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.model;
 
public enum State {
 
    ACTIVE("Active"),
    INACTIVE("Inactive"),
    DELETED("Deleted"),
    LOCKED("Locked");
     
    private String state;
     
    private State(final String state){
        this.state = state;
    }
     
    public String getState(){
        return this.state;
    }
 
    @Override
    public String toString(){
        return this.state;
    }
 
    public String getName(){
        return this.name();
    }
 
 
}
第10步:创建Dao层
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.dao;
 
import java.io.Serializable;
 
import java.lang.reflect.ParameterizedType;
 
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
 
public abstract class AbstractDao {
     
    private final Class persistentClass;
     
    @SuppressWarnings("unchecked")
    public AbstractDao(){
        this.persistentClass =(Class) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
    }
     
    @Autowired
    private SessionFactory sessionFactory;
 
    protected Session getSession(){
        return sessionFactory.getCurrentSession();
    }
 
    @SuppressWarnings("unchecked")
    public T getByKey(PK key) {
        return (T) getSession().get(persistentClass, key);
    }
 
    public void persist(T entity) {
        getSession().persist(entity);
    }
 
    public void delete(T entity) {
        getSession().delete(entity);
    }
     
    protected Criteria createEntityCriteria(){
        return getSession().createCriteria(persistentClass);
    }
 
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.dao;
 
import com.websystique.springsecurity.model.User;
 
public interface UserDao {
 
    User findById(int id);
     
    User findBySSO(String sso);
     
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.dao;
 
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
 
import com.websystique.springsecurity.model.User;
 
@Repository("userDao")
public class UserDaoImpl extends AbstractDao implements UserDao {
 
    public User findById(int id) {
        return getByKey(id);
    }
 
    public User findBySSO(String sso) {
        Criteria crit = createEntityCriteria();
        crit.add(Restrictions.eq("ssoId", sso));
        return (User) crit.uniqueResult();
    }
 
     
}
第11步:创建Service层
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.service;
 
import com.websystique.springsecurity.model.User;
 
public interface UserService {
 
    User findById(int id);
     
    User findBySso(String sso);
     
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.service;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import com.websystique.springsecurity.dao.UserDao;
import com.websystique.springsecurity.model.User;
 
@Service("userService")
@Transactional
public class UserServiceImpl implements UserService{
 
    @Autowired
    private UserDao dao;
 
    public User findById(int id) {
        return dao.findById(id);
    }
 
    public User findBySso(String sso) {
        return dao.findBySSO(sso);
    }
 
}

Hibernate配置部分

-------------------------------------

hibernate配置类添加 @Bean对DataSource配置的方法以及SessionFactory & Transaction Manager上。

数据源属性从application.properties文件获取,其中也包含连接mysql 数据库的链接等。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.websystique.springsecurity.configuration;
 
import java.util.Properties;
 
import javax.sql.DataSource;
 
import org.hibernate.SessionFactory;
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.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
 
@Configuration
@EnableTransactionManagement
@ComponentScan({ "com.websystique.springsecurity.configuration" })
@PropertySource(value = { "classpath:application.properties" })
public class HibernateConfiguration {
 
    @Autowired
    private Environment environment;
 
    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan(new String[] { "com.websystique.springsecurity.model" });
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
     }
     
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
        dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
        dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
        dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
        return dataSource;
    }
     
    private Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
        properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
        properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
        return properties;        
    }
     
    @Bean
    @Autowired
    public HibernateTransactionManager transactionManager(SessionFactory s) {
       HibernateTransactionManager txManager = new HibernateTransactionManager();
       txManager.setSessionFactory(s);
       return txManager;
    }
}

application.properties

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/websystique
jdbc.username = myuser
jdbc.password = mypassword
hibernate.dialect = org.hibernate.dialect.MySQLDialect
hibernate.show_sql = true
hibernate.format_sql = true

Views(视图)部分

---------------------------

第13步: 添加视图

login.jsp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

    
        
        Login page
        
        
        
    
 
    
        
            
                
                    
                        
                        
                            
                                
                                    Invalid username and password.
                                
                            
                            
                                
                                    You have been logged out successfully.

注意:和CSRF 相关的是

代码语言:javascript
代码运行次数:0
运行
复制

这一行的目的是防止CSRF攻击。正如你所见jsp中CSRF参数使用EL表达式获取的。因此需要允许el表达式:

需要在jsp头添加如下一行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<%@ page isELIgnored="false"%>

welcome.jsp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"  pageEncoding="ISO-8859-1"%>


    
    Welcome page


    Greeting : ${greeting}
    This is a welcome page.

admin.jsp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>


    
    Admin page


    Dear ${user}, Welcome to Admin Page.
    ">Logout

dba.jsp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>


    
    DBA page


    Dear ${user}, Welcome to DBA Page.
    ">Logout

accessDenied.jsp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>


    
    AccessDenied page


    Dear ${user}, You are not authorized to access this page
    ">Logout

Database 模式部分

-----------------------------

第14步:创建数据库模式和填充模拟数据
/*All User's are stored in APP_USER table*/ create table APP_USER ( id BIGINT NOT NULL AUTO_INCREMENT, sso_id VARCHAR(30) NOT NULL, password VARCHAR(100) NOT NULL, first_name VARCHAR(30) NOT NULL, last_name VARCHAR(30) NOT NULL, email VARCHAR(30) NOT NULL, state VARCHAR(30) NOT NULL, PRIMARY KEY (id), UNIQUE (sso_id) ); /* USER_PROFILE table contains all possible roles */ create table USER_PROFILE( id BIGINT NOT NULL AUTO_INCREMENT, type VARCHAR(30) NOT NULL, PRIMARY KEY (id), UNIQUE (type) ); /* JOIN TABLE for MANY-TO-MANY relationship*/ CREATE TABLE APP_USER_USER_PROFILE ( user_id BIGINT NOT NULL, user_profile_id BIGINT NOT NULL, PRIMARY KEY (user_id, user_profile_id), CONSTRAINT FK_APP_USER FOREIGN KEY (user_id) REFERENCES APP_USER (id), CONSTRAINT FK_USER_PROFILE FOREIGN KEY (user_profile_id) REFERENCES USER_PROFILE (id) ); /* Populate USER_PROFILE Table */ INSERT INTO USER_PROFILE(type) VALUES ('USER'); INSERT INTO USER_PROFILE(type) VALUES ('ADMIN'); INSERT INTO USER_PROFILE(type) VALUES ('DBA'); /* Populate APP_USER Table */ INSERT INTO APP_USER(sso_id, password, first_name, last_name, email, state) VALUES ('bill','abc123', 'Bill','Watcher','bill@xyz.com', 'Active'); INSERT INTO APP_USER(sso_id, password, first_name, last_name, email, state) VALUES ('danny','abc124', 'Danny','Theys','danny@xyz.com', 'Active'); INSERT INTO APP_USER(sso_id, password, first_name, last_name, email, state) VALUES ('sam','abc125', 'Sam','Smith','samy@xyz.com', 'Active'); INSERT INTO APP_USER(sso_id, password, first_name, last_name, email, state) VALUES ('nicole','abc126', 'Nicole','warner','nicloe@xyz.com', 'Active'); INSERT INTO APP_USER(sso_id, password, first_name, last_name, email, state) VALUES ('kenny','abc127', 'Kenny','Roger','kenny@xyz.com', 'Active'); /* Populate JOIN Table */ INSERT INTO APP_USER_USER_PROFILE (user_id, user_profile_id) SELECT user.id, profile.id FROM app_user user, user_profile profile where user.sso_id='bill' and profile.type='USER'; INSERT INTO APP_USER_USER_PROFILE (user_id, user_profile_id) SELECT user.id, profile.id FROM app_user user, user_profile profile where user.sso_id='danny' and profile.type='USER'; INSERT INTO APP_USER_USER_PROFILE (user_id, user_profile_id) SELECT user.id, profile.id FROM app_user user, user_profile profile where user.sso_id='sam' and profile.type='ADMIN'; INSERT INTO APP_USER_USER_PROFILE (user_id, user_profile_id) SELECT user.id, profile.id FROM app_user user, user_profile profile where user.sso_id='nicole' and profile.type='DBA'; INSERT INTO APP_USER_USER_PROFILE (user_id, user_profile_id) SELECT user.id, profile.id FROM app_user user, user_profile profile where user.sso_id='kenny' and profile.type='ADMIN'; INSERT INTO APP_USER_USER_PROFILE (user_id, user_profile_id) SELECT user.id, profile.id FROM app_user user, user_profile profile where user.sso_id='kenny' and profile.type='DBA';

我们已经创建了 User, UserProfile和关系表

我们填充用户和角色:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Bill,Danny : USER
Sam        : ADMIN
Nicole     : DBA
Kenny      : ADMIN, DBA

此时mysql数据库的截图:

接下来我们启动web应用程序,尝试根据不同用户的不同角色来登录和访问。

第15步:构建和部署应用

现在构建 war 包(通过eclipse或者myeclipse)或者通过maven 命令行(  mvn clean install). 在一个 Servlet 3.0 容器中发布本应用. 在这里我使用的是tomcat, 我将 war 文件放到  tomcat webapps 文件夹然后点击 tomcat安装目录的bin文件夹下的 start.bat .

启动应用 打开浏览器 在地址栏输入localhost:8080/SpringSecurityHibernateAnnotationExample/并回车

localhost:8080/SpringSecurityHibernateAnnotationExample/admin 访问admin界面

将会被转到登录界面

通过USER角色的账户进行登录

提交表单,将到 访问拒绝页面

通过ADMIN 角色的用户登录

提供一个admin权限的证书并登录

访问db  页面

localhost:8080/SpringSecurityHibernateAnnoationExample/db 将出现访问拒绝

通过DBA角色的账户登记即可

本文结束。下一篇文章将介绍Spring Security 4  整合Hibernate基于角色的登录。

代码下载地址:http://websystique.com/?smd_process_download=1&download_id=1408

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016/05/05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
写给开发人员的实用密码学 - 对称加密算法
所谓数据加密,就是将一段数据处理成无规则的数据,除非有关键的密钥,否则谁也无法得知无规则数据的真实含义。
云水木石
2021/01/27
1.3K0
写给开发人员的实用密码学 - 对称加密算法
Android O中对TEE加解密算法的新要求
我们都知道,Android中keystore机制中的keymaster需要在TEE实现。Google关于Android后续版本中keymaster中的加解密算法要求如下: RSA 无填充 RSAES-OAEP (PaddingMode::RSA_OAEP) RSAES-PKCS1-v1_5 (PaddingMode::RSA_PKCS1_1_5_ENCRYPT) SHA-256 RSASSA-PSS (PaddingMode::RSA_PSS) RSASSA-PKCS1-v1_5 (PaddingMode:
安智客
2018/02/24
1.5K0
网络安全&密码学—python中的各种加密算法
数据加密是一种保护数据安全的技术,通过将数据(明文)转换为不易被未经授权的人理解的形式(密文),以防止数据泄露、篡改或滥用。加密后的数据(密文)可以通过解密过程恢复成原始数据(明文)。数据加密的核心是密码学,它是研究密码系统或通信安全的一门学科,包括密码编码学和密码分析学。
小羽网安
2024/07/02
5550
网络安全&密码学—python中的各种加密算法
加密与安全_AES & RSA 密钥对生成及PEM格式的代码实现
在现代信息安全中,加密算法扮演着至关重要的角色。今天我们来聊聊两种常见的加密算法——RSA和AES,用通俗易懂的语言带大家理解它们的核心原理和优缺点。
小小工匠
2024/05/27
7170
JDK安全模块JCE核心Cipher使用详解
javax.crypto.Cipher,翻译为密码,其实叫做密码器更加合适。Cipher是JCA(Java Cryptographic Extension,Java加密扩展)的核心,提供基于多种加解密算法的加解密功能。在不了解Cipher之前,我们在完成一些需要加解密的模块的时候总是需要到处拷贝代码,甚至有些错误的用法也被无数次拷贝,踩坑之后又要拷贝补坑的代码。为什么不尝试理解Cipher然后合理地使用呢?
Throwable
2020/06/23
3.2K0
对称加密算法和分组密码的模式
由于加密出来的数据很可能有很多不可见字符,因此这里会将加密后的结果进行一次Base64Encode。
linjinhe
2018/06/06
2.6K0
30分钟搞定AES系列(上):基础特性
AES是对称加密算法的一种,全称是ADVANCED ENCRYPTION STANDARD。
bowenerchen
2022/11/15
5.5K2
30分钟搞定AES系列(上):基础特性
【密码学】为什么不推荐在对称加密中使用CBC工作模式
这篇文章是我在公司内部分享中一部分内容的详细版本,如标题所言,我会通过文字、代码示例、带你完整的搞懂为什么我们不建议你使用cbc加密模式,用了会导致什么安全问题,即使一定要用需要注意哪些方面的内容。
9eek
2023/05/23
3.2K1
【密码学】为什么不推荐在对称加密中使用CBC工作模式
循序渐进学加密
还记得上初二的那年夏天,班里来了一个新同学,他就住在我家对面的楼里,于是我们一起上学放学,很快便成了最要好的朋友。我们决定发明一套神秘的沟通方式,任何人看到都不可能猜到它的真实含义。我们第一个想到的就是汉语拼音,但很显然光把一个句子变成汉语拼音是不够的,于是我们把26个英文字母用简谱的方式从低音到高音排起来,就得到了一个简单的密码本:
知识与交流
2021/04/02
8920
现代密码学实践指南[2015年]
本文介绍目前现代密码学的最先进技术, 前半部分主要翻译自 《Cryptographic Right Answers》,附上收集的资料,和byron个人的理解。
byronhe
2021/06/25
1.1K0
Android 安全
MD5长度默认是128bit,这样表达不好,所以将二级制转换成16进制,4bit代表一个16进制,所有128/4=32 ,所以为32位16进制。 MD5 16位与32位区别是将32位后面的16位去掉,得到的16位
Yif
2019/12/26
1.1K0
RSA签名的PSS模式
PSS 私钥签名流程的一种填充模式。目前主流的RSA签名包括RSA-PSS和RSA-PKCS#1 v1.5。
mariolu
2018/12/24
9.2K1
简单小结密码学入门知识点
  密码,最初的目的是用于对信息加密,计算机领域的密码技术种类繁多。但随着密码学的运用,密码还被用于身份认证、防止否认等功能上。密码是通信双方按约定的法则进行信息特殊变换的一种重要保密手段。依照这些法则,变明文为密文,称为加密变换;变密文为明文,称为脱密变换。密码在早期仅对文字或数码进行加、脱密变换,随着通信技术的发展,对语音、图像、数据等都可实施加、脱密变换。
步履不停凡
2019/08/23
2.2K0
简单小结密码学入门知识点
java加解密实例
序 本文主要小结一下java里头的AES以及RSA加解密。 AES 使用AES加密时需要几个参数: 密钥长度(Key Size) AES算法下,key的长度有三种:128、192和256 bits。
code4it
2018/09/17
1K0
java加解密实例
对称算法(分组算法) 非对称算法 Hash算法 密码键盘中的常用名称解释 Pinblock: ANSI9.8 算法
解释:pin block,顾名思义就是pin块,密码块的意思,实际上是对pin原文做一定转换后的结果
zhangjiqun
2024/12/16
1490
TLS协议分析 (四) handshake协议概览
TLS 1.3对握手做了大修改,下面先讲TLS 1.2,讲完再介绍一下分析TLS 1.3.
用户8964349
2021/09/07
1.6K0
加密与安全_探索对称加密算法
对称加密算法是一种加密技术,使用相同的密钥来进行加密和解密数据。在这种算法中,发送方使用密钥将明文(未加密的数据)转换为密文(加密的数据),而接收方使用相同的密钥将密文还原为明文。
小小工匠
2024/05/26
2150
加密与安全_探索对称加密算法
斯坦福大学密码学-基于陷门置换的公钥加密 11
注意:G在现实中有一个参数,叫安全参数,指定了这个密钥生成算法将要生成的密钥大小。
Daffy
2020/11/07
2.6K0
【爬虫知识】爬虫常见加密解密算法
本文总结了在爬虫中常见的各种加密算法、编码算法的原理、在 JavaScript 中和 Python 中的基本实现方法,遇到 JS 加密的时候可以快速还原加密过程,有的网站在加密的过程中可能还经过了其他处理,但是大致的方法是一样的。
K哥爬虫
2021/08/03
8.5K0
【爬虫知识】爬虫常见加密解密算法
C++ CryptoPP使用RSA加解密
Crypto++ (CryptoPP) 是一个用于密码学和加密的 C++ 库。它是一个开源项目,提供了大量的密码学算法和功能,包括对称加密、非对称加密、哈希函数、消息认证码 (MAC)、数字签名等。Crypto++ 的目标是提供高性能和可靠的密码学工具,以满足软件开发中对安全性的需求。RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,由三位密码学家Ron Rivest、Adi Shamir和Leonard Adleman于1977年共同提出。RSA算法被广泛应用于信息安全领域,特别是在数字签名和密钥交换等场景中。
王瑞MVP
2023/12/01
1.6K0
C++ CryptoPP使用RSA加解密
推荐阅读
相关推荐
写给开发人员的实用密码学 - 对称加密算法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验