对于最新的稳定版本,请使用 Spring Security Kerberos 2.1.0! |
附录
附录 A:本文档中使用的材料
虚拟 UserDetailsService,因为我们没有真正的 用户源。
public class DummyUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
return new User(username, "notUsed", true, true, true, true,
AuthorityUtils.createAuthorityList("ROLE_USER"));
}
}
附录 B:Kerberos 速成课程
在任何身份验证过程中,通常都有三个参与方 涉及。
首先是client
有时是客户端计算机,但在大多数
在场景中,它是坐在计算机上的实际用户,并且
尝试访问资源。然后是resource
用户正在尝试
以访问。在此示例中,它是一个 Web 服务器。
然后有一个Key Distribution Center
或KDC
.在
Windows 环境,这将是一个Domain Controller
.KDC
是
一个真正将一切结合在一起的 IT 部门,因此是最
关键组件。正因为如此,它也是
被视为单点故障。
最初,当Kerberos
environment 为 setup 和 domain user
principals 创建到数据库中,加密密钥也是
创建。这些加密密钥基于共享密钥(即用户
password) 和实际密码永远不会以明文形式保存。
有效KDC
拥有自己的密钥和域用户的其他密钥。
有趣的是,在resource
以及KDC
在身份验证过程中。
当客户端想要使用resource
it 优先
需要与KDC
.Client
将制作一个特殊包裹
其中包含加密和未加密的部分。未加密的部分
包含,即有关用户的信息和加密部分 other
信息,这是协议的一部分。Client
将加密包
data 的 key 中。
什么时候KDC
从客户端 it 接收此身份验证包
检查这个client
声明来自未加密的部分,并且基于
它所使用的信息client
decrypt 密钥
它的数据库。如果此解密成功KDC
知道这个client
就是它声称的那个。
KDC 返回给客户端的是一个名为Ticket Granting
Ticket
它由 KDC 自己的私钥签名。稍后client
发回此票证,它可以尝试解密它,如果
作成功了 它知道这是一张票 它自己
最初签名并交给client
.
当客户端想要获取可用于身份验证的票证时
with a service,TGT
发送到KDC
然后签署服务工单
替换为服务自己的密钥。此时,彼此之间的信任client
和service
已创建。此服务票证包含数据
其中只有service
本身能够解密。
什么时候client
正在使用之前发送的服务进行身份验证
收到了服务票证,然后认为我没有
对这个家伙一无所知,但他给我一张认证票。
什么service
接下来可以做的是尝试解密该票证,如果
作成功了,它知道只有知道我的另一方
credentials 是KDC
因为我信任他,所以我也可以信任他
这个客户就是他声称的那个。
附录 C:设置 Kerberos 环境
执行 Kerberos 环境的生产设置超出了 本文档但本附录提供了一些帮助来帮助您 started 用于设置开发所需的组件。
设置 MIT Kerberos
第一个作是设置一个新的 Realm 和一个数据库。
# kdb5_util create -s -r EXAMPLE.ORG
Loading random data
Initializing database '/var/lib/krb5kdc/principal' for realm 'EXAMPLE.ORG',
master key name 'K/[email protected]'
You will be prompted for the database Master Password.
It is important that you NOT FORGET this password.
Enter KDC database master key:
Re-enter KDC database master key to verify:
kadmin
命令可用于管理 Kerberos 环境,但
您还不能使用它,因为数据库中没有 admin 用户。
root@neo:/etc/krb5kdc# kadmin
Authenticating as principal root/[email protected] with password.
kadmin: Client not found in Kerberos database while initializing
kadmin interface
让我们使用kadmin.local
命令创建一个。
root@neo:/etc/krb5kdc# kadmin.local
Authenticating as principal root/[email protected] with password.
kadmin.local: listprincs
K/[email protected]
kadmin/[email protected]
kadmin/[email protected]
kadmin/[email protected]
krbtgt/[email protected]
kadmin.local: addprinc root/[email protected]
WARNING: no policy specified for root/[email protected]; defaulting to
no policy
Enter password for principal "root/[email protected]":
Re-enter password for principal "root/[email protected]":
Principal "root/[email protected]" created.
然后通过修改kadm5.acl
文件并重新启动 Kerberos
服务业。
# cat /etc/krb5kdc/kadm5.acl
# This file Is the access control list for krb5 administration.
*/admin *
现在您可以使用kadmin
与之前创建的root/admin
主要。让我们创建我们的第一个用户user1
.
kadmin: addprinc user1
WARNING: no policy specified for [email protected]; defaulting to no
policy
Enter password for principal "[email protected]":
Re-enter password for principal "[email protected]":
Principal "[email protected]" created.
让我们创建第二个用户user2
并导出 keytab 文件。
kadmin: addprinc user2
WARNING: no policy specified for [email protected]; defaulting to no
policy
Enter password for principal "[email protected]":
Re-enter password for principal "[email protected]":
Principal "[email protected]" created.
kadmin: ktadd -k /tmp/user2.keytab [email protected]
Entry for principal [email protected] with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/tmp/user2.keytab.
Entry for principal [email protected] with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/tmp/user2.keytab.
Entry for principal [email protected] with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/tmp/user2.keytab.
Entry for principal [email protected] with kvno 2, encryption type des-cbc-crc added to keytab WRFILE:/tmp/user2.keytab.
让我们为 tomcat 创建一个服务票证,并将凭证导出到
名为tomcat.keytab
.
kadmin: addprinc -randkey HTTP/[email protected]
WARNING: no policy specified for HTTP/[email protected];
defaulting to no policy
Principal "HTTP/[email protected]" created.
kadmin: ktadd -k /tmp/tomcat.keytab HTTP/[email protected]
Entry for principal HTTP/[email protected] with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/tmp/tomcat2.keytab.
Entry for principal HTTP/[email protected] with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/tmp/tomcat2.keytab.
Entry for principal HTTP/[email protected] with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/tmp/tomcat2.keytab.
Entry for principal HTTP/[email protected] with kvno 2, encryption type des-cbc-crc added to keytab WRFILE:/tmp/tomcat2.keytab.
设置 Windows 域控制器
这是使用Windows Server 2012 R2
互联网上到处都是如何设置 Windows AD 的好文章和视频 但是这两个是非常有用的 Rackspace 和 Microsoft 技术网。 |
-
正常的域控制器和 Active Directory 设置已完成。
-
使用的 dns 域
example.org
和 Windows 域EXAMPLE
. -
我创建了各种域用户,例如
user1
,user2
,user3
,tomcat
并将密码设置为Password#
.
我最终还将我的 VM 的所有 IP 添加到 AD 的 dns 服务器中,以便 以免造成任何麻烦。
Name: WIN-EKBO0EQ7TS7.example.org
Address: 172.16.101.135
Name: win8vm.example.org
Address: 172.16.101.136
Name: neo.example.org
Address: 172.16.101.1
服务主体名称 (SPN) 需要使用HTTP
以及
服务器名称neo.example.org
运行 Tomcat servlet 容器的位置。这
用于tomcat
domain user 及其keytab
然后用作
service 凭证。
PS C:\> setspn -A HTTP/neo.example.org tomcat
我导出了密钥表文件,该文件被复制到运行 tomcat 的 linux 服务器。
PS C:\> ktpass /out c:\tomcat.keytab /mapuser [email protected] /princ HTTP/[email protected] /pass Password# /ptype KRB5_NT_PRINCIPAL /crypto All
Targeting domain controller: WIN-EKBO0EQ7TS7.example.org
Using legacy password setting method
Successfully mapped HTTP/neo.example.org to tomcat.
附录 D:故障排除
本附录提供有关故障排除的一般信息 错误和问题。
如果您认为环境和配置设置正确,请执行 仔细检查并要求其他人检查可能的明显错误 或错别字。Kerberos 设置通常非常脆弱,但事实并非如此 总是很容易调试问题所在。 |
GSSException: Failure unspecified at GSS-API level (Mechanism level:
Invalid argument (400) - Cannot find key of appropriate type to
decrypt AP REP - RC4 with HMAC)
如果您看到 abore 错误指示缺少密钥类型,则会发生这种情况
具有两种不同的用例。首先,您的 JVM 可能不支持
适当的加密类型,或者在krb5.conf
文件。
default_tkt_enctypes = rc4-hmac
default_tgs_enctypes = rc4-hmac
第二种情况不太明显且难以追踪,因为它会导致
变成相同的错误。这个特定的GSSException
如果你
只是没有所需的加密密钥,这可能会导致
由于 Kerberos 服务器中的错误配置或简单的拼写错误
主要。
在大多数系统中,所有命令和库都会搜索 Kerberos 从默认位置或特殊位置配置 就像 JDK 一样。这很容易混淆,尤其是在使用 unix 工作时 系统,这些系统可能已经具有与 MIT 一起使用的默认设置 kerberos 的 Windows 域。
这是一个具体的例子,会发生什么ldapsearch
尝试
使用 Kerberos 身份验证查询 Windows AD。
$ ldapsearch -H ldap://WIN-EKBO0EQ7TS7.example.org -b "dc=example,dc=org"
SASL/GSSAPI authentication started
ldap_sasl_interactive_bind_s: Local error (-2)
additional info: SASL(-1): generic failure: GSSAPI Error:
Unspecified GSS failure. Minor code may provide more information
(No Kerberos credentials available)
嗯,这看起来不太好,一个简单的迹象表明我没有 拥有有效的 Kerberos 票证,如下所示。
$ klist
klist: Credentials cache file '/tmp/krb5cc_1000' not found
我们已经有一个从 Windows AD 导出的密钥表文件以供使用 在 Linux 上运行 tomcat。让我们尝试使用它来进行身份验证 使用 Windows AD。
您可以有一个专用的配置文件,该文件通常可以与 通过系统属性的本机 Linux 命令和 JVM。
$ cat krb5.ini
[libdefaults]
default_realm = EXAMPLE.ORG
default_keytab_name = /tmp/tomcat.keytab
forwardable=true
[realms]
EXAMPLE.ORG = {
kdc = WIN-EKBO0EQ7TS7.example.org:88
}
[domain_realm]
example.org=EXAMPLE.ORG
.example.org=EXAMPLE.ORG
让我们使用该配置和 keytab 来获取初始凭证。
$ env KRB5_CONFIG=/path/to/krb5.ini kinit -kt tomcat.keytab HTTP/[email protected]
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: HTTP/[email protected]
Valid starting Expires Service principal
26/03/15 09:04:37 26/03/15 19:04:37 krbtgt/[email protected]
renew until 27/03/15 09:04:37
让我们看看如果我们现在尝试对 Windows AD。
$ ldapsearch -H ldap://WIN-EKBO0EQ7TS7.example.org -b "dc=example,dc=org"
SASL/GSSAPI authentication started
ldap_sasl_interactive_bind_s: Local error (-2)
additional info: SASL(-1): generic failure: GSSAPI Error:
Unspecified GSS failure. Minor code may provide more information
(KDC returned error string: PROCESS_TGS)
这可能仅仅是因为ldapsearch
越来越困惑和简单
使用错误的配置。你可以看出来ldapsearch
要使用
不同的配置KRB5_CONFIG
env 变量,就像我们一样
与kinit
.您还可以使用KRB5_TRACE=/dev/stderr
获取
本机库正在执行的作的更详细输出。
$ env KRB5_CONFIG=/path/to/krb5.ini ldapsearch -H ldap://WIN-EKBO0EQ7TS7.example.org -b "dc=example,dc=org"
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: HTTP/[email protected]
Valid starting Expires Service principal
26/03/15 09:11:03 26/03/15 19:11:03 krbtgt/[email protected]
renew until 27/03/15 09:11:03
26/03/15 09:11:44 26/03/15 19:11:03
ldap/[email protected]
renew until 27/03/15 09:11:03
在上面,您可以通过查看来了解如果查询成功会发生什么
Kerberos 门票。现在,您可以尝试进一步的查询命令
即,如果您使用KerberosLdapContextSource
.
$ ldapsearch -H ldap://WIN-EKBO0EQ7TS7.example.org \
-b "dc=example,dc=org" \
"(| ([email protected])
([email protected]))" \
dn
...
# test user, example.org
dn: CN=test user,DC=example,DC=org
附录 E:为 Spnego 协商配置浏览器
火狐浏览器
完成以下步骤以确保您的 Firefox 浏览器 enabled 以执行 Spnego 身份验证。
-
打开 Firefox。
-
在 address 字段中,键入 about:config。
-
在 filter/search 中,键入 negotiate。
-
参数 network.negotiate-auth.trusted-uris 可以设置为 default https://,这不适合您。一般而言 如果 Kerberos 需要委派。
-
建议使用
https
用于所有通信。
铬
使用 Google Chrome 时,您通常需要设置命令行参数 将 Chrome 服务器列入白名单的订单将进行协商。
-
在 Windows 计算机(客户端)上:Chrome 会与 Internet Explorer,因此,如果所有更改都应用于 IE(如所述 在 E.3 中),则无需通过命令行参数传递任何内容。
-
在 Linux/Mac OS 计算机(客户端)上:命令行参数
--auth-negotiate-delegate-whitelist
应仅在 Kerberos 时使用 delegation 是必需的(否则不要设置此参数)。 -
建议使用
https
用于所有通信。
--auth-server-whitelist="*.example.com"
--auth-negotiate-delegate-whitelist="*.example.com"
您可以通过在 Chrome 的地址栏中键入 chrome://policy/ 来查看启用了哪些策略。
在 Linux 中,Chrome 还会从/etc/opt/chrome/policies/managed
目录。
{
"AuthServerWhitelist" : "*.example.org",
"AuthNegotiateDelegateWhitelist" : "*.example.org",
"DisableAuthNegotiateCnameLookup" : true,
"EnableAuthNegotiatePort" : true
}