7
votes

Is it possible to do optional kerberos authentication?

What I want is: if the client (browser) is not on the domain it is redirected to a username/password web login. Otherwise it will do SPNEGO do Kerberos authentication.

Is there is any solution for this? If Yes what are the configurations we required?

3
You haven't stated what the web server environment is. I know how to do this for Apache on linux, but that may have nothing to do with what your environment is.Fred the Magic Wonder Dog

3 Answers

4
votes

Yes. You can do this. When the server receives an unauthenticated request, it replies with a 401 ("Authorization required") which is a header WWW-Authenticate set to Negotiate. If the Kerberos authentication fails, the server also send a 401 back.

Whenever the client fails to authenticate (for example, if it doesn't have any Kerberos credentials, or the authentication failed) the 401 page content will be shown.

So, to solve your problem, all you have to do is to include the login page on the 401 page.

0
votes

If you're need redirect to login page after server receives an unauthenticated request (like Elias Mårtenson said), you need configure spring security like this:

springSecurity.xml

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:sec="http://www.springframework.org/schema/security"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

<sec:http entry-point-ref="spnegoEntryPoint" >
    <sec:custom-filter ref="spnegoAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
    <sec:form-login login-page="/login.xhtml" default-target-url="/index.xhtml" />
    <sec:access-denied-handler error-page="/login.xhtml" />
</sec:http>

<bean id="spnegoAuthenticationProcessingFilter" class="org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter"> 
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

<sec:authentication-manager alias="authenticationManager">
    <sec:authentication-provider ref="kerberosServiceAuthenticationProvider" /> <!-- Used with SPNEGO -->
    <sec:authentication-provider ref="kerberosAuthenticationProvider"/> <!-- Used with form login -->
</sec:authentication-manager>

<bean id="kerberosAuthenticationProvider" class="org.springframework.security.extensions.kerberos.KerberosAuthenticationProvider">
    <property name="kerberosClient">
        <bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosClient">
            <property name="debug" value="true"/>
        </bean>
    </property>
    <property name="userDetailsService" ref="customUserDetailsService"/>
</bean>

<bean id="kerberosServiceAuthenticationProvider" class="ru.rfcfefa.epod.common.base.interceptor.CustomKerberosServiceAuthenticationProvider">
    <property name="ticketValidator">
        <bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator">
            <property name="servicePrincipal" value="HTTP/serverName.domain.local" />
            <!-- Setting keyTabLocation to a classpath resource will most likely not work in a Java EE application Server -->
            <!-- See the Javadoc for more information on that -->
            <property name="keyTabLocation" value="http-server.keytab" />
            <property name="debug" value="true" />
        </bean>
    </property>
    <property name="userDetailsService" ref="customUserDetailsService" />
</bean>

<bean class="org.springframework.security.extensions.kerberos.GlobalSunJaasKerberosConfig">
    <property name="debug" value="true" />
    <property name="krbConfLocation" value="krb5.conf"/>
</bean>
</beans>

krb5.conf

[libdefaults]
    default_realm = DOMAIN.LOCAL
    default_tkt_enctypes = aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
    default_tgs_enctypes = aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
    permitted_enctypes   = aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc

[realms]
    DOMAIN.LOCAL  = {
        kdc = serverAD.domain.local 
        default_domain = DOMAIN.LOCAL
}

[domain_realm]
     .DOMAIN.LOCAL = DOMAIN.LOCAL

  • HTTP/serverName.domain.local - service Principal name
  • http-server.keytab - generated keytab file ( see MIKE WIESNER blog or Lior Chaga experience)
  • Be careful with keyTabLocation property, it's not a path to .keytab file, it's a URL to .keytab file, so use file:/ to locate
  • krbConfLocation - path to kerberos configuration file krb5.conf on your system
  • customUserDetailsService - your custom detailService
  • don't forgot set properties debug to false in production
0
votes

if you're using Apache, the Cosign module can be adjusted to do this with some JavaScript on the (normal, in-band auth) login page, and a second path to the login controller that's Kerberos authenticated. The "regular" login form tests if access to a Kerberos-protected resource succeeds, and redirects the browser to complete login automatically if so.

To my mind the above seems a bit backwards, and it's objectionable to add a JavaScript requirement where it's not strictly necessary. I think Elias Mårtenson's answer has it right - attempt Kerberos and fall back to in-band login within an HTTP 401 response - but whether it's possible depends on your environment.