Spring Boot 实现https ssl免密登录(X.509 pki登录)

要让项目实现 ssl 免密登录,首先需要开启 https

所以先从 Spring Boot 如何开启 https 说起。

创建服务端证书

为了开启 https ,我们需要一份证书。

实际开发中,会在网上申请一个机构颁发的证书。这里为了方便,我会使用 openssl 命令自己生成一个证书来使用。

openssl req -x509 -sha256 -days 3650 -newkey rsa:4096 -keyout rootCA.key -out rootCA.crt

所有的密码都是 123456 ,然后根据提示输入相关信息就好,如果嫌麻烦也可以直接回车跳过。

这样我们就得到了证书 rootCA.crt 和私钥 rootCA.key

要在 Spring Boot 中实现服务器端 X.509 身份验证,还需要给我们的服务端也生成一个证书。

openssl req -new -newkey rsa:4096 -keyout localhost.key -out localhost.csr

同样,密码是 123456 ,文件名 localhost 可以自行修改。

接下来就是用 rootCA 给我们的服务端证书做签名了,在此之前,我们先写一个配置文件,里面写有一些基本的配置

vi conf.config

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost

其中 DNS.1 的值就是你的域名,比如 www.segmentfault.comlocalhost 等等。如果这里填错了,访问网站时,浏览器会提示网站不安全。

然后给服务端证书签名,会提示你输入 rootCA 的密码

openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in localhost.csr -out localhost.crt -days 365 -CAcreateserial -extfile conf.config

成功后,让我们查看一下证书的信息

openssl x509 -in localhost.crt -text

最后再将签名证书和私钥打包到 PKCS 文件中

openssl pkcs12 -export -out localhost.p12 -name "localhost" -inkey localhost.key -in localhost.crt

这条指令会要你先输入 localhost.key 的密码,然后再要你定义 localhost.p12 的密码。 localhost.p12 这个密码一定要记住,因为在 Spring 的配置文件中有用到。

另外需要特别注意的是, Spring 配置文件中 server.ssl.keyAlias 的值,就是命令中的 localhost(-name "localhost")

Spring Boot开启https

localhost.p12 复制到 resources 目录下之后编译项目

修改application.properties文件

server.port=8888
server.ssl.key-store=classpath:localhost.p12
server.ssl.key-store-password=123456
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=localhost

chrome://settings/security 中,选择 受信任的根证书颁发机构 导入 rootCA.crt

这时启动项目,就可以使用 https 访问网站了,而且浏览器提示网站时安全的。

创建信托证书

信托证书中会存有 信任的外部实体的证书

这里我们只要将 rootCA.crt 添加进去就可以了

keytool -import -trustcacerts -noprompt -alias ca -ext san=dns:localhost,ip:127.0.0.1 -file rootCA.crt -keystore localhost.jks

然后将 localhost.jks 添加到项目中,并修改配置文件

application.properties添加:

server.ssl.trust-store=classpath:localhost.jks
server.ssl.trust-store-password=123456
server.ssl.client-auth=need

注意:此时由于添加了server.ssl.client-auth=need,因为没有添加个人证书,所以这个时候刷新页面,项目会无法访问,如果想要同时兼任普通登录,可以将need改成want,但是want只会在第一次访问页面时才会向客户索取个人证书

创建客户端证书

现在创建一个客户端的证书,步骤和服务端的差不多一样。

openssl req -new -newkey rsa:4096 -nodes -keyout shurlormes.key -out shurlormes.csr

在生成客户端证书时,那些信息不建议跳过,因为在后续的步骤中,会获取其中的信息用以登录。比如我在 Common Name 处填写的信息,就是等下用来登录的用户名。

接下来用 RootCA 给客户端证书签名

openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in shurlormes.csr -out shurlormes.crt -days 365 -CAcreateserial

然后再将签名证书和私钥打包到 PKCS 文件中

openssl pkcs12 -export -out shurlormes.p12 -name "shurlormes" -inkey shurlormes.key -in shurlormes.crt

最后在 chrome://settings/security 选择 个人证书shurlormes.p12 导入,期间会要你输入它的密码。

这时候刷新页面,浏览器就会弹出一个对话框,让你选择个人认证了。

Spring Boot获取个人证书信息

恭喜你,到了这一步, pki 登录已经完成了 99% 了。接下来就是通过 request 获取证书信息,然后处理字符串,拿到用户名做登录即可。

