2012-10-08 27 views
15

Ich frage mich, wie man den Zugriff der Benutzer auf meine Web-App anhand ihrer IP mit Spring Security filtert. Sollte ich AbstractAuthenticationProcessingFilter oder etwas ähnliches erweitern und seine Methoden auf meine eigene Weise überschreiben? Wenn ja, könnten Sie ein Beispiel für eine solche Erweiterung und ein Beispiel für eine Filterbeschreibung in web.xml geben? Vielen Dank im Voraus.IP-Filter mit Spring Security

P.S. In meiner App habe ich auch Spring Security-Unterstützung (mit Standard org.springframework.web.filter.DelegatingFilterProxy), aber ich will es nicht nur Benutzeranmeldeinformationen überprüfen, sondern auch ihre IPs.

+0

möglich Duplikat http://stackoverflow.com/questions/10147161/authenticating-by-ip-address-in-spring- 3-1-cleverest-way-to-do-that – Anshu

Antwort

13

Eine Möglichkeit, dies zu tun, ist die Verwendung von Spring Security Web Security Expressions. Zum Beispiel:

<http use-expressions="true"> 
    <intercept-url pattern="/admin*" 
     access="hasRole('admin') and hasIpAddress('192.168.1.0/24')"/> 
    ... 
</http> 
+0

Hat super funktioniert. Stellen Sie nur sicher, dass Sie use-expressions = "true" haben, da Web-Sicherheitsausdrücke funktionieren müssen. Obwohl die Lösung das hat, sagt sie nicht explizit, dass das notwendig ist (was mir geholfen hätte;) – Andre

+2

Dies ist jedoch keine Lösung, die in realen Szenarien gut funktioniert, da sie in XML kodiert ist Datei und erfordert einen Neustart des App-Servers. – Aquarelle

7

prüft diese individuelle AuthenticationProvider Implementierung von IP-Adresse Authentifizierung

// 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)); 
    } 

} 

sicherheits web.xml

<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> 

Der Ansatz aus bestehenden Frage genommen Authenticating By IP Address In Spring 3.1: Smartest Way To Do That?, könnte dies helfen, zu beginnen.

+0

Danke für Ihre Antwort. Es scheint zu meiner Bitte zu passen, aber ich entschied mich einfach Web Security-Ausdrücke zu verwenden, weil es einfach ist. –

0

Anshu Antwort ist eine gute Idee, einen Benutzer von IP-Authentifizierung, aber es kann nicht mit cas Authentifizierung werden arbeiten. Ich habe eine andere Auflösung, die Verwendung eines Filters ist für diese Situation besser geeignet.

public class IPAuthenticationFilter extends AbstractAuthenticationProcessingFilter { 
    private AuthenticationUserDetailsService<CasAssertionAuthenticationToken> authenticationUserDetailsService; 
    private static Set<String> ipWhitelist; 

    @Autowired 
    private AppProperty appProperty; 

    @PostConstruct 
    public void init() { 
     ipWhitelist = new HashSet<>(Arrays.asList(appProperty.getIpWhitelist())); 
     setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() { 
      @Override 
      public void onAuthenticationSuccess(
        HttpServletRequest httpServletRequest, 
        HttpServletResponse httpServletResponse, 
        Authentication authentication) throws IOException, ServletException { 
       // do nothing 
      } 
     }); 
    } 

    public IPAuthenticationFilter() { 
              super("/"); 
                          } 

    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) 
      throws AuthenticationException, IOException { 
     String userName = request.getHeader(appProperty.getHeaderCurUser()); 
     Assertion assertion = new AssertionImpl(userName); 
     CasAssertionAuthenticationToken token = new CasAssertionAuthenticationToken(assertion, ""); 
     UserDetails userDetails = authenticationUserDetailsService.loadUserDetails(token); 

     CasAuthenticationToken result = new CasAuthenticationToken(
       "an-id-for-ip-auth", 
       userDetails, 
       request.getRemoteAddr(), 
       userDetails.getAuthorities(), 
       userDetails, 
       assertion 
     ); 
     return result; 
    } 

    protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) { 
     String userName = request.getHeader(appProperty.getHeaderCurUser()); 
     return ipWhitelist.contains(request.getRemoteAddr()) && !StringUtils.isEmpty(userName); 
    } 

    protected void successfulAuthentication(
      HttpServletRequest request, 
      HttpServletResponse response, 
      FilterChain chain, 
      Authentication authResult) throws IOException, ServletException { 
     super.successfulAuthentication(request, response, chain, authResult); 
     chain.doFilter(request, response); 
    } 

    public AuthenticationUserDetailsService<CasAssertionAuthenticationToken> getAuthenticationUserDetailsService() { 
     return authenticationUserDetailsService; 
    } 

    public void setAuthenticationUserDetailsService(
      AuthenticationUserDetailsService<CasAssertionAuthenticationToken> authenticationUserDetailsService) { 
     this.authenticationUserDetailsService = authenticationUserDetailsService; 
    } 
} 

Sie können diesen Filter vor cas wie folgt hinzu:

http.addFilterBefore(ipAuthenticationFilter(), CasAuthenticationFilter.class)