diff --git a/README.md b/README.md index 2793581..38b06d5 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,12 @@ mvn -T 8 package -Pdist,native -DskipTests -Dmaven.javadoc.skip=true # 知识树 -## HDFS + +## Common 模块 + + +## HDFS 模块 + - [HDFS概览](./hdfs/README.md) - NameNode相关 - [namenode全景](./hdfs/namenode全景.md) @@ -27,7 +32,8 @@ mvn -T 8 package -Pdist,native -DskipTests -Dmaven.javadoc.skip=true - [BPServiceActor详解](./hdfs/BPServiceActor详解.md) -## Yarn +## Yarn 模块 + - [Yarn概览](./yarn/README.md) - [ResourceManager详解](./yarn/resourcemanager.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) -## Zookeeper +## Zookeeper模块 - [Zookeeper概览](./zookeeper/README.md) -## OZone +## OZone 模块 - [OZone概览](./ozone/README.md) diff --git a/common/attach/SPNEGO认证流程图.eddx b/common/attach/SPNEGO认证流程图.eddx new file mode 100644 index 0000000..32a7809 Binary files /dev/null and b/common/attach/SPNEGO认证流程图.eddx differ diff --git a/common/authenticated.md b/common/authenticated.md new file mode 100644 index 0000000..6043b98 --- /dev/null +++ b/common/authenticated.md @@ -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); +``` + + +# 服务端认证 + + + +