2012-10-08 46 views
15

Tôi tự hỏi cách lọc truy cập của người dùng vào ứng dụng web của tôi bằng IP của họ bằng cách sử dụng Bảo mật mùa xuân. Tôi có nên mở rộng AbstractAuthenticationProcessingFilter hoặc một cái gì đó như thế và ghi đè lên phương pháp của nó theo cách riêng của tôi không? Nếu có, bạn có thể đưa ra ví dụ về việc mở rộng và ví dụ về mô tả bộ lọc trong web.xml không? Cảm ơn trước.Bộ lọc IP sử dụng Bảo mật mùa xuân

P.S. Trong ứng dụng của tôi, tôi cũng có hỗ trợ Spring Security (sử dụng mặc định org.springframework.web.filter.DelegatingFilterProxy), nhưng tôi muốn nó không chỉ kiểm tra thông tin đăng nhập của người dùng mà còn kiểm tra IP của họ.

+0

thể trùng lặp của http://stackoverflow.com/questions/10147161/authenticating-by-ip-address-in-spring- 3-1-smart-way-to-do-that – Anshu

Trả lời

13

Một cách bạn có thể thực hiện việc này là sử dụng số Web Security Expressions của Spring Security. Ví dụ:

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

Làm việc tuyệt vời. Chỉ cần chắc chắn rằng bạn đã sử dụng biểu thức = "true" vì nó là cần thiết cho các biểu thức bảo mật web để làm việc. Mặc dù các giải pháp không có điều đó, nó không rõ ràng nói rằng đó là cần thiết (mà có thể đã giúp tôi;) – Andre

+2

Đây không phải là một giải pháp mà sẽ làm việc tốt trong các kịch bản thế giới thực, tuy nhiên, vì nó được mã hóa cứng thành một XML và yêu cầu khởi động lại máy chủ ứng dụng. – Aquarelle

7

Kiểm tra tùy chỉnh này AuthenticationProvider thực hiện để xác thực bằng địa chỉ IP

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

} 

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

Cách tiếp cận được lấy từ câu hỏi hiện Authenticating By IP Address In Spring 3.1: Smartest Way To Do That?, điều này có thể giúp để bắt đầu với.

+0

Cảm ơn câu trả lời của bạn. Nó có vẻ phù hợp với yêu cầu của tôi, nhưng tôi đã quyết định đơn giản sử dụng các biểu thức bảo mật web vì nó đơn giản. –

0

Câu trả lời của Anshu là ý tưởng tốt khi xác thực người dùng bằng ip, nhưng có thể không hoạt động với xác thực cas. Tôi có độ phân giải khác, sử dụng bộ lọc phù hợp hơn cho tình huống này.

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

Bạn có thể thêm bộ lọc này trước khi cas như thế này:

http.addFilterBefore(ipAuthenticationFilter(), CasAuthenticationFilter.class) 
Các vấn đề liên quan