分享

如何使用 Kerberos/SPNEGO 和 Oracle WebLogic Server 配置基于浏览器的 SSO

 sven_ 2015-08-10

如何使用 Kerberos/SPNEGO 和 Oracle WebLogic Server 配置基于浏览器的 SSO


作者:Abhijit Patil

Oracle WebLogic Server 为 Microsoft 客户端使用 Kerberos 进行一次性登录提供了全面的解决方案。

2012 年 5 月发布

本文介绍如何让 Microsoft 客户端(在本例中为浏览器)在 Windows 域内使用 Kerberos 进行身份验证之后能够凭借同样的凭证在 Oracle WebLogic Server (Oracle WebLogic Server) 域中透明地通过身份验证,而不必再次键入口令。

该特性旨在让客户端浏览器能够访问 Oracle WebLogic Server 上的受保护资源,并通过 SPNEGO 票证透明地向 Oracle WebLogic Server 提供来自 Kerberos 数据库的身份验证信息。注意,该特性还适用于 Java SE 客户端。Oracle WebLogic Server 将能够识别票证,并从中提取信息。然后该服务器将使用该信息进行身份验证,如果被验证的用户有权访问资源,则允许其访问该资源。(Kerberos 仅负责身份验证;授权仍由 Oracle WebLogic Server 处理。)

以下配置用于演示此场景:

  • 浏览器客户端 (MACHINEA):Windows 7 Enterprise(已安装 IE 9.0/Firefox 7.0.1/Chrome 17)
  • Oracle WebLogic Server (MACHINEB) — Linux 版本 2.6.18-238.0.0.0.1.el5xen,已安装 Oracle WebLogic Server 12c (Oracle JDK 1.6)。
  • KDC (MACHINEC) — Windows Server 2008 R2 Enterprise SP1

注意,尽管本场景使用以上配置,但 SPNEGO 应适用于更早版本的浏览器、Oracle WebLogic Server、JDK 等。

weblogic-sso-kerberos-f1
图 1:SPNEGO/Kerberos 场景的计算机配置

下面的步骤列表详细分解了上图所示跨平台身份验证设计的过程。

  1. 当登录用户 (MACHINEA) 从 Oracle WebLogic Server (MACHINEB) 请求资源时,将发送一个初始 HTTP GET 谓词。
  2. 运行 SPNEGO 令牌处理程序代码的 Oracle WebLogic Server (MACHINEB) 要求进行身份验证并发出 401 Access Denied, WWW-Authenticate:Negotiate 响应。
  3. 客户端(MACHINEA 上的浏览器)于是从 TGS/KDC (MACHINEC) 请求会话票证。
  4. TGS/KDC (MACHINEC) 向客户端提供必要的 Kerberos 票证(假设客户端已获得授权),票证封装在 SPNEGO 令牌中。
  5. 客户端重新发送 HTTP GET 请求 + Negotiate SPNEGO Token(该令牌包含在 Authorization:Negotiate base64(token) 标头中)。
  6. Oracle WebLogic Server 的 SPNEGO 令牌处理程序代码接受该令牌并通过 GSS API 进行处理,对用户进行身份验证并以所请求的 URL 进行响应。

KDC 配置

Windows 2008 Server 域控制器可以充当基于 Kerberos 的客户端和主机系统的 Kerberos 密钥分发中心 (KDC) 服务器。

为 Oracle WebLogic Server 服务器创建一个帐户

在这一步中,在 Active Directory 上创建一个代表 Oracle WebLogic Server 的 Kerberos 主体。主体名称将类似于 name@REALM.NAME,其中 REALM.NAME 是领域的管理名称。在本例中,主体名称将是 negotiatetestserver@SECURITYQA.COM。托管 Oracle WebLogic Server 的计算机不必是 SECURITYQA.com 域的一部分。在本例中,它是 OTHERDOM.DOM 域的一部分。在 AD 中,帐户类型应为“User”而不是“Computer”。

在 Active Directory 中为 Oracle WebLogic Server 实例创建一个用户“negotiatetestserver”

  • 启动 Programs/Administrative Tools/Active Directory Users and Computers 工具。
  • 右键单击 Users 节点并选择 New/User。(不要选择 Machine。)
  • 在“Full Name”域和“Logon Name”域中键入用户“negotiatetestserver”。
  • 单击 Next,并输入口令(当然,还要记住它)
  • 验证未选中任何口令选项。单击 Next
  • 单击 Finish


weblogic-sso-kerberos-f2
图 2:Account 选项卡,显示 KDC 上“negotiatetestserver”用户的属性

按照 Kerberos 协议配置用户

  • 在左侧窗格的 Users 树中找到新创建的用户并双击它。
  • 在用户“negotiatestserver”的“Account”选项卡上,
    • 对于 AES128-SHA1 加密强度,确保选中 This account supports AES 128 bit encryption;取消选中所有其他选项(password never expires 除外)。
    • 对于 AES256-SHA1 加密强度,确保选中 This account supports AES 256 bit encryption;取消选中所有其他选项(password never expires 除外)。
    • 对于 RC4-HMAC-NT 加密强度,确保取消选中所有选项(password never expires 除外)。
    • 对于 DES-CBC-CRC 加密强度,确保选中 Use Kerberos DES encryption types for this account 并确保取消选中所有选项(password never expires 除外)。
  • 单击 OK

定义服务主体名称并为该服务创建 Keytab

SPN(服务主体名称)是标识一个服务实例的唯一名称,与运行该服务实例的登录帐户关联。SPN 用于客户端与托管特定服务的服务器之间的相互身份验证过程。客户端根据它尝试连接的服务的 SPN 找到计算机帐户。

ktpass 命令行工具允许管理员将非 Windows Server Kerberos 服务配置为 Windows Server Active Directory 中的安全主体。Ktpass 在 Active Directory 中配置该服务的服务器主体名称并生成一个 MIT 式的 Kerberos“keytab”文件,其中包含该服务的共享密钥。该工具允许支持 Kerberos 身份验证的基于 UNIX 的服务使用 Windows Server Kerberos KDC 服务提供的互操作特性。

使用以下命令配置 SPN(针对 AES128 加密强度)并生成 keytab 文件:

C:\Users\bt>ktpass -out negotiatetestserver_keytab -princ negotiatetestserver@SECURITYQA.COM -mapUser negotiatetestserver -kvno 0 -crypto  AES128-SHA1 -pass <password> -p type KRB5_NT_PRINCIPAL

将生成的 keytab 文件 (negotiatetestserver_keytab) 保存在安全位置,并将其导出到 Oracle WebLogic Server 的域目录。(在本例中,将此文件传输到 MachineB。)稍后说明的 JAAS(Java 身份验证和授权服务)配置文件将引用此文件。

Oracle WebLogic Server 服务器配置

对该服务器的配置有以下重要要求:

  • 在 Kerberos 领域中,必须通过 Kerberos 主体(我们在上一节中已定义)表示服务器。
  • 服务器需要能够访问 KDC。
  • Oracle WebLogic Server 进程需要能够访问其在 Kerberos 中帐户的凭证。
  • Oracle WebLogic Server 必须配置成可识别请求中的 spnego 令牌。

创建 JAAS 登录文件

JAAS 允许动态配置登录模块。我们需要指定一个 JAAS 配置文件以指定使用的登录模块。

使用以下内容在 Oracle WebLogic Server 域目录中创建一个名为 krb5Login.conf 的文件:

对于使用 Oracle JDK 的 Oracle WebLogic Server:

com.sun.security.jgss.initiate {
  com.sun.security.auth.module.Krb5LoginModule required principal="negotiatetestserver@SECURITYQA.COM"
useKeyTab=true keyTab=negotiatetestserver_keytab
   storeKey=true debug=true;
};
com.sun.security.jgss.krb5.accept {
  com.sun.security.auth.module.Krb5LoginModule required principal="negotiatetestserver@SECURITYQA.COM"
useKeyTab=true keyTab=negotiatetestserver_keytab
   storeKey=true debug=true;
};

对于使用 IBM JDK 的 Oracle WebLogic Server:

com.ibm.security.jgss.initiate {
  com.ibm.security.auth.module.Krb5LoginModule required principal="negotiatetestserver@SECURITYQA.COM"
useKeyTab=true keyTab=negotiatetestserver_keytab storeKey=true debug=true;
};
com.ibm.security.jgss.accept {
  com.ibm.security.auth.module.Krb5LoginModule required principal="negotiatetestserver@SECURITYQA.COM"
useKeyTab=true keyTab=negotiatetestserver_keytab storeKey=true debug=true;
};

使用启动参数进行 Oracle WebLogic Server 的 Kerberos 身份验证

这里假设您已将第 2 步中生成的 keytab 文件“negotiatetestserver_keytab”传送到 Oracle WebLogic Server 上的域目录。如果 Oracle WebLogic Server 使用 Oracle JDK,请在 Oracle WebLogic Server java 命令行指定以下选项:

-Dsun.security.krb5.debug=true -Djava.security.krb5.realm=SECURITYQA.COM -Djava.security.krb5.kdc=MACHINEC -Djava.security.auth.login.config= krb5Login.conf -Djavax.security.auth.useSubjectCredsOnly=false

对于使用 IBM JDK 的 Oracle WebLogic Server,在 Oracle WebLogic Server java 命令行指定以下选项:


-Dcom.ibm.security.jgss.debug=all -Djava.security.krb5.realm=SECURITYQA.COM -Djava.security.krb5.kdc=MACHINEC -Djava.security.auth.login.config= krb5Login.conf -Djavax.security.auth.useSubjectCredsOnly=false


配置身份断言提供程序

WebLogic Server 包括一个安全提供程序(Negotiate Identity Assertion 提供程序)以支持 Microsoft 客户端一次性登录 (SSO)。此身份断言提供程序对 SPNEGO(简单和受保护协商)令牌进行解码以获取 Kerberos 令牌,验证 Kerberos 令牌并将 Kerberos 令牌映射到 WebLogic 用户。您需要在 WebLogic 安全领域内配置 Negotiate Identity Assertion 提供程序以便支持 Microsoft 客户端进行 SSO。请参见配置 Negotiate Identity Assertion 提供程序

安装 Java Cryptography Extension (JCE) 无限强度权限策略文件

(此步骤仅适用于打算使用 AES256-SHA1 加密强度的情况。对于所有其他加密强度,请跳过此步骤)。您需要下载和安装此文件包,它提供的“无限强度”策略文件不含对加密强度的任何限制。

  • 对于 Oracle JDK 6:在此下载 Java Cryptography Extension (JCE) 无限强度权限策略文件 6。
  • 对于 Oracle JDK 7:在此下载 Java Cryptography Extension (JCE) 无限强度权限策略文件 7。使用下载的 zip 文件内的 2 个 jar 文件覆盖“<JAVA_HOME>/jre/lib/security”目录下的 2 个 jar 文件。
  • 对于 IBM JDK 6 及更高版本:在此下载 Java Cryptography Extension (JCE) 无限强度权限策略文件 7 并按照安装说明进行操作

在 Web 应用程序中定义安全约束

为了进行身份验证,必须在参与客户端一次性登录的 Web 应用程序中,对被访问的资源(JSP 或 Servlet)实施保护。

以下是本例中所用的 servlet 代码 (SimpleTestServlet.java):

package wlstest.functional.security.negotiate.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpUtils;

public class SimpleTestServlet extends HttpServlet
{
    public void service(HttpServletRequest req, HttpServletResponse res)
        throws ServletException, IOException
    {
        res.setContentType("text/html");
        PrintWriter out = res.getWriter();

        out.println("<html>");
        out.println("<head><title>Simple Test Servlet</title></head>");
        out.println("<body>");
        out.println("<h3>Requested URL:</h3>");
        out.println("<pre>");
        out.println(HttpUtils.getRequestURL(req).toString());
        out.println("</pre>");
   
        Enumeration theEnum = getServletConfig().getInitParameterNames();
        if (theEnum != null)
        {
            boolean first = true;
            while (theEnum.hasMoreElements())
            {
                if (first)
                {
                    out.println("<h3>Init Parameters</h3>");
                    out.println("<pre>");
                    first = false;
                }
                String param = (String) theEnum.nextElement();
                out.println(" "+param+": "+getInitParameter(param));
            }
            out.println("</pre>");
        }

        out.println("<h3>Request information:</h3>");
        out.println("<pre>");

        print(out, "Request method", req.getMethod());
        print(out, "Request URI", req.getRequestURI());
        print(out, "Request protocol", req.getProtocol());
        print(out, "Servlet path",     req.getServletPath());
        print(out, "Path info",        req.getPathInfo());
        print(out, "Path translated",  req.getPathTranslated());
        print(out, "Query string",     req.getQueryString());
        print(out, "Content length",   req.getContentLength());
        print(out, "Content type",     req.getContentType());
        print(out, "Server name",      req.getServerName());
        print(out, "Server port",      req.getServerPort());
        print(out, "Remote user",      req.getRemoteUser());
        print(out, "Remote address",   req.getRemoteAddr());
        print(out, "Remote host",      req.getRemoteHost());
        print(out, "Scheme",           req.getScheme());
        print(out, "Authorization scheme", req.getAuthType());
        print(out, "Request scheme", req.getScheme());
        out.println("</pre>");

        Enumeration e = req.getHeaderNames();
        if (e.hasMoreElements())
        {
            out.println("<h3>Request headers:</h3>");
            out.println("<pre>");
            while (e.hasMoreElements())
            {
                String name = (String)e.nextElement();
                out.println(" " + name + ": " + req.getHeader(name));
            }
            out.println("</pre>");
        }

        e = req.getParameterNames();
        if (e.hasMoreElements())
        {
            out.println("<h3>Servlet parameters (Single Value style):</h3>");
            out.println("<pre>");
            while (e.hasMoreElements())
            {
                String name = (String)e.nextElement();
                out.println(" " + name + " = " + req.getParameter(name));
            }
            out.println("</pre>");
        }
   
        e = req.getParameterNames();
        if (e.hasMoreElements())
        {
            out.println("<h3>Servlet parameters (Multiple Value style):</h3>");
            out.println("<pre>");
            while (e.hasMoreElements())
            {
                String name = (String)e.nextElement();
                String vals[] = (String []) req.getParameterValues(name);
                if (vals != null)
                {
                    out.print("<b> " + name + " = </b>");
                    out.println(vals[0]);
                    for (int i = 1; i<vals.length; i++)
                        out.println("           " + vals[i]);
                }
                out.println("<p>");
            }
            out.println("</pre>");
        }

        out.println("<h3>Request Attributes:</h3>");
        e = req.getAttributeNames();
        if (e.hasMoreElements())
        {
            out.println("<pre>");
            while (e.hasMoreElements())
            {
                String name = (String)e.nextElement();
                Object o = req.getAttribute(name);
                if (o == null) continue;
                out.println(" " + name + ": type=" + o.getClass().getName() + " str='" + o.toString() + "'");
            }
            out.println("</pre>");
        }
        out.println("</body></html>");
    }

    private void print (PrintWriter out, String name, String value)
    {
        out.print(" " + name + ": ");
        out.println(value == null ? "<none>" : value);
    }

    private void print (PrintWriter out, String name, int value)
    {
        out.print(" " + name + ": ");
        if (value == -1)
            out.println("<none>");
        else
            out.println(value);
    }
}

web.xml 文件如下所示:


<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 1.2//EN" "http://java./j2ee/dtds/web-app_2_2.dtd">
<web-app>
    <display-name>Simple Test Servlet (Basic Auth)</display-name>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>BasicAuthSimpleTestServlet</web-resource-name>
            <url-pattern>/*</url-pattern>
            <url-pattern>/</url-pattern>
            <http-method>POST</http-method>
            <http-method>GET</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>negotiateAdminRole</role-name>
        </auth-constraint>
        <user-data-constraint>
            <description>no description</description>
            <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <security-role>
        <role-name>negotiateAdminRole</role-name>
    </security-role>

    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>default</realm-name>
    </login-config>

    <servlet>
        <servlet-name>BasicAuthSimpleTestServlet</servlet-name>
        <servlet-class>wlstest.functional.security.negotiate.servlet.SimpleTestServlet</servlet-class>
    </servlet>

    <welcome-file-list>
        <welcome-file>/BasicAuthSimpleTestServlet</welcome-file>
    </welcome-file-list>

    <servlet-mapping>
        <servlet-name>BasicAuthSimpleTestServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

角色 negotiateAdminRole 在 weblogic.xml 中进行定义,如下所示:

<!DOCTYPE weblogic-web-app PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN" "http://www./servers/wls810/dtd/weblogic810-web-jar.dtd">
<weblogic-web-app>
  <security-role-assignment>
    <role-name>negotiateAdminRole</role-name>
    <principal-name>negotiateAdmin</principal-name>
    <principal-name>Administrators</principal-name>
  </security-role-assignment>
</weblogic-web-app>

可以从这里下载本文所使用的 servlet 和相关文件。


客户端配置

为了进行一次性登录,需要一个经过身份验证的 Microsoft 客户端,它属于由您的领域所控制的域,并且请求访问 Oracle WebLogic Server 服务。

配置 Internet Explorer 浏览器

要配置 Internet Explorer 浏览器以使用 Windows 身份验证,请在 Internet Explorer 中按照以下过程进行配置。

配置本地内联网域

   1. 在 Internet Explorer 中,选择“工具”>“Internet 选项”。
   2. 选择“安全”选项卡。
   3. 选择“本地 Intranet”并单击“站点”。
   4. 在“本地 Intranet”弹出窗口中,确保选中“包括所有不使用代理服务器的站点”和“包括没有列在其他区域的所有本地(Intranet)站点”选项。

weblogic-sso-kerberos-f3
图 3:Internet Explorer“本地 Intranet”对话框


   5. 单击“高级”。
   6. 在“本地 Intranet”(高级)对话框中,添加参与 SSO 配置的 Oracle WebLogic Server 实例将使用的所有相对域名(例如 myhost.example.com)并单击“确定”。

weblogic-sso-kerberos-f4
图 4:Internet Explorer 的高级“本地 Intranet”对话框

配置内联网身份验证

   1. 选择“工具”>“Internet 选项”。
   2. 选择“安全”选项卡。
   3. 选择“本地 Intranet”并单击“自定义级别...”。.
   4. 在“安全设置”对话框中,滚动到“用户验证”部分。
   5. 选择“只在 Intranet 区域自动登录”。此选项可使用户不必重新输入登录凭证,这是该解决方案的一个重要部分。
   6. 单击“确定”。

weblogic-sso-kerberos-f5
图 5:配置内联网身份验证

验证代理设置

如果启用了代理服务器:
   1. 选择“工具”>“Internet 选项”。
   2. 选择“连接”选项卡并单击“局域网设置”。
   3. 验证代理服务器地址和端口号是否正确。
   4. 单击“高级”。
   5. 在“代理服务器设置”对话框中,确保在“例外情况”域中输入所有需要的域名。
   6. 单击“确定”关闭“代理服务器设置”对话框。

配置 Mozilla Firefox 浏览器

要配置 Firefox 浏览器使用 Windows 集成身份验证,请完成以下步骤:
   1. 启动 Firefox。
   2. 在位置栏中输入 about:config。
   3. 输入筛选字符串 network.negotiate。
   4. 按照下图所示设置首选项:

weblogic-sso-kerberos-f6
图 6:在 Firefox 中实现 Windows 集成身份验证所需的首选项

配置 Google Chrome 浏览器

对于 Chrome 浏览器,无需特别配置。

验证配置
  • 以“SECURITYQA.COM\<YOUR-USER-NAME)”用户身份登录到 MachineA(浏览器客户端)
  • 打开命令提示符窗口并运行“klist purge”。这是为了清除任何现有票证。

 

weblogic-sso-kerberos-f7
图 7:使用 klist 查看和清除票证

  • 打开浏览器并访问 Web 应用程序的 url。在本例中,将访问一个提供基本 HTTP 标头信息的 servlet:


weblogic-sso-kerberos-f8
图 8:在 SPNEGO 身份验证后显示 HTTP 信息的 Servlet

  • 如果 SSO 失败,将通过浏览器提示您输入用户名/口令。在本例中,需要检查 wls 服务器日志中的异常(参见下面的“故障排除”一节)。

 

weblogic-sso-kerberos-f9
图 9:在 SPNEGO 失败后浏览器提示输入用户名/口令

  • 确认浏览器是否发送 SPNEGO 令牌。查找消息“Authorization:Negotiate YII…”。这表示浏览器已经将 SPNEGO 令牌传递到 Oracle WebLogic Server。


    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip, deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Connection: keep-alive
    Authorization: Negotiate YIIGzQYGKwYBBQUCoIIGwTCCBr2gMDAuBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCNwICHgYKKwYBBAGCNwICCqKCB
    ocEggaDYIIGfwYJKoZIhvcSAQICAQBuggZuMIIGaqADAgEFoQMCAQ6iBwMFACAAAACjggUCYYIE/jCCBPqgAwIBBaEQGw5TRUNVUklUWVFBLkNPTaIrMCmgAwIBA
    qEiMCAbBEhUVFAbGGFkYzIxNzA3MTkudXMub3JhY2xlLmNvbaOCBLIwggSuoAMCARGhAwIBJKKCBKAEggSc8v4RphGvP7CinPf4mhiBzyfZWQG …

  • 还可以在 Oracle WebLogic Server 日志中检查 Oracle WebLogic Server 是否使用正确的加密。

    对于 Oracle JDK:

    >>>Pre-Authentication Data:
           PA-DATA type = 19
           PA-ETYPE-INFO2 etype = 17
    >>>Pre-Authentication Data:
           PA-DATA type = 2
           PA-ENC-TIMESTAMP
    >>>Pre-Authentication Data:
           PA-DATA type = 16
    >>>Pre-Authentication Data:
           PA-DATA type = 15
    AcquireTGT: PREAUTH FAILED/REQUIRED, re-send AS-REQ
    Updated salt from pre-auth = SECURITYQA.COMnegotiatetestserver
    >>>KrbAsReq salt is SECURITYQA.COMnegotiatetestserver
    Pre-Authenticaton: find key for etype = 17
    AS-REQ: Add PA_ENC_TIMESTAMP now
    >>> EType: sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType
    >>> KrbAsReq calling createMessage
    >>> KrbAsReq in createMessage
    >>> KrbKdcReq send: kdc=rno05089 UDP:88, timeout=30000, number of retries =3, #bytes=241
    >>> KDCCommunication: kdc=rno05089 UDP:88, timeout=30000,Attempt =1, #bytes=241
    >>> KrbKdcReq send: #bytes read=100
    >>> KrbKdcReq send: #bytes read=100
    >>> KdcAccessibility: remove rno05089
    >>> KDCRep: init() encoding tag is 126 req type is 11

    对于 IBM JDK:

    JGSS_DBG_PROV] getMechs: Mechanism(s) supported by provider IBMJGSSProvider
    [JGSS_DBG_PROV]   1.3.6.1.5.5.2
    [JGSS_DBG_PROV] getMechs: Mechanism(s) supported by provider IBMJGSSProvider
    [JGSS_DBG_PROV]   1.2.840.113554.1.2.2
    [JGSS_DBG_PROV] getMechs: Mechanism(s) supported by provider IBMSPNEGO
    [JGSS_DBG_PROV]   1.3.6.1.5.5.2
    [JGSS_DBG_PROV] getMechs: 2 unique mechanism(s) found
    [JGSS_DBG_PROV]   [0]: 1.3.6.1.5.5.2
    [JGSS_DBG_PROV]   [1]: 1.2.840.113554.1.2.2
    [JGSS_DBG_CTX] Default list of negotiable mechs:
                1.2.840.113554.1.2.2
                              
    [JGSS_DBG_CTX] AuthenticatorCache, scope of bucket122
    [JGSS_DBG_CTX] ticket enc type = rc4-hmac
    [JGSS_DBG_CTX] Successfully decrypted ticket
    [JGSS_DBG_CTX] Put authz info in cache
    [JGSS_DBG_CTX] Session key type = rc4-hmac
    [JGSS_DBG_CTX] Successfully decrypted authenticator
    [JGSS_DBG_CTX] Remote subkey type = rc4-hmac
    [JGSS_DBG_CTX] No delegated creds from peer
    [JGSS_DBG_CTX] Received channel binding checksum

故障排除

以下是 SPNEGO 配置期间可能遇到的典型异常以及解决方案:

  • kinit:Cannot contact any KDC for requested realm while getting initial credentials。计算机已成功发出请求,但 KDC 一直未响应。主机与 KDC 之间的网络可能中断,或者您位于防火墙后面。
  • javax.security.auth.login.LoginException:KrbException::Pre-authentication information was invalid (24) - Preauthentication failed。主体存在于 kerberos 中,但口令是错误的。这是一个口令问题。请仔细检查 keytab 的有效性,或所输入口令的有效性。
  • Exception:krb_error 0 Cannot retrieve key from keytab for principal xxx No error。您提供的 keytab 文件不是为该主体创建的,或者不存在这样的文件(这很容易核实)。如果该文件不存在,主体 xxx 可能存在于 AD 服务器中,但此 keytab 不是针对它的。另一方面,主体可能根本不存在。
  • javax.security.auth.login.LoginException:KrbException:KDC has no support for encryption type (14) - KDC has no support for encryption type。KDC 不支持所请求的加密类型。请选择所使用的 KDC 支持的加密类型。
  • <Debug> <SecurityDebug> <000000> <Found NTLM token when expecting SPNEGO>。这是很常见的错误。这表示 Oracle WebLogic Server 准备好提取 SPNEGO 令牌但无法在浏览器发送的请求中找到它。浏览器未正确配置以发送 spnego 令牌,请回到客户端配置,并仔细检查浏览器配置。您的 SPN 定义中存在某种错误:要么是未为此服务定义 SPN,要么是存在重复的 SPN,这意味着该 SPN 解析为与其关联的多个主体。
  • Exception:weblogic.security.providers.utils.NegotiateTokenException:GSSException:No valid credentials provided (Mechanism level:Attempt to obtain new ACCEPT credentials failed!)。这是很常见的异常,涵盖在 Oracle WebLogic Server 从 krb5Login.conf 文件加载 JAAS 配置到读取 keytab 和成功解码 SPNEGO 票证的过程中可能发生的任何错误。krb5Login.conf 文件无法找到或打开 — 仔细检查您为 Oracle WebLogic Server 指定它的方式,仔细检查是否存在以及权限。krb5Login.conf 中可能存在某种语法错误
  • java.lang.SecurityException at javax.security.auth.login.Configuration.getConfiguration。处理 JAAS 登录配置文件时遇到问题,可能是因为文件中的语法错误。请仔细检查该配置文件以发现错误。
  • GSSException:No valid credentials provided (Mechanism level:Attempt to obtain new INITIATE credentials failed!(null)) .. . Caused by:javax.security.auth.login.LoginException:Clock skew too great。Kerberos 要求以松散方式同步 KDC 和客户端上的时间。(默认在 5 分钟之内。)如果情况不是这样,就会产生此错误。请同步时钟(或请系统管理员同步)。

总结

SSO 跨平台身份验证是通过模拟使用 Kerberos 协议的原生 Windows 到 Windows 身份验证服务的协商行为来实现的。为使跨平台身份验证起作用,可以使用 Oracle WebLogic Server 解析 SPNEGO 令牌以提取 Kerberos 令牌,然后使用令牌进行身份验证,从而为最终用户提供透明的身份验证。

 


Abhijit Patil 是 Oracle Weblogic Server 组技术人员中的主要成员。他在各种 Weblogic Server 技术方面(包括安全性、Web 服务、服务器集群等)拥有 10 多年的工作经验。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多