2012-10-08 2 views
15

스프링 보안을 사용하여 IP로 내 웹 앱에 대한 사용자 액세스를 필터링하는 방법을 알고 싶습니다. AbstractAuthenticationProcessingFilter 또는 그와 비슷한 것을 확장하고 내 방식대로 메서드를 재정의해야합니까? 그렇다면 확장 및 필터 설명 예를 web.xml에 줄 수 있습니까? 미리 감사드립니다. 스프링 보안을 사용하는 IP 필터

P. 내 응용 프로그램에서는 스프링 보안 (기본값 : org.springframework.web.filter.DelegatingFilterProxy 사용)을 지원하지만 사용자 자격 증명뿐만 아니라 IP도 확인하고 싶습니다.

+0

의 중복 가능성 http://stackoverflow.com/questions/10147161/authenticating-by-ip-address-in-spring- 3-1-smartest-way-to-do-that – Anshu

답변

13

이것을 할 수있는 한 가지 방법은 스프링 시큐리티의 Web Security Expressions을 사용하는 것입니다. 예 :

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

잘 처리되었습니다. 웹 보안 표현식이 작동하는 데 필요한만큼 use-expressions = "true"인지 확인하십시오. 비록 솔루션이 그걸 가지고 있다고해도 분명히 그것이 필요하다는 것을 말하지는 않습니다 (그것은 나를 도왔을 것입니다). – Andre

+2

이것은 실제 시나리오에서 잘 작동 할 수있는 솔루션은 아니지만, XML로 하드 코딩되어 있기 때문에 아닙니다 파일이며 응용 프로그램 서버를 다시 시작해야합니다. – Aquarelle

7

확인

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

} 

보안의 web.xml을 IP 주소로 접근 방식은 기존의 질문 Authenticating By IP Address In Spring 3.1: Smartest Way To Do That?에서 가져

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

를 인증이 사용자 정의 AuthenticationProvider에 구현이 시작하는 데 도움이 될 수 있습니다.

+0

답해 주셔서 감사합니다. 내 요청에 맞는 것 같지만 웹 보안 표현을 단순하게 사용하기로 결정했습니다. –

0

Anshu의 대답은 사용자를 ip로 인증하는 좋은 방법이지만 CAS 인증에서는 작동하지 않을 수 있습니다. 필터를 사용하면이 상황에 더 적합한 다른 해결책이 있습니다.

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

이 같은 캐스 전에이 필터를 추가 할 수 있습니다

http.addFilterBefore(ipAuthenticationFilter(), CasAuthenticationFilter.class) 
관련 문제