Java语言开发学习之用Spring Boot实现https ssl免密登录
小职 2021-01-07 来源 : 阅读 663 评论 0

摘要:本文主要向大家介绍了Java语言开发学习之用Spring Boot实现https ssl免密登录,通过具体的内容向大家展现,希望对大家Java语言开发的学习有所帮助。

本文主要向大家介绍了Java语言开发学习之用Spring Boot实现https ssl免密登录,通过具体的内容向大家展现,希望对大家Java语言开发的学习有所帮助。

Java语言开发学习之用Spring Boot实现https ssl免密登录

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

 

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

 

创建服务端证书

 

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

 

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

 

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

Java语言开发学习之用Spring Boot实现https ssl免密登录

 

所有的密码都是 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.com , localhost 等等。如果这里填错了,访问网站时,浏览器会提示网站不安全。

 

然后给服务端证书签名,会提示你输入 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

 Java语言开发学习之用Spring Boot实现https ssl免密登录

最后再将签名证书和私钥打包到 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 目录下之后编译项目

 Java语言开发学习之用Spring Boot实现https ssl免密登录

用Spring Boot实现https ssl免密登录

修改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

 Java语言开发学习之用Spring Boot实现https ssl免密登录

 

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

 Java语言开发学习之用Spring Boot实现https ssl免密登录

用Spring Boot实现https ssl免密登录

创建信托证书

 

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

 

这里我们只要将 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 添加到项目中,并修改配置文件

 Java语言开发学习之用Spring Boot实现https ssl免密登录

用Spring Boot实现https ssl免密登录

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只会在第一次访问页面时才会向客户索取个人证书

 Java语言开发学习之用Spring Boot实现https ssl免密登录

 

创建客户端证书

 

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

 

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

 

 Java语言开发学习之用Spring Boot实现https ssl免密登录

在生成客户端证书时,那些信息不建议跳过,因为在后续的步骤中,会获取其中的信息用以登录。比如我在 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 导入,期间会要你输入它的密码。

 Java语言开发学习之用Spring Boot实现https ssl免密登录

 Java语言开发学习之用Spring Boot实现https ssl免密登录

 Java语言开发学习之用Spring Boot实现https ssl免密登录

 

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

 Java语言开发学习之用Spring Boot实现https ssl免密登录

 

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

}

 Java语言开发学习之用Spring Boot实现https ssl免密登录

 Java语言开发学习之用Spring Boot实现https ssl免密登录

用Spring Boot实现https ssl免密登录

Spring Boot 同时开启http和https

 

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

 Java语言开发学习之用Spring Boot实现https ssl免密登录

用Spring Boot实现https ssl免密登录

要同时开启 https 和 http ,只需添加一个 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;

    }

}

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

 Java语言开发学习之用Spring Boot实现https ssl免密登录

 

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

 Java语言开发学习之用Spring Boot实现https ssl免密登录

 

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 ,否则浏览器会提示网站不安全。



关注“职坐标在线”(Zhizuobiao_Online)公众号,免费获取学习视频资料、技术就业咨询

Java语言开发学习之用Spring Boot实现https ssl免密登录

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程