@RequestMapping("/login")
public String login(HttpServletRequest request) {
  X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
  if(certs != null) {
    X509Certificate gaX509Cert = certs[0];
    String dn = gaX509Cert.getSubjectDN().toString();
    System.out.println("个人证书信息:" + dn);
    String username = "";
    String[] dnArray = dn.split(",");
    for (String dnItem : dnArray) {
      String[] dnInfo = dnItem.split("=");
      String key = dnInfo[0];
      String value = dnInfo[1];
      if("cn".equalsIgnoreCase(key.trim())) {
        username = value;
        break;
      }
    }
    System.out.println("用户名:" + username);

    if(!StringUtils.isEmpty(username)) {
      SecurityContext securityContext = SecurityContextHolder.getContext();
      User userDetails = new User(username, "", Collections.EMPTY_LIST);
      securityContext.setAuthentication(new UsernamePasswordAuthenticationToken(userDetails, "", Collections.EMPTY_LIST));
      return "redirect:/";
    }

  }
  return "login";
}

Spring Boot 同时开启http和https

相信大家都发现了,现在项目只能通过 https 访问,如果用 http 访问浏览器直接返回 Bad request 了。

要同时开启 httpshttp ,只需添加一个 TomcatConfig 就可以

@Configuration
public class TomcatHttpConfig {
  @Bean
  public TomcatServletWebServerFactory servletContainer() {
    TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
    tomcat.addAdditionalTomcatConnectors(initiateHttpConnector());
    return tomcat;
  }

  private Connector initiateHttpConnector() {
    Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
    connector.setScheme("http");
    connector.setPort(9999);
    connector.setSecure(false);
    return connector;
  }
}

这时候启动项目,注意看控制台打印的信息。

说明已经成功启动 http 在端口 9999https8888 ,页面也可以成功访问了。

Spring Boot http自动跳转https

上面我们已经可以同时访问 htt p和 https ,但如果我要访问 http 的时候,自动跳转的 https 呢?

只需要在上面的基础上稍微改改就可以了。

@Configuration
public class TomcatHttpConfig {
  @Bean
  public TomcatServletWebServerFactory servletContainer() {
    TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
      @Override
      protected void postProcessContext(Context context) {
        SecurityConstraint securityConstraint = new SecurityConstraint();
        securityConstraint.setUserConstraint("CONFIDENTIAL");
        SecurityCollection collection = new SecurityCollection();
        collection.addPattern("/*");
        securityConstraint.addCollection(collection);
        context.addConstraint(securityConstraint);
      }
    };
    tomcat.addAdditionalTomcatConnectors(initiateHttpConnector());
    return tomcat;
  }

  private Connector initiateHttpConnector() {
    Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
    connector.setScheme("http");
    connector.setPort(9999);
    connector.setSecure(false);
    connector.setRedirectPort(8888);
    return connector;
  }
}

踩坑总结

  • 把服务端证书p12文件添加到项目resources后,记得rebuild项目,否则target的classes中没有生成证书文件,会导致项目启动失败。
  • application.properties中的server.ssl.keyAlias需要和生成p12文件的-name一致,否则也会导致项目无法启动。
  • 如果要指定域名,需要修改conf.confg中的DNS.1,否则浏览器会提示网站不安全。

代码地址

https://github.com/Shurlormes/pkilogin

参考资料

https://www.baeldung.com/x-509-authentication-in-spring-security

到此这篇关于Spring Boot 实现https ssl免密登录(X.509 pki登录)的文章就介绍到这了,更多相关Spring Boot https ssl免密登录内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springboot实现注册的加密与登录的解密功能(demo)

    前情提要:本demo是基于springboot+mybatis-plus实现加密,加密为主,全局异常处理,日志处理为辅,而登录密码加密是每个项目中必须要的,密码不可能明文存入数据,这样没有安全性. 涉及的功能,全局异常处理,日志处理,mybatis-plus实现与数据库的交互,密码加密,restful风格 涉及的工具:IDEA,postman,sqlyog(navicat) 1. 首先我们直接看效果吧,如果你不满意,也就没必要看了 如果这正是你想要的效果呢,那你可以继续看下面的内容了 2. 首先

  • SpringBoot+Shiro学习之密码加密和登录失败次数限制示例

    这个项目写到现在,基本的雏形出来了,在此感谢一直关注的童鞋,送你们一句最近刚学习的一句鸡汤:念念不忘,必有回响.再贴一张ui图片: 前篇思考问题解决 前篇我们只是完成了同一账户的登录人数限制shiro拦截器的编写,对于手动踢出用户的功能只是说了采用在session域中添加一个key为kickout的布尔值,由之前编写的KickoutSessionControlFilter拦截器来判断是否将用户踢出,还没有说怎么获取当前在线用户的列表的核心代码,下面贴出来: /** * <p> * 服务实现类

  • Spring Boot 实现https ssl免密登录(X.509 pki登录)

    要让项目实现 ssl 免密登录,首先需要开启 https . 所以先从 Spring Boot 如何开启 https 说起. 创建服务端证书 为了开启 https ,我们需要一份证书. 实际开发中,会在网上申请一个机构颁发的证书.这里为了方便,我会使用 openssl 命令自己生成一个证书来使用. openssl req -x509 -sha256 -days 3650 -newkey rsa:4096 -keyout rootCA.key -out rootCA.crt 所有的密码都是 123

  • spring boot 配置HTTPS代码实例

    这篇文章主要介绍了spring boot 配置HTTPS代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 spring boot 版本是<version>1.5.8.RELEASE</version> 1.配置文件里,看下不要有空格=[不要有空格] 2.别名 ================ server.port=8095 server.ssl.key-store=*.pfx server.ssl.key-store-pa

  • Spring Boot + Vue 前后端分离项目如何踢掉已登录用户

    上篇文章中,我们讲了在 Spring Security 中如何踢掉前一个登录用户,或者禁止用户二次登录,通过一个简单的案例,实现了我们想要的效果. 但是有一个不太完美的地方,就是我们的用户是配置在内存中的用户,我们没有将用户放到数据库中去.正常情况下,松哥在 Spring Security 系列中讲的其他配置,大家只需要参考Spring Security+Spring Data Jpa 强强联手,安全管理只有更简单!一文,将数据切换为数据库中的数据即可. 本文是本系列的第十三篇,阅读前面文章有助

  • Spring Boot支持HTTPS步骤详解

    Spring Boot中启动HTTPS 如果你使用Spring Boot,并且想在内嵌tomcat中添加HTTPS,需要有一个证书. 两种方式 自己通过keytool生成 通过证书授权机构购买 这里采用第一种方式,采用keytool生成. -genkey 生成秘钥 -alias 别名 -keyalg 秘钥算法 -keysize 秘钥长度 -validity 有效期 -keystore 生成秘钥库的存储路径和名称 -keypass 秘钥口令 -storepass 秘钥库口令 -dname 拥有者信

  • Spring boot security权限管理集成cas单点登录功能的实现

    目录 1.Springboot集成Springsecurity 2.部署CASserver 3.配置CASclient 挣扎了两周,Spring security的cas终于搞出来了,废话不多说,开篇! 1.Spring boot集成Spring security 本篇是使用spring security集成cas,因此,先得集成spring security新建一个Spring boot项目,加入maven依赖,我这里是用的架构是Spring boot2.0.4+Spring mvc+Spri

  • 详解spring boot配置 ssl

    ssl协议位于tcp/ip协议与各种应用协议之间,为数据通信提供安全支持. ssl协议分为两层: ssl记录协议,它建立在可靠传输协议之上,为高层协议提供数据封装.压缩.加密等基本功能支持. ssl握手协议,它建立在ssl记录协议之上,用于实际数据传输开始前,通信双方进行身份认证.协商加密算法.交换加密密钥等 基于B/S的web应用,是通过https来实现ssl的.https是http的安全版,即在http下加入ssl层,https的安全基础是ssl: 我们开始在spring boot中使用ss

  • Shell自动化配置SSH免密登录和取消SSH免密配置脚本

    目录 1. 前文 2.实现代码 3. 使用方法 4. 使用注意 1. 前文 搭建了一套有多台主机的局域网环境,不完全考虑安全性的情况下,为方便管理局域网内主机,配置SSH免密登录,因主机较多,前阵子针对配置ssh免密和取消ssh免密功能单独写了脚本来自动化批量部署,现把两个功能封装在一起做成交互式程序 2.实现代码 #!/bin/bash #Author:cosann #Version:0.2 #date:2022/7/27 #description:批量部署SSH免密登录脚本 E_ERROR=

  • spring boot实战之内嵌容器tomcat配置

    本文介绍了spring boot实战之内嵌容器tomcat配置,分享给大家,具体如下: 默认容器 spring boot默认web程序启用tomcat内嵌容器tomcat,监听8080端口,servletPath默认为 / 通过需要用到的就是端口.上下文路径的修改,在spring boot中其修改方法及其简单: 在资源文件中配置: server.port=9090 server.contextPath=/lkl 启动spring boot 2015-10-04 00:06:55.768 INFO

  • 利用Spring boot如何创建简单的web交互应用

    关于页面渲染 其实在工作中,一直都是前后端分离,也就是说,我的工作从来都是提供接口,而不写 html css js 之类的,所以在这方面也没有经验. 这里为了给大家介绍下模板引擎,我将会写个非常非常简单的页面,如果不好看,请见谅~ Spring Boot 官方推荐的模板引擎是 Thymeleaf ,点击可以进入其官网了解详情. 本章目标 让 Spring Boot 应用可以访问到静态资源文件 创建用户登录表单,并对用户名.密码进行校验 校验失败,将返回登录页,并展示错误信息 校验成功,重定向到苹

  • Spring Boot和Vue跨域请求问题原理解析

    这篇文章主要介绍了Spring Boot和Vue跨域请求问题原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 使用Spring Boot + Vue 做前后端分离项目搭建,实现登录时,出现跨域请求 Access to XMLHttpRequest at 'http://localhost/open/login' from origin 'http://localhost:8080' has been blocked by CORS pol

随机推荐