This type of authentication is used in for example MS Windows Domains and can utilize SPNEGO, NTLM or Kerberos authentication.
The flow is the following (the same steps as are given here or here but in terms of browser / Web server interaction; also local developers please check here):
WWW-Authenticate: NEGOTIATE
.WWW-authorization: NEGOTIATE encoded-spnego-token
header to the HTTP request. Here encoded-spnego-token
is the SPNEGO token encoded in base64 which is basically a wrapper for the service ticket or NTLM block.HTTP/host.fqdn.com@KERBEROS-REALM
). This is done using the utility ktpass.exe
. One of its arguments is the keytab file location to save the secret key to. This keytab contains the list of pairs “service principal name → secret key” (which is derived from the Kerberos password). You should place this in a secure / non-public-access location. In JBoss you define the location of the the keytab via <application-policy>
in conf/login-config.xml
(is implementation-specific). The authenticator searches the keytab for a pre-configured service principal and retrieves the service secret key. In Tomcat, since you don't have login-config.xml
, you need to define this in a separate configuration file.
You can different approaches to implement SSO on Tomcat/JBoss here and here but:
$ curl --negotiate -u : http://service-id.company.org/status No resource method found for GET, return 405 with Allow header
O
flag reported for HTTP/service-id.company.org
means that ok-as-delegate is enabled: $ klist -f Ticket cache: FILE:/tmp/krb5cc Default principal: user123@REALM.COMPANY.ORG Valid starting Expires Service principal 02/07/17 16:02:30 02/08/17 05:02:23 HTTP/service-id.company.org@REALM.COMPANY.ORG renew until 02/08/17 16:02:22, Flags: FRAO
For description of flags check Kerberos ticket properties.
On Linux:
user123@host:~> ktutil ktutil: addent -password -p USER123@REALM.COMPANY.ORG -k 1 -e RC4-HMAC Password for USER123@REALM.COMPANY.ORG: ***** ktutil: wkt USER123.keytab ktutil: q
On Windows:
C:\> ktab -a USER123@REALM.COMPANY.ORG -k USER123.keytab Password for USER123@REALM.COMPANY.ORG:***** Done! Service key for USER123@REALM.COMPANY.ORG is saved in USER123.keytab
or
C:\> ktab -a USER123@REALM.COMPANY.ORG <password> -k USER123.keytab
Now this keytab can be used in KerberosRestTemplate
or in login.config
(to be passed to Java via -Djava.security.auth.login.config=login.config
):
// Login entry for a Kerberos client (initiator of a secure Kerberos connection): com.sun.security.jgss.krb5.initiate { com.sun.security.auth.module.Krb5LoginModule required storeKey=true useKeyTab=true doNotPrompt=true principal="USER123@REALM.COMPANY.ORG" keyTab="USER123.keytab" ; };
javax.security.auth.login.LoginException: No key to store
exception when using the keytab, then remove your ticket cache (rm /tmp/krb5cc_nnnn
).
user123
) provided that it matches principal
in login.config
.
-Dsun.security.krb5.debug=true
-Dsun.security.spnego.debug=true
debug=true
to module configuration in login.config
.Check also:
GSSException: Defective token detected
GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag) at sun.security.jgss.GSSHeader.<init>(GSSHeader.java:80) at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:287) at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:267) at org.eclipse.jetty.security.SpnegoLoginService.login(SpnegoLoginService.java:132) at org.eclipse.jetty.security.authentication.SpnegoAuthenticator.validateRequest(SpnegoAuthenticator.java:80)
Make sure you are using the browser from different machine as the server.
KrbException: Cannot find key of appropriate type to decrypt AP REP - RC4 with HMAC
KrbException: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - RC4 with HMAC at sun.security.krb5.KrbApReq.authenticate(KrbApReq.java:263) at sun.security.krb5.KrbApReq.<init>(KrbApReq.java:134) at sun.security.jgss.krb5.InitSecContextToken.<init>(InitSecContextToken.java:79) at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:724) at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:323) at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:267) at sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(SpNegoContext.java:874) at sun.security.jgss.spnego.SpNegoContext.acceptSecContext(SpNegoContext.java:541) at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:323) at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:267) at org.eclipse.jetty.security.SpnegoLoginService.login(SpnegoLoginService.java:132)
rc4-hmac
in Authentication Protocol (AP) reply. In order to use des-cbc-md5
one must activate the Use Kerberos DES encryption types for this account setting for server user account otherwise you get stuck in rc4-hmac
mode (which apparently is default in Win2K8 R2 and later).
References:
To be sure also check that des-cbc-md5
(Kerberos encryption type 3) is the one listed in your keytab file:
$ klist -e -k service.keytab [1] Service principal: HTTP/service-id.company.org@REALM.COMPANY.ORG KVNO: 3 Key type: 3
Otherwise you need to regenerate the keytab file (see Cannot find key of appropriate type to decrypt AP REP, "Cannot find key of appropriate type to decrypt" error again on W2k8).
javax.security.auth.useSubjectCredsOnly
? Setting the system property
javax.security.auth.useSubjectCredsOnly
to false allows us to relax the usual restriction of requiring a GSS mechanism to obtain necessary credentials from an existing Subject, set up by JAAS. When this restriction is relaxed, it allows the mechanism to obtain credentials from some vendor-specific location. For example, some vendors might choose to use the operating system's cache if one exists, while others might choose to read from a protected file on disk.When this restriction is relaxed, Sun Microsystem's Kerberos mechanism still looks for the credentials in the Subject associated with the thread's access control context, but if it doesn't find any there, it performs JAAS authentication using a Kerberos module to obtain new ones. The Kerberos module prompts you for a Kerberos principal name and password. Note that Kerberos mechanism implementations from other vendors may behave differently when this property is set to false. Consult their documentation to determine their implementation's behavior.
"Девица не хочет лезть в Окно" – device not compatible with Windows.