2012-04-13 17 views
12

मैंने वसंत सुरक्षा 3.1 का उपयोग कर एलडीएपी प्रमाणीकरण लागू किया है। इसके लिए मेरी security.xml फ़ाइल नीचे पोस्ट की गई है।स्प्रिंग में आईपी पते द्वारा प्रमाणीकरण 3.1: ऐसा करने का सबसे स्मार्ट तरीका?

मुझे अपनी प्रमाणीकरण प्रक्रिया को बदलने की आवश्यकता है जैसे कि यदि कोई उपयोगकर्ता "सफेद सूची" (डेटाबेस तालिका में रखा गया) पर किसी आईपी पते से साइट पर आता है, तो उस उपयोगकर्ता को स्वचालित रूप से स्प्रिंग 3.1 के साथ प्रमाणित किया जाना चाहिए और फिर लॉगिन स्क्रीन से दूर रीडायरेक्ट किया गया (मेरा विचार नहीं, मुझे ऐसा बताया गया था)।

यदि उपयोगकर्ता सफेद सूचीबद्ध आईपी पते में से किसी एक से नहीं है, तो उसे लॉगिन पृष्ठ पर एलडीएपी प्रमाणीकरण के माध्यम से जाने के लिए मजबूर होना चाहिए।

मैं वसंत और वसंत सुरक्षा के लिए नया हूं इसलिए मैं Spring 3.1 Reference Documentation पर गया और सभी अनुभाग 1 पढ़ा। वहां, मैंने सलाह पढ़ी है कि यदि आपके पास कोई विशेष प्रमाणीकरण आवश्यकता है तो आपको Section II Architecture and Implementation पढ़ना चाहिए। मैंने ऐसा किया, बहुत धीरे-धीरे और नोट्स लिया।

हालांकि, चूंकि मैं इस सब के लिए नया हूं, मुझे यकीन नहीं है कि मैं पूरी तरह से समझता हूं कि मुझे क्या करना है और इसे करने के बारे में जाने का सबसे बढ़िया तरीका क्या है।


अद्यतन 3: मैं काम करने के लिए कंकाल कोड मिला है, यहाँ फ़ाइलें मैं


आईपी पता द्वारा सत्यापन के लिए मेरे कस्टम AuthenticationProvider कार्यान्वयन के साथ समाप्त हो गया हैं

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

} 

मेरा * -security.xml फ़ाइल

<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

यह वास्तव में एक बुरा विचार है। क्या होगा यदि एक सफेद सूचीबद्ध पते में से एक एनएटी फ़ायरवॉल का है? तब उस फ़ायरवॉल के पीछे सब लोग (सैकड़ों लोग हो सकते हैं) स्वचालित रूप से प्रमाणित किए जाएंगे चाहे वे कौन हैं। –

+1

यह हमारी स्थिति में नहीं होगा और मुझे ऐसा करने का आदेश दिया गया है। – Steve

+0

आपको शायद उन दृष्टिकोणों के साथ प्रयोग करना होगा जिन्हें आपने पहले ही उल्लेख किया है। यदि आईपी पते की सूची गतिशील रूप से बदलना नहीं है तो आप उन्हें स्टार्टअप समय पर लोड कर सकते हैं। –

उत्तर

4

आपका तरीका बिल्कुल ध्वनि लगता है, आप सोच रहे जब तक यह एक सफल परिणाम हो जाता है कि वसंत प्रत्येक AuthenticationProvider की कोशिश करेंगे, तो आपके मामले में आप LDAP प्रदाता से पहले आपके आईपी आधारित प्रदाता को परिभाषित करेगा में सही कर रहे हैं।

आपके सेटअप के आधार पर आपको अपने प्रमाणीकरण .getDetails() कॉल पर WebAuthenticationDetails ऑब्जेक्ट नहीं मिल सकता है। यदि ऐसा है तो आपको अपने web.xml में स्प्रिंग के RequestContextListener या RequestContextFilter जोड़ना चाहिए। इसके बाद आप RequestContextHolder क्लास का उपयोग कर स्रोत आईपी पता प्राप्त कर पाएंगे और RequestContextHolder.getRequestAttributes() को कॉल कर सकते हैं।

आपको केवल एक प्रमाणीकरण प्रदाता को लागू करने की आवश्यकता है, उपयोगकर्ताDetailsService, UserDetails या प्रमाणीकरण कक्षा को लागू करने की कोई आवश्यकता नहीं है। यदि आप उपयोगकर्ता को अपने आईपी पते के माध्यम से प्रमाणित करने में सक्षम नहीं हैं तो आपको शून्य वापस करना चाहिए। इस मामले में वसंत एलडीएपी प्रदाता की कोशिश करेगा। अगर किसी कारण से आप एलडीएपी पर प्रयास पारित नहीं करना चाहते हैं तो आपको एक प्रमाणीकरण अपवाद फेंकना चाहिए जो प्रक्रिया को रोक देगा और आखिरकार उपयोगकर्ता के लिए 403 त्रुटि होगी।

मुझे उम्मीद है कि यह मदद करता है :)

+0

मैंने टिप्पणियों के प्रकाश में अपनी मूल पोस्ट अपडेट की। मुझे अभी भी एक समस्या है। किसी भी सुझाव के लिए अग्रिम में धन्यवाद। – Steve