2012-04-13 1 views
12

Ich habe LDAP-Authentifizierung mit Spring Security 3.1 implementiert. Meine security.xml-Datei dafür ist unten veröffentlicht.Authentifizieren von IP-Adresse im Frühjahr 3.1: intelligenteste Möglichkeit, das zu tun?

Ich muss meinen Authentifizierungsprozess so ändern, dass, wenn ein Benutzer von einer IP-Adresse auf einer "weißen Liste" (in einer Datenbanktabelle gehalten) zur Site kommt, dieser Benutzer automatisch mit Spring 3.1 und dann authentifiziert werden soll Umgeleitet von der Login-Bildschirm (nicht meine Idee, wurde mir gesagt).

Wenn der Benutzer nicht von einer der aufgelisteten IP-Adressen kommt, sollte er/sie gezwungen werden, die LDAP-Authentifizierung auf der Anmeldeseite zu durchlaufen.

Ich bin neu in Spring and Spring Security, also ging ich zu der Spring 3.1 Reference Documentation und lesen Sie alle von Abschnitt I. Dort lese ich den Rat, dass, wenn Sie spezielle Authentifizierung benötigen, sollten Sie Section II Architecture and Implementation lesen. Ich machte das sehr langsam und machte mir Notizen.

Da ich jedoch neu in all dem bin, bin ich mir nicht sicher, ob ich komplett verstehe, was ich tun muss und was der klügste Weg ist, es zu tun.


Update 3: Ich habe das Skelett Code bekam, hier zu arbeiten, sind die Dateien, die ich mit endete


Meine individuelle AuthenticationProvider Implementierung für die Authentifizierung von IP-Adresse

// Authentication Provider To Authenticate By IP Address With Allowed IPs 
// Stored in a db table 


package acme.com.controller.security; 

//import acme.com.controller.security.CustomUserInfoHolder; 

import org.springframework.security.authentication.AuthenticationProvider; 
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 
import org.springframework.security.core.Authentication; 
import org.springframework.security.core.AuthenticationException; 
import org.springframework.security.web.authentication.WebAuthenticationDetails; 
import org.springframework.security.core.context.SecurityContextHolder; 
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; 
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper; 
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 
import org.springframework.security.core.userdetails.UserDetails; 

import org.apache.log4j.Logger; 


public class CustomIPAddressAuthenticationProvider implements AuthenticationProvider 
{ 

    private static final Logger logger = Logger.getLogger(CustomIPAddressAuthenticationProvider.class); 
    private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper(); 


    @Override 
    public Authentication authenticate(Authentication authentication) 
    throws AuthenticationException { 


     WebAuthenticationDetails wad = null; 
     String userIPAddress   = null; 
     boolean isAuthenticatedByIP = false; 

     // Get the IP address of the user tyring to use the site 
     wad = (WebAuthenticationDetails) authentication.getDetails(); 
     userIPAddress = wad.getRemoteAddress(); 


     logger.debug("userIPAddress == " + userIPAddress); 

     // Compare the user's IP Address with the IP address in the database 
     // stored in the USERS_AUTHENTICATED_BY_IP table & joined to the 
     // USERS tabe to make sure the IP Address has a current user 
     //isAuthenticatedByIP = someDataObject.hasIPAddress(userIPAddress); 
     isAuthenticatedByIP = true; 


     // Authenticated, the user's IP address matches one in the database 
     if (isAuthenticatedByIP) 
     { 

      logger.debug("isAuthenticatedByIP is true, IP Addresses match"); 
      UserDetails user = null; 


      UsernamePasswordAuthenticationToken result = null; 

      result = new UsernamePasswordAuthenticationToken("John Principal", 
                   "PlaceholderPWE"); 

      result.setDetails(authentication.getDetails()); 

      return result; 
     } 


     // Authentication didn't happen, return null to signal that the 
     // AuthenticationManager should move on to the next Authentication provider 
     return null; 
    } 


    @Override 
    public boolean supports(Class<? extends Object> authentication) 
    { 
     // copied it from AbstractUserDetailsAuthenticationProvider 
     return(UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)); 
    } 

} 

Meine * -Security.XML-Datei

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:s="http://www.springframework.org/schema/security" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security-3.1.xsd"> 

    <s:http pattern="/login*" security="none"/> 
    <s:http pattern="/search*" security="none"/> 
    <s:http pattern="/css/**" security="none"/> 
    <s:http pattern="/js/**" security="none"/> 
    <s:http pattern="/images/**" security="none"/> 




    <s:http auto-config="true" use-expressions="true"> 
     <s:intercept-url pattern="/**" access="isAuthenticated()" /> 

     <s:form-login login-page="/login" 
      authentication-failure-url="/loginfailed" /> 
     <s:logout logout-success-url="/logout" /> 
    </s:http> 



    <s:ldap-server url = "ldap://ldap-itc.smen.acme.com:636/o=acme.com"/> 


    <bean id="customIPAddressAuthenticationProvider" class="com.acme.controller.security.CustomIPAddressAuthenticationProvider" /> 


    <s:authentication-manager> 
     <!-- Proposed: Custom Authentication Provider: Try To Authenticate BY IP Address First, IF NOT, Authenticate WiTh THE LDAP Authentication Provider --> 
     <s:authentication-provider ref="customIPAddressAuthenticationProvider" /> 
     <s:ldap-authentication-provider user-dn-pattern="uid={0},ou=People"/> 
    </s:authentication-manager> 


</beans> 
+1

Das ist eine wirklich schlechte Idee. Was passiert, wenn eine der Adressen in der weißen Liste die einer NAT-Firewall ist? Dann werden alle, die sich hinter dieser Firewall befinden (möglicherweise Hunderte von Personen), automatisch authentifiziert, unabhängig davon, wer sie sind. –

+1

Das wird in unserer Situation nicht passieren, und mir wurde befohlen, dies zu tun. – Steve

+0

Sie werden wahrscheinlich mit den bereits erwähnten Ansätzen experimentieren müssen. Wenn sich die Liste der IP-Adressen nicht dynamisch ändern muss, können Sie sie alle zum Zeitpunkt des Starts laden. –

Antwort

4

Ihr Ansatz ziemlich Sound scheint, sind Sie recht in der Annahme, dass der Frühling wird jedes AuthenticationProvider versuchen, bis es ein erfolgreiches Ergebnis bekommt, so in Ihrem Fall, dass Sie Ihre IP-basierte Anbieter vor den LDAP-Provider definieren würden.

Abhängig von Ihrer Konfiguration erhalten Sie möglicherweise kein WebAuthenticationDetails-Objekt bei Ihrem Aufruf authentication.getDetails(). Wenn dies der Fall ist, sollten Sie Spring's RequestContextListener oder RequestContextFilter zu Ihrer web.xml hinzufügen. Sie können dann die Quell-IP-Adresse abrufen, indem Sie die RequestContextHolder-Klasse verwenden und RequestContextHolder.getRequestAttributes() aufrufen.

Sie sollten nur einen AuthenticationProvider implementieren, es ist nicht notwendig, eine UserDetailsService-, UserDetails- oder Authentication-Klasse zu implementieren. Sie sollten null zurückgeben, wenn Sie den Benutzer nicht über seine IP-Adresse authentifizieren können. In diesem Fall versucht Spring den LDAP-Provider. Wenn Sie aus irgendeinem Grund den Versuch nicht an LDAP weitergeben möchten, sollten Sie eine AuthenticationException auslösen, die den Prozess stoppt und schließlich zu einem 403-Fehler für den Benutzer führt. Ich hoffe, das hilft :)

+0

Ich habe meinen ursprünglichen Beitrag angesichts der Kommentare aktualisiert. Ich habe immer noch ein Problem. Vielen Dank im Voraus für irgendwelche Tipps. – Steve