增加客户端认证详解
This commit is contained in:
parent
4f78b49c94
commit
9d4268c123
14
README.md
14
README.md
@ -12,7 +12,12 @@ mvn -T 8 package -Pdist,native -DskipTests -Dmaven.javadoc.skip=true
|
|||||||
|
|
||||||
# 知识树
|
# 知识树
|
||||||
|
|
||||||
## HDFS
|
|
||||||
|
## Common 模块
|
||||||
|
|
||||||
|
|
||||||
|
## HDFS 模块
|
||||||
|
|
||||||
- [HDFS概览](./hdfs/README.md)
|
- [HDFS概览](./hdfs/README.md)
|
||||||
- NameNode相关
|
- NameNode相关
|
||||||
- [namenode全景](./hdfs/namenode全景.md)
|
- [namenode全景](./hdfs/namenode全景.md)
|
||||||
@ -27,7 +32,8 @@ mvn -T 8 package -Pdist,native -DskipTests -Dmaven.javadoc.skip=true
|
|||||||
- [BPServiceActor详解](./hdfs/BPServiceActor详解.md)
|
- [BPServiceActor详解](./hdfs/BPServiceActor详解.md)
|
||||||
|
|
||||||
|
|
||||||
## Yarn
|
## Yarn 模块
|
||||||
|
|
||||||
- [Yarn概览](./yarn/README.md)
|
- [Yarn概览](./yarn/README.md)
|
||||||
- [ResourceManager详解](./yarn/resourcemanager.md)
|
- [ResourceManager详解](./yarn/resourcemanager.md)
|
||||||
- [作业启动](./yarn/job_start.md)
|
- [作业启动](./yarn/job_start.md)
|
||||||
@ -41,11 +47,11 @@ mvn -T 8 package -Pdist,native -DskipTests -Dmaven.javadoc.skip=true
|
|||||||
- [jobhistory 作业缓存](./yarn/jobhistory_cache.md)
|
- [jobhistory 作业缓存](./yarn/jobhistory_cache.md)
|
||||||
|
|
||||||
|
|
||||||
## Zookeeper
|
## Zookeeper模块
|
||||||
- [Zookeeper概览](./zookeeper/README.md)
|
- [Zookeeper概览](./zookeeper/README.md)
|
||||||
|
|
||||||
|
|
||||||
## OZone
|
## OZone 模块
|
||||||
- [OZone概览](./ozone/README.md)
|
- [OZone概览](./ozone/README.md)
|
||||||
|
|
||||||
|
|
||||||
|
BIN
common/attach/SPNEGO认证流程图.eddx
Normal file
BIN
common/attach/SPNEGO认证流程图.eddx
Normal file
Binary file not shown.
104
common/authenticated.md
Normal file
104
common/authenticated.md
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
|
||||||
|
# 客户端认证
|
||||||
|
客户端的入口函数为 KerberosAuthenticator.authenticate函数
|
||||||
|
|
||||||
|
## 连接HTTP服务端
|
||||||
|
|
||||||
|
```java
|
||||||
|
HttpURLConnection conn = token.openConnection(url, connConfigurator);
|
||||||
|
conn.setRequestMethod(AUTH_HTTP_METHOD);
|
||||||
|
conn.connect();
|
||||||
|
```
|
||||||
|
|
||||||
|
## SPNEGO认证
|
||||||
|
对于普通的HTTP的kerberos认证(SPNEGO),需要现在客户端登录KDC服务。核心代码在函数doSpnegoSequence里面。
|
||||||
|
|
||||||
|
首先需要登录KDC服务端:
|
||||||
|
|
||||||
|
```java
|
||||||
|
subject = new Subject();
|
||||||
|
LoginContext login = new LoginContext("", subject,
|
||||||
|
null, new KerberosConfiguration());
|
||||||
|
// 登录KDC服务
|
||||||
|
login.login();
|
||||||
|
```
|
||||||
|
下面主要是开始认证的时候的逻辑。核心处理逻辑流程图如下:
|
||||||
|
|
||||||
|
![pic](https://pan.zeekling.cn/zeekling/hadoop/common/Hadoop_auth_client_spnego.png)
|
||||||
|
|
||||||
|
主要代码逻辑如下。
|
||||||
|
|
||||||
|
```java
|
||||||
|
GSSManager gssManager = GSSManager.getInstance();
|
||||||
|
// 设置服务端的域名,由于是HTTP协议,所以当前要求principal的格式为:HTTP/HOST_NAME的方式。
|
||||||
|
String servicePrincipal = KerberosUtil.getServicePrincipal("HTTP",
|
||||||
|
KerberosAuthenticator.this.url.getHost());
|
||||||
|
Oid oid = KerberosUtil.NT_GSS_KRB5_PRINCIPAL_OID;
|
||||||
|
GSSName serviceName = gssManager.createName(servicePrincipal,
|
||||||
|
oid);
|
||||||
|
oid = KerberosUtil.GSS_KRB5_MECH_OID;
|
||||||
|
// 创建获取token的上下文信息。
|
||||||
|
gssContext = gssManager.createContext(serviceName, oid, null,
|
||||||
|
GSSContext.DEFAULT_LIFETIME);
|
||||||
|
gssContext.requestCredDeleg(true);
|
||||||
|
gssContext.requestMutualAuth(true);
|
||||||
|
|
||||||
|
byte[] inToken = new byte[0];
|
||||||
|
byte[] outToken;
|
||||||
|
boolean established = false;
|
||||||
|
|
||||||
|
// Loop while the context is still not established
|
||||||
|
while (!established) {
|
||||||
|
HttpURLConnection conn =
|
||||||
|
token.openConnection(url, connConfigurator);
|
||||||
|
// 获取客户端的token。对于第一次的场景,inToken为空。
|
||||||
|
// 对于中间过程,需要将服务端给的token传进去校验。
|
||||||
|
outToken = gssContext.initSecContext(inToken, 0, inToken.length);
|
||||||
|
if (outToken != null) {
|
||||||
|
// 将token发送给服务端
|
||||||
|
sendToken(conn, outToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gssContext.isEstablished()) {
|
||||||
|
// 读取服务端发送的token。
|
||||||
|
inToken = readToken(conn);
|
||||||
|
} else {
|
||||||
|
// 认证完成,认证结束
|
||||||
|
established = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 认证完成/无须认证
|
||||||
|
|
||||||
|
如果HTTP服务端返回的是HTTP_OK,则认为服务端是不需要认证的,或者是已经认证完成了。在已经完成认证的场景下,
|
||||||
|
需要解析Token。
|
||||||
|
|
||||||
|
```java
|
||||||
|
AuthenticatedURL.extractToken(conn, token);
|
||||||
|
if (isTokenKerberos(token)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
needFallback = true;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 其他自定义
|
||||||
|
|
||||||
|
其他自定义认证的场景,可以通过指定Authenticator的方式实现,具体实现可以自定义,主要保证服务端和客户端一致即可。
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 当前主要适用于对认证方式需要扩展的场景。
|
||||||
|
Authenticator auth = getFallBackAuthenticator();
|
||||||
|
auth.setConnectionConfigurator(connConfigurator);
|
||||||
|
auth.authenticate(url, token);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# 服务端认证
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user