当前位置: 首页 > 科技观察

使用SpringBoot实现httpsssl免密码登录

时间:2023-03-13 09:11:41 科技观察

要让项目实现ssl免密码登录,首先需要开启https。因此,让我们从如何在SpringBoot中启用https开始。创建服务器证书为了启用https,我们需要一个证书。在实际开发中,你会在网上申请一个机构颁发的证书。这里为了方便起见,我会使用openssl命令生成证书以供使用。opensslreq-x509-sha256-days3650-newkeyrsa:4096-keyoutrootCA.key-outrootCA.crt所有密码都是123456,然后根据提示输入相关信息即可,如果嫌麻烦直接回车跳过.这样我们就得到了证书rootCA.crt和私钥rootCA.key。要在SpringBoot中实现服务器端X.509身份验证,我们还需要为我们的服务器生成证书。opensslreq-new-newkeyrsa:4096-keyoutlocalhost.key-outlocalhost.csr同样密码为123456,文件名localhost可自行修改。下一步是使用rootCA签署我们的服务器证书。在此之前,我们先写一个配置文件,里面有一些基本的配置viconf.configauthorityKeyIdentifier=keyid,issuerbasicConstraints=CA:FALSEsubjectAltName=@alt_names[alt_names]DNS.1=localhost其中DNS.1的值为你的域名,比如如www.segmentfault.com、localhost等。如果这里出错,访问该网站时,浏览器会提示该网站不安全。然后签署服务器证书,会提示输入rootCA密码opensslx509-req-CArootCA.crt-CAkeyrootCA.key-inlocalhost.csr-outlocalhost.crt-days365-CAcreateserial-extfileconf.config成功后,让我们检查一下证书信息opensslx509-inlocalhost.crt-text最后将签名的证书和私钥打包到PKCS文件中.keypassword,然后你需要为localhost.p12定义一个密码。密码localhost.p12一定要记住,因为在Spring的配置文件中用到了。另外需要注意的是,Spring配置文件中server.ssl.keyAlias的取值是命令中的localhost(-name"localhost")。SpringBoot打开https将localhost.p12复制到resources目录下,然后编译项目修改application.properties文件server.port=8888server.ssl.key-store=classpath:localhost.p12server.ssl.key-store-password=123456server.ssl.keyStoreType=PKCS12server.ssl.keyAlias=localhost在chrome://settings/security中选择受信任的根证书颁发机构导入rootCA.crt然后启动项目,即可使用https访问网站,浏览器提示网站安全。创建信任证书信任证书会存放可信外部实体的证书这里我们只需要在其中添加rootCA.crtkeytool-import-trustcacerts-noprompt-aliasca-extsan=dns:localhost,ip:127.0.0.1-filerootCA.crt-keystorelocalhost.jks然后在项目中添加localhost.jks,修改配置文件application.properties添加:server.ssl.trust-store=classpath:localhost.jksserver.ssl.trust-store-password=123456server。ssl.client-auth=need注意:此时由于添加了server.ssl.client-auth=need,没有添加个人证书,所以此时刷新页面会无法访问该项目。如果想兼做普通登录,可以设置Need改为want,want只会在第一次访问页面时向客户索取个人证书。创建客户端证书现在创建客户端证书,步骤和服务器上的几乎一样。opensslreq-new-newkeyrsa:4096-nodes-keyoutshurlormes.key-outshurlormes.csr生成客户端证书时,不建议跳过这些信息,因为在后续步骤中,会获取这些信息用于登录。比如我在CommonName处填写的信息就是后面用来登录的用户名。接下来使用RootCA对客户端证书opensslx509-req-CArootCA.crt-CAkeyrootCA.key-inshurlormes.csr-outshurlormes.crt-days365-CAcreateserial进行签名,然后将签名后的证书和私钥打包到PKCS文件opensslpkcs12-export-outshurlormes.p12-name"shurlormes"-inkeyshurlormes.key-inshurlormes.crt最后在chrome://settings/security中选择个人证书导入shurlormes.p12,期间会要求输入其密码。此时刷新页面,浏览器会弹出一个对话框,让你选择个人认证。SpringBoot获取个人证书信息恭喜,至此pki登录已经完成99%。接下来就是通过request获取证书信息,然后对字符串进行处理,获取登录的用户名。@RequestMapping("/login")publicStringlogin(HttpServletRequestrequest){X509Certificate[]certs=(X509Certificate[])request.getAttribute("javax.servlet.request.X509Certificate");if(certs!=null){X509CertificategaX509Cert=certs[0];Stringdn=gaX509Cert.getSubjectDN().toString();System.out.println("个人证明书信息:"+dn);Stringusername="";String[]dnArray=dn.split(",");for(StringdnItem:dnArray){String[]dnInfo=dnItem.split("=");Stringkey=dnInfo[0];Stringvalue=dnInfo[1];if("cn".equalsIgnoreCase(key.trim())){username=value;break;}}System.out.println("用户名:"+username);if(!StringUtils.isEmpty(username)){SecurityContextsecurityContext=SecurityContextHolder.getContext();UseruserDetails=newUser(username,"",Collections.EMPTY_LIST);securityContext.setAuthentication(newUsernamePasswordAuthenticationToken(userDetails,"",Collections.EMPTY_LIST));return"redirect:/";}}returnn"login";}SpringBoot同时启用http和https。相信大家都发现了项目只能通过https访问。如果使用http访问浏览器,直接返回Badrequest。同时启用https和http,只需要添加一个TomcatConfig就可以@ConfigurationpublicclassTomcatHttpConfig{@BeanpublicTomcatServletWebServerFactoryservletContainer(){TomcatServletWebServerFactorytomcat=newTomcatServletWebServerFactory();tomcat.addAdditionalTomcatConnectors(initiateHttpConnector());returntomcat;}privateConnectorinitiateHttpConnector=Connector(){Connector(Connector)"org.apache.coyote.http11.Http11NioProtocol");connector.setScheme("http");connector.setPort(9999);connector.setSecure(false);returnconnector;}}这个时候启动项目,注意打印在控制台上的信息。说明已经在9999端口成功启动了http,在8888端口启动了https,页面也可以正常访问了。SpringBoothttp自动跳转到https我们已经可以同时访问http和https了,但是如果我要访问http,自动跳转的https呢?只需要在上面的基础上稍作修改即可。@ConfigurationpublicclassTomcatHttpConfig{@BeanpublicTomcatServletWebServerFactoryservletContainer(){TomcatServletWebServerFactorytomcat=newTomcatServletWebServerFactory(){@OverrideprotectedvoidpostProcessContext(Contextcontext){SecurityConstraintsecurityConstraint=newSecurityConstraint();securityConstraint.setUserConstraint("CONFIDENTIAL");SecurityCollectioncollection=newSecurityCollection();collection.addPattern("/*");securityConstraint.addCollection(集合);context.addConstraint(securityConstraint);}};tomcat.addAdditionalTomcatConnectors(initiateHttpConnector());returntomcat;}privateConnectorinitiateHttpConnector(){Connectorconnector=newConnector("org.apache.coyote.http11.Http11")NioProtocol;connector.setScheme("http");connector.setPort(9999);connector.setSecure(false);connector.setRedirectPort(8888);returnconnector;}}踩坑总结添加服务器证书p12文件后项目资源,记得重建项目,否则我的证书文件没有在目标类中生成,会导致项目项目无法启动。application.properties中的server.ssl.keyAlias需要和生成的p12文件的-name保持一致,否则项目启动失败。如果要指定域名,需要修改conf.confg中的DNS.1,否则浏览器会提示网站不安全。