使用 Hibernate、Spring 和 JDBC 配置 SSL 证书

Posted

技术标签:

【中文标题】使用 Hibernate、Spring 和 JDBC 配置 SSL 证书【英文标题】:Configure SSL certificates with Hibernate, Spring and JDBC 【发布时间】:2013-09-08 01:47:35 【问题描述】:

我正在尝试从使用用户名和密码登录到我的 mysql 数据库服务器的未加密 JDBC 连接转移到使用 SSL 和基于证书的身份验证的连接。我正在使用带有 Spring MVC 的 Hibernate。我的 WebAppConfig 文件如下所示:

package com.****.PolicyManager.init;

import java.util.Properties;

import javax.annotation.Resource;
import javax.sql.DataSource;

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;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

@Configuration
@ComponentScan("com.sprhib")
@EnableWebMvc
@EnableTransactionManagement
@PropertySource("classpath:application.properties")
public class WebAppConfig 


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

    @Resource
    private Environment env;

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

    @Bean
    public LocalSessionFactoryBean sessionFactory() 
        LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
        sessionFactoryBean.setDataSource(dataSource());
        sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(
                PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
        sessionFactoryBean.setHibernateProperties(hibProperties());
        return sessionFactoryBean;
    

    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 HibernateTransactionManager transactionManager() 
        HibernateTransactionManager transactionManager = 
                new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory().getObject());
        return transactionManager;
    

    @Bean
    public UrlBasedViewResolver setupViewResolver() 
        UrlBasedViewResolver resolver = new UrlBasedViewResolver();
        resolver.setPrefix("/WEB-INF/pages/");
        resolver.setSuffix(".jsp");
        resolver.setViewClass(JstlView.class);
        return resolver;
    


我的属性配置文件(application.properties)如下:

#DB properties:
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/PolicyManager
db.urlSSL=jdbc:mysql://localhost:3306/PolicyManager?autoReconnect=true&verifyServerCertificate=false&useSSL=true&requireSSL=true
db.username=myuser
db.password=mypass

#Hibernate Configuration:
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.show_sql=true
entitymanager.packages.to.scan=com.****.PolicyManager.model

我已经在 /etc/mysql/certs 中生成了正确的证书并编辑了 my.cnf 以指向那个时候,但是在网上找不到任何关于如何配置我的数据库初始化的特定方法以使用证书的信息-基于身份验证,无需将我的数据库用户名和密码以纯文本形式存储在服务器上。

谁能建议一个解决方案或指向一个使用此 WebAppConfig.java 文件(hib 属性、DriverManagerDataSource 和 LocalSessionFactoryBean)进行配置的教程?

【问题讨论】:

您不应该将DriverManagerDataSource 用于生产,它不是连接池,而且速度很慢。您应该使用适当的连接池。 我应该使用什么替代数据源? 一个合适的连接池,如Commons-DBCP 或Tomcat-JDBC。那里有很多。 DriverManagerDataSource 非常适合测试,但不适用于生产,因为您需要一个真正的连接池。 【参考方案1】:

MySQL 指南有information 说明在客户端做什么,this bug 也有一些详细信息。

基本上是通过以下步骤完成的

    使用您的客户证书创建密钥库和信任库 配置您的环境(或 MysqlDataSource)以使用这些密钥库和信任库 正确配置连接 URL(您显然已经这样做了)。

应该就是这样。关键是在客户端拥有正确的证书。

更多信息:

    Secure JDBC connection to MySQL from GlassFish Secure JDBC connection to MySQL from Java MySQL SSL Documentation

【讨论】:

以上是关于使用 Hibernate、Spring 和 JDBC 配置 SSL 证书的主要内容,如果未能解决你的问题,请参考以下文章

hibernate初探之接口说明,session使用

hibernate4使用原生jdbc进行批处理

JDBC-Mybatis-Hibernate

使用 Hibernate + Spring 进行缓存 - 一些问题

在Spring中使用Hibernate 4

Spring和Hibernate的注解整合 hibernate3和hibernate4/5的区别