# SASL

> 原文： [https://docs.oracle.com/javase/tutorial/jndi/ldap/sasl.html](https://docs.oracle.com/javase/tutorial/jndi/ldap/sasl.html)

LDAP v3 协议使用 [SASL](http://www.ietf.org/rfc/rfc2222.txt) 来支持 _ 可插拔 _ 身份验证。这意味着 LDAP 客户端和服务器可以配置为协商并使用可能的非标准和/或自定义机制进行身份验证，具体取决于客户端和服务器所需的保护级别。 LDAP v2 协议不支持 SASL。

目前定义了几种 SASL 机制：

*   匿名（ [RFC 2245](http://www.ietf.org/rfc/rfc2245.txt) ）
*   CRAM-MD5（ [RFC 2195](http://www.ietf.org/rfc/rfc2195.txt) ）
*   Digest-MD5（ [RFC 2831](http://www.ietf.org/rfc/rfc2831.txt) ）
*   外部（ [RFC 2222](http://www.ietf.org/rfc/rfc2830.txt) ）
*   Kerberos V4（ [RFC 2222](http://www.ietf.org/rfc/rfc2830.txt) ）
*   Kerberos V5（ [RFC 2222](http://www.ietf.org/rfc/rfc2830.txt) ）
*   SecurID（ [RFC 2808](http://www.ietf.org/rfc/rfc2808.txt) ）
*   S / Key（ [RFC 2222](http://www.ietf.org/rfc/rfc2830.txt) ）

## LDAP 服务器支持的 SASL 机制

在上一个列表中的机制中，流行的 LDAP 服务器（例如来自 Oracle，OpenLDAP 和 Microsoft 的服务器）支持 External，Digest-MD5 和 Kerberos V5。 [RFC 2829](http://www.ietf.org/rfc/rfc2829.txt) 建议使用 Digest-MD5 作为 LDAP v3 服务器的强制默认机制。

这是 [`simple program`](examples/ServerSasl.java) ，用于查找 LDAP 服务器支持的 SASL 机制列表。

```
// Create initial context
DirContext ctx = new InitialDirContext();

// Read supportedSASLMechanisms from root DSE
Attributes attrs = ctx.getAttributes(
    "ldap://localhost:389", new String[]{"supportedSASLMechanisms"});

```

以下是通过对支持外部 SASL 机制的服务器运行此程序而产生的输出。

```
{supportedsaslmechanisms=supportedSASLMechanisms: 
                         EXTERNAL, GSSAPI, DIGEST-MD5}

```

## 指定身份验证机制

要使用特定的 SASL 机制，请在 [`Context.SECURITY_AUTHENTICATION`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#SECURITY_AUTHENTICATION)环境属性中指定其 Internet 分配号码机构（IANA）注册的机制名称。您还可以指定 LDAP 提供程序尝试的机制列表。这是通过指定空格分隔机制名称的有序列表来完成的。 LDAP 提供程序将使用它找到实现的第一种机制。

这是一个示例，要求 LDAP 提供程序尝试获取 DIGEST-MD5 机制的实现，如果不可用，请使用 GSSAPI。

```
env.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5 GSSAPI");

```

您可以从应用程序的用户处获取此身份验证机制列表。或者您可以通过类似于之前显示的呼叫询问 LDAP 服务器来获取它。 LDAP 提供程序本身不会向服务器咨询此信息。它只是试图找到并使用指定机制的实现。

平台中的 LDAP 提供程序内置支持 External，Digest-MD5 和 GSSAPI（Kerberos v5）SASL 机制。您可以添加对其他机制的支持。

## 指定身份验证机制的输入

某些机制（如 External）不需要额外的输入 - 仅机制名称就足以使身份验证继续进行。 [外部示例](ssl.html#EXTERNAL)显示了如何使用外部 SASL 机制。

大多数其他机制需要一些额外的输入根据机制，输入类型可能会有所不同。以下是机制所需的一些常见输入。

*   **验证 ID** 。执行身份验证的实体的标识。
*   **授权 ID** 。如果身份验证成功，则应对其进行访问控制检查的实体的标识。
*   **身份验证凭据**。例如，密码或密钥。

如果程序（例如代理服务器）代表另一个实体进行身份验证，则身份验证和授权 ID 可能会有所不同。使用 [`Context.SECURITY_PRINCIPAL`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#SECURITY_PRINCIPAL)环境属性指定认证标识。它的类型为 `java.lang.String` 。

使用 [`Context.SECURITY_CREDENTIALS`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#SECURITY_CREDENTIALS)环境属性指定认证标识的密码/密钥。它的类型为 `java.lang.String` ， `char` 数组（ `char []` ），或`字节`数组（`字节[]` ）。如果密码是`字节`数组，则使用 UTF-8 编码将其转换为 `char` 数组。

如果已设置`“java.naming.security.sasl.authorizationId”`属性，则将其值用作授权 ID。它的值必须是 `java.lang.String` 类型。默认情况下，空字符串用作授权标识，指示服务器从客户端的身份验证凭据派生授权标识。

[Digest-MD5 示例](digest.html)显示如何使用 `Context.SECURITY_PRINCIPAL` 和 `Context.SECURITY_CREDENTIALS` 属性进行 Digest-MD5 身份验证。

如果机制需要输入而不是已经描述的那些，那么你需要为要使用的机制定义 _ 回调 _ 对象，你可以查看 [JNDI 教程](https://docs.oracle.com/javase/jndi/tutorial/ldap/security/callback.html)中的回调示例。本课程的下一部分将讨论如何使用 SASL Digest-MD5 身份验证机制。 JNDI 教程中介绍了 [SASL 策略](https://docs.oracle.com/javase/jndi/tutorial/ldap/security/sasl.html)， [GSS API（Kerberos v5）](https://docs.oracle.com/javase/jndi/tutorial/ldap/security/gssapi.html)和 [CRAM-MD5](https://docs.oracle.com/javase/jndi/tutorial/ldap/security/crammd5.html) 机制。