//  ========================================================================
//  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
//  ========================================================================
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================

[[spnego-support]]
=== Spnego Support

Spnego or Simple and Protected GSSAPI Negotiation Mechanism is a way for
users to be seamlessly authenticated when running on a Windows or Active
Directory based network. Jetty supports this type of authentication and
authorization through the JDK so you must be using a JDK that supports
it, which recent versions of Java 6 and 7 do. Also important to note is
that this is an incredibly fragile setup where everything needs to be
configured just right for things to work, otherwise it can fail in fun
and exciting, not to mention obscure ways.

There is a substantial amount of configuration and testing required to
enable this feature as well as knowledge and access to central systems
on a Windows network such as the Active Domain Controller and the
ability to create and maintain service users.

==== Configuring Jetty and Spnego

To run with spengo enabled the following command line options are
required:

....

-Djava.security.krb5.conf=/path/to/jetty/etc/krb5.ini \
-Djava.security.auth.login.config=/path/to/jetty/etc/spnego.conf \
-Djavax.security.auth.useSubjectCredsOnly=false
 
    
....

For debugging the spengo authentication the following options are very
helpful:

....

-Dorg.eclipse.jetty.LEVEL=debug \
-Dsun.security.spnego.debug=all

    
....

Spengo Authentication must be enabled in the webapp in the following
way. The name of the role will be different for your network.

[source, xml, subs="{sub-order}"]
----

 <security-constraint>
   <web-resource-collection>
     <web-resource-name>Secure Area</web-resource-name>
     <url-pattern>/secure/me/*</url-pattern>
   </web-resource-collection>
   <auth-constraint>
     <!-- this is the domain that the user is a member of -->
     <role-name>MORTBAY.ORG</role-name>  
   </auth-constraint>
 </security-constraint>
 <login-config>
   <auth-method>SPNEGO</auth-method>
   <realm-name>Test Realm</realm-name>
   <!-- optionally to add custom error page -->
   <spnego-login-config>
     <spengo-error-page>/loginError.html?param=foo</spnego-error-page>
   </spnego-login-config>
 </login-config>

      
----

A corresponding UserRealm needs to be created either programmatically if
embedded, via the jetty.xml or in a context file for the webapp.

This is what the configuration within a jetty xml file would look like.

[source, xml, subs="{sub-order}"]
----

  <Call name="addBean">
     <Arg>
       <New class="org.eclipse.jetty.security.SpnegoLoginService">
         <Set name="name">Test Realm</Set>
         <Set name="config"><Property name="jetty.home" default="."/>/etc/spnego.properties</Set>
       </New>
     </Arg>
   </Call>

      
----

This is what the configuration within a context xml file would look
like.

[source, xml, subs="{sub-order}"]
----

 <Get name="securityHandler">
   <Set name="loginService">
     <New class="org.eclipse.jetty.security.SpnegoLoginService">
       <Set name="name">Test Realm</Set> 
       <Set name="config">
        <SystemProperty name="jetty.home" default="."/>/etc/spnego.properties
      </Set>
     </New>
   </Set>
   <Set name="checkWelcomeFiles">true</Set>
 </Get>

      
----

There are a number of important configuration files with spnego that are
required. The default values for these configuration files from this
test example are found in the jetty-distribution.

spnego.properties::
  configures the user realm with runtime properties
krb5.ini::
  configures the underlying kerberos setup
spnego.conf::
  configures the glue between gssapi and kerberos

It is important to note that the keytab file referenced in the krb5.ini
and the spengo.conf files needs to contain the keytab for the targetName
for the http server. To do this use a process similar to this:

On the windows active domain controller run:

[source, screen, subs="{sub-order}"]
....

$ setspn -A HTTP/linux.mortbay.org ADUser

    
....

To create the keytab file use the following process:

[source, screen, subs="{sub-order}"]
....

$ ktpass -out c:\dir\krb5.keytab -princ HTTP/linux.mortbay.org@MORTBAY.ORG -mapUser ADUser -mapOp set -pass ADUserPWD -crypto RC4-HMAC-NT -pType KRB5_NT_PRINCIPAL

    
....

This step should give you the keytab file which should then be copied
over to the machine running this http server and referenced from the
configuration files. For our testing we put the keytab into the etc
directory of jetty and referenced it from there.

==== Configuring Firefox

The follows steps have been required to inform Firefox that it should
use a negotiation dialog to authenticate.

1.  browse to about:config and agree to the warnings
2.  search through to find the 'network' settings
3.  set network.negotiate-auth.delegation-uris to http://,https://
4.  set network.negotiate-auth.trusted-uris to http://,https://

==== Configuring Internet Explorer

The follows steps have been required to inform Internet Explorer that it
should use a negotiation dialog to authenticate.

1.  Tools -> Options -> Security -> Local Intranet -> Sites (everything
should be checked here)
2.  Tools -> Options -> Security -> Local Intranet -> Sites -> Advanced
(add url to server (http:// and/or https:// use the hostname!)
3.  Tools -> Options -> Security -> Local Intranet -> Sites -> Advanced
-> Close
4.  Tools -> Options -> Security -> Local Intranet -> Sites -> Ok
5.  Tools -> Options -> Advanced -> Security (in the checkbox list)
6.  locate and check 'Enable Integrated Windows Authentication'
7.  Tools -> Options -> Advanced -> Security -> Ok
8.  close IE then reopen and browse to your spengo protected resource

____
[NOTE]
You must go to the hostname and not the IP, if you go to the IP it will default to NTLM authentication...the following conditions must be
 true for Spnego authentication to work.
+
* You must be within the Intranet Zone of the network
* Accessing the server using a Hostname rather then IP
* Integrated Windows Authentication in IE is enabled and the host is trusted in Firefox
* The server is not local to the browser, it can't be running on localhost.
* The client's Kerberos system is authenticated to a domain controller
____
