spring boot zuul集成kubernetes等第三方登录
介绍一下,在单点登录平台集成kubernetes登录,集成其它系统的登录原理是一样的,如grafana, nacos, jenkins等。
POM引用:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
系统入口类:
@SpringBootApplication
@EnableZuulProxy
@Slf4j
public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }
}
controller:
这里要说下,kubernetes的登录逻辑:

有两个login:
第一个login:https://***:30000/api/v1/csrftoken/login
返回json:
{
"token": "4IJufIQiwOWcaFmQdMMHKQqNEro:1573810029428"
}
第二个login:https://**30000/api/v1/login,使用第一个login返回的token进行登录:

返回json:
{
"jweToken": "{\"protected\":\"eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0\",\"aad\":\"eyJleHAiOiIyMDE5LTExLTE1VDE5OjI3OjA5WiIsImlhdCI6IjIwMTktMTEtMTVUMDk6Mjc6MDlaIn0\",\"encrypted_key\":\"Pq5FWwv06JXsPL8H5N3ZAlk7jTGHIGwbdjFdNUoAa6mWn-avNnPiZNjgsDFPZF8cNDgVsN_J-BmranVabxVe9VeJmuDgfY-2KTANslsKF4g2nPdZC3DDmFdLB6V-eXaBduw0ABLGaGisPX_T-3Qxls1sx9EuJ8vvH9a3Fr_iQPxiGxyG_61jSjqqtwXB-sftxULpAuDv84V4Ebba9JLFxCSJnmQ0E8hw3w5Ady1pw3dbPb8q1HnuPEd3Ry27EJYRzswQWkG9CJRxbcQtOzlneW0jBqrbbi-UpVy2vQC2zmdLKACzwkas3l9BBKHJF7xwxUoX-oc4i6NM6HqkwIbSAQ\",\"iv\":\"HoG3iDTSawS7-xBS\",\"ciphertext\":\"Ad696v6QmyciUmE_F3xstK6xX9CZAQw1IsKmi9oDwjoVELaBDZOPTfR-Cqub3WHj520Svdubei8QiIC5zg\",\"tag\":\"8Rf53qa5hBn7jrAiuYqrLw\"}",
"errors": []
}
然后我们就可以用jweToken写入cookie 轻松访问k8s了。

下面的代码显示这这三个步骤:
package com.cis.jpa.demo.controller; import com.alibaba.fastjson.JSONObject;
import com.cis.jpa.demo.dto.LoginResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder; /**
* @author :hkk
* @date :Created in 2019/11/15 13:29
*/
@RestController
public class K8sController {
private static final String K8S_ADDR = "https://***:30000/"; @Autowired
private RestTemplate restTemplate;
@RequestMapping("/sso")
public void index(HttpServletResponse response) throws IOException { String loginToken = getLoginToken();
LoginResult body = getLoginJweToken(loginToken);
String code = URLEncoder.encode(body.getJweToken(), "utf-8");
Cookie cookie = new Cookie("jweToken",code);
cookie.setPath("/");
response.addCookie(cookie);
response.addHeader("jweToken",body.getJweToken());
response.sendRedirect("/"); } private LoginResult getLoginJweToken(String loginToken) {
JSONObject json = new JSONObject();
json.put("kubeconfig", "");
json.put("password", "admin");
json.put("username", "admin");
json.put("token", ""); HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
headers.add("x-csrf-token", loginToken); HttpEntity<String> formEntity = new HttpEntity<>(json.toString(), headers); String loginUrl = K8S_ADDR + "api/v1/login";
return restTemplate.postForEntity(loginUrl, formEntity, LoginResult.class).getBody();
} private String getLoginToken() {
String preLoginUrl = K8S_ADDR +"api/v1/csrftoken/login"; LoginResult body = restTemplate.getForEntity(preLoginUrl, LoginResult.class).getBody(); return body.getToken();
} }
这里先用两个restTemplate获取token和jweToken,但由于是https所以,需要配置restTemplate:
这个类摘自网络,出处找不到了。。。
package com.cis.jpa.demo.confing; import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Component; import javax.net.ssl.*;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.Socket;
import java.security.cert.X509Certificate; /**
* @author :hkk
* @date :Created in 2019/11/15 11:14
*/
@Component
public class HttpsClientRequestFactory extends SimpleClientHttpRequestFactory { @Override
protected void prepareConnection(HttpURLConnection connection, String httpMethod) {
try {
if (!(connection instanceof HttpsURLConnection)) {
throw new RuntimeException("An instance of HttpsURLConnection is expected");
} HttpsURLConnection httpsConnection = (HttpsURLConnection) connection; TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
} }
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
httpsConnection.setSSLSocketFactory(new MyCustomSSLSocketFactory(sslContext.getSocketFactory())); httpsConnection.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}); super.prepareConnection(httpsConnection, httpMethod);
} catch (Exception e) {
e.printStackTrace();
}
} /**
* We need to invoke sslSocket.setEnabledProtocols(new String[] {"SSLv3"});
* see http://www.oracle.com/technetwork/java/javase/documentation/cve-2014-3566-2342133.html (Java 8 section)
*/
// SSLSocketFactory用于创建 SSLSockets
private static class MyCustomSSLSocketFactory extends SSLSocketFactory { private final SSLSocketFactory delegate; public MyCustomSSLSocketFactory(SSLSocketFactory delegate) {
this.delegate = delegate;
} // 返回默认启用的密码套件。除非一个列表启用,对SSL连接的握手会使用这些密码套件。
// 这些默认的服务的最低质量要求保密保护和服务器身份验证
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
} // 返回的密码套件可用于SSL连接启用的名字
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
} @Override
public Socket createSocket(final Socket socket, final String host, final int port,
final boolean autoClose) throws IOException {
final Socket underlyingSocket = delegate.createSocket(socket, host, port, autoClose);
return overrideProtocol(underlyingSocket);
} @Override
public Socket createSocket(final String host, final int port) throws IOException {
final Socket underlyingSocket = delegate.createSocket(host, port);
return overrideProtocol(underlyingSocket);
} @Override
public Socket createSocket(final String host, final int port, final InetAddress localAddress,
final int localPort) throws
IOException {
final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);
return overrideProtocol(underlyingSocket);
} @Override
public Socket createSocket(final InetAddress host, final int port) throws IOException {
final Socket underlyingSocket = delegate.createSocket(host, port);
return overrideProtocol(underlyingSocket);
} @Override
public Socket createSocket(final InetAddress host, final int port, final InetAddress localAddress,
final int localPort) throws
IOException {
final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);
return overrideProtocol(underlyingSocket);
} private Socket overrideProtocol(final Socket socket) {
if (!(socket instanceof SSLSocket)) {
throw new RuntimeException("An instance of SSLSocket is expected");
}
((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1"});
return socket;
}
}
}
再配置restTemplate:
@Bean
public RestTemplate restTemplate(HttpsClientRequestFactory factory){ return new RestTemplate(factory);
}
restTemplate就可以访问https站点了。
controller中第三步跳转到“ / ”根目录:
根目录在是zuul中配置跳转的:
zuul:
host:
max-per-route-connections: 300000
socket-timeout-millis: 300000
connect-timeout-millis: 60000
ignoredServices: '*'
ignoredPatterns: '/sso'
routes:
k8s-config:
path: /**
url: https://***:30000/
stripPrefix: true
sensitiveHeaders: Cookie,Set-Cookie
与restTemplate一样,zuul也是默认不支持访问https的,(kubernetes与其它系统的不同点是它是https登录),其他都是http协议。
zuul网关路由https时,需要对httpclient做一些处理,否则会报错:
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
解决这个问题有两个思络,一是对特定站点进行证书的导入配置,另一种是无论是哪个https站点,都可以访问,这里我们选择第二种:
@Bean
public CloseableHttpClient httpClient() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException {
SSLConnectionSocketFactory scsf = new SSLConnectionSocketFactory(
SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build()
, NoopHostnameVerifier.INSTANCE
); return HttpClients.custom().setSSLSocketFactory(scsf).build();
}
这样我们就可以像访问自己的站点一样,访问k8s dashboard了。
spring boot zuul集成kubernetes等第三方登录的更多相关文章
- tp5集成淘宝,微信,网易,新浪等第三方登录
tp5集成淘宝,微信,网易,新浪等第三方登录 一.总结 一句话总结: 接口 链接 实现的话就是这些平台给的一个接口(链接),你通过这些接口登录进去之后,它会给你返回用户名,头像之类的信息,我们的网站存 ...
- Spring Boot:集成Druid数据源
综合概述 数据库连接池负责分配.管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个:释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据 ...
- shiro 和 spring boot 的集成
1 添加依赖 使用 shiro-spring-boot-web-starter 在 spring boot 中集成 shiro 只需要再添加一个依赖 <dependency> <gr ...
- Spring Boot 项目集成 Alibaba Druid
Druid 是一个非常好用的数据库连接池,但是他的好并不止体现在作为一个连接池加快数据访问性能上和连接管理上,他带有一个强大的监控工具:Druid Monitor.不仅可以监控数据源和慢查询,还可以监 ...
- spring boot 2 集成JWT实现api接口认证
JSON Web Token(JWT)是目前流行的跨域身份验证解决方案.官网:https://jwt.io/本文使用spring boot 2 集成JWT实现api接口验证. 一.JWT的数据结构 J ...
- 对QQ、微信等第三方登录的几个思考
转自:http://www.jianshu.com/p/7f282dfc16fc 今天聊聊注册.登录环节中很常见的第三方登录,如QQ.微信.支付宝.新浪微博等.虽然这些产品的开放平台都提供了标准的接入 ...
- Spring Boot快速集成kaptcha生成验证码
Kaptcha是一个非常实用的验证码生成工具,可以通过配置生成多样化的验证码,以图片的形式显示,从而无法进行复制粘贴:下面将详细介绍下Spring Boot快速集成kaptcha生成验证码的过程. 本 ...
- [转帖]spring boot项目集成jacoco
小试牛刀:spring boot项目集成jacoco 2019-03-28 20:14:36 zyq23333 阅读数 509 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议, ...
- Java | Spring Boot Swagger2 集成REST ful API 生成接口文档
Spring Boot Swagger2 集成REST ful API 生成接口文档 原文 简介 由于Spring Boot 的特性,用来开发 REST ful 变得非常容易,并且结合 Swagg ...
随机推荐
- 同样的WiFi,手机能连上网,电脑不能。错误代码DNS_PROBE_POSSIBLE
今天电脑不知打为撒,出了这样个毛病,原因不明.先试着用电脑管家修复,无效.找了网上的很多办法,排除了dns.ip之类的问题.最后在贴吧里看到大神的解决办法,实测简单有效.链接http://tieba. ...
- smarty 模板中输出时间戳为年月日格式
日期:{:date('Y-m-d',$v['addtime'])} // $v['addtime']数据库中的时间戳 输出结果: 日期:{:date('Y-m-d H:i:s',$v['addtim ...
- CFS理论模型
参考资料:<调度器笔记>Kevin.Liu <Linux kernel development> <深入Linux内核架构> version: 2.6.32.9 下 ...
- 剑指XX游戏(六) - 轻松搞定面试中的红黑树问题
原文地址 http://blog.csdn.net/silangquan/article/details/18655795?utm_source=tuicool&utm_medium=refe ...
- Appium移动自动化测试(四)之元素定位
做过UI自动化测试的童鞋都会发现, 在上一篇文章中居然没有万能定位方式Xpath. 是滴, 确实没有! ADT自带的uiautomatorviewer里面并没有属性xpath, 如果我们需要的话,还需 ...
- ES5与ES6常用语法教程之 ①函数写法、创建对象、导入导出模块方式
函数写法区别 计算a, b两个数字之和,有返回值 es5 写法 function add(a, b) { return a + b; } es6 写法(箭头函数) let add = (a, b) = ...
- OpenStack组件——Nova计算资源管理
1.nova介绍 Nova 是 OpenStack 最核心的服务,负责维护和管理云环境的计算资源.OpenStack 作为 IaaS 的云操作系统,虚拟机生命周期管理也就是通过 Nova 来实现的. ...
- 【神经网络与深度学习】gflags介绍
gflags是什么: gflags是google的一个开源的处理命令行参数的库,使用c++开发,具备python接口,可以替代getopt. gflags使用起来比getopt方便,但是不支持参数的简 ...
- Linux 中账户管理
账户管理涉及到三个文件: 1./etc/passwd yy@ubuntu:~$ head -n 3 /etc/passwdroot:x:0:0:root:/root:/bin/bashdaemon:x ...
- LeetCode | DP专题详解
221 medium 221. Maximal Square Medium Given a 2D binary matrix filled with 0's and 1's, find the ...