Announcement Announcement Module
Collapse
No announcement yet.
Multi-level Authentication Strategy Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Multi-level Authentication Strategy

    Hello,

    Im trying to implement a multi-level authentication strategy in my application. More specifically:
    When a request is received I need to first attempt an authentication using Kerberos against an Active Directory.
    If this authentication succeeds then no login page is shown and the requested page is served.
    If the Kerberos authentication fails then I need to serve a login page and allow users to log-in through the form.

    The way Im thinking of implementing that is the following:
    For the Kerberos authentication I will use a SpnegoAuthenticationProcessingFilter provided from Spring Security Extensions in a http namespace setup like:

    Code:
      <security:http>
      	.
            <security:custom-filter before="FORM_LOGIN_FILTER"     ref="spnegoAuthenticationProcessingFilter"/>
            .
      </security:http>
    For the "normal" authentication a UsernamePasswordAuthenticationFilter with all the usual wiring (AuthenticationManager, UserDetailsService etc) will be used.This will be the "FORM_LOGIN_FILTER".

    However, in the case of a successful Kerberos authentication I need to prevent the FORM_LOGIN_FILTER from attempting an authentication. Going through AbstractAuthenticationProcessingFilter's code I can see that the doFilter() method initially consults a protected requiresAuthentication() method in order to decide, as the name reveals, whether it should attempt an authentication.

    So, my question is:
    Is it sufficient to simply subclass UsernamePasswordAuthenticationFilter and override requiresAuthentication() in a way like:
    Code:
       ..
         If(SecurityContextHolder.getContext().getAuthentication() != null){
    	    return false;
         }
         return true;
    ..
    or are there any other conditions I should take into account when deciding if an authentication is needed?

    Any input much appreciated!

    Kind Regards
    Savvas.

  • #2
    ...smal correction on the overriden requiresAuthentication() implementation:

    Code:
      protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
          If(SecurityContextHolder.getContext().getAuthentication() != null){
    	return false;
           }
           return super.requiresAuthentication();
      }

    Comment


    • #3
      Some time ago I've been working at the same scenario.
      Here is fragment of the configuration file:
      Code:
      <http entry-point-ref="spnegoEntryPoint" use-expressions="true">
      		<intercept-url pattern="/secured/**" access="isFullyAuthenticated()" />
      		<custom-filter ref="spnegoAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
      		<form-login login-page="/login" default-target-url="/secured/test" />
      		<logout logout-url="/j_spring_security_logout" logout-success-url="/tests/test" />
      	</http>
      
      	<b:bean id="spnegoEntryPoint" class="org.springframework.security.extensions.kerberos.web.SpnegoEntryPoint" />
      
      	<b:bean id="spnegoAuthenticationProcessingFilter" class="org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter">
      		<!--    AuthenticationFailureHandler-->
      		<b:property name="failureHandler">
      			<b:bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
      				<b:property name="defaultFailureUrl" value="/login" />
      			</b:bean>
      		</b:property>
      		<b:property name="authenticationManager" ref="authenticationManager" />
      	</b:bean>
      
      	<authentication-manager alias="authenticationManager">
      		<authentication-provider ref="kerberosServiceAuthenticationProvider">
      			<jdbc-user-service data-source-ref="dataSource" />
      		</authentication-provider>
      		<!-- Used with SPNEGO -->
      		<authentication-provider ref="kerberosAuthenticationProvider">
      			<jdbc-user-service data-source-ref="dataSource" />
      		</authentication-provider>
      		<!-- Used with form login -->
      	</authentication-manager>
      
      	<b:bean id="kerberosAuthenticationProvider" class="org.springframework.security.extensions.kerberos.KerberosAuthenticationProvider">
      		<b:property name="kerberosClient">
      			<b:bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosClient">
      				<b:property name="debug" value="true" />
      			</b:bean>
      		</b:property>
      		<b:property name="userDetailsService" ref="dummyUserDetailsService" />
      	</b:bean>
      
      	<b:bean id="kerberosServiceAuthenticationProvider" class="org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider">
      		<b:property name="ticketValidator">
      			<b:bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator">
      				<b:property name="servicePrincipal" value="${security.service.principal}" />
      				<!-- 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 -->
      				<b:property name="keyTabLocation" value="${security.file.path.keytab}" />
      				<b:property name="debug" value="true" />
      			</b:bean>
      		</b:property>
      		<b:property name="userDetailsService" ref="dummyUserDetailsService" />
      	</b:bean>
      
      	<b:bean class="org.springframework.security.extensions.kerberos.GlobalSunJaasKerberosConfig">
      		<b:property name="debug" value="true" />
      		<!-- You can point to a different kerberos config location here, if you don't want the default one -->
      		<b:property name="krbConfLocation" value="${security.file.path.krb5}" />
      	</b:bean>
      So all you need is properly configured kerberos (as you can see, most of the code is from kerberos sample app) and AuthenticationFailureHandler added to your SpnegoAuthenticationProcessingFilter.

      Comment


      • #4
        Thanks re6exp for providing this configuration. It's exactly what I'm looking for. At the moment I am unable to setup a Kerberos environment (register SPN, generate keytab etc).

        Can someone please confirm that this configuration works that re6exp provided (I'm busy with a POC and this is part of my solution).

        Kind regards,

        Comment

        Working...
        X