2010-04-05 24 views
19

जब मैं अपने एप्लिकेशन में लॉग इन कर रहा हूं तो मैं ट्रैक करना चाहता हूं। मेरे पास कुछ कोड है जो उपयोगकर्ता प्रमाणीकृत होने के ठीक बाद निष्पादित करना चाहता हूं। समस्या यह है कि, मैं यह नहीं समझ सकता कि इसे कहां कहा जाना चाहिए। वसंत-सुरक्षा के पास प्रमाणीकरण के बाद एक विधि को कॉल करने का कोई तरीका है?स्प्रिंग-सिक्योरिटी: प्रमाणीकरण के बाद कॉल विधि

उत्तर

4

बस अपना खुद का स्प्रिंगसेक्चरिटी फ़िल्टर लिखें और इसे अपने प्रमाणीकरण प्रदाता कहने के बाद फ़िल्टर श्रृंखला में जोड़ें।

package my.code; 

public class AuditFilter extends SpringSecurityFilter { 

    public void doFilterHttp(...) throws ... { 
     {application code to run before request is processed} 
     chain.doFilter(...); 
     {application code to run after request has fully processed} 
    } 
} 
आपके विन्यास एक्सएमएल में

तो (भी आप सेटअप सुरक्षा फ़िल्टर श्रृंखला) इस तरह एक पंक्ति जोड़ें:

<bean id="auditFilter" class="my.code.AuditFilter> 
    <security:custom-filter position="LAST"/> <-- you can change the position 
</bean> 
+0

कृपया ध्यान दें कि SpringSecurityFilter स्प्रिंग सुरक्षा में जेनेरिक स्प्रिंग वेब GenericFilterBean करने के लिए बदल 3. –

-1

यह लिंक Post Authentication Logic ByteClip पर बताते हैं परेशान किए बिना सफल प्रमाणीकरण के बाद कुछ तर्क निष्पादित करने के लिए कैसे वसंत सुरक्षा फ़िल्टर श्रृंखला

+2

लिंक टूटी हुई। ... – chrismarx

11

सबसे अच्छा तरीका एक एप्लिकेशन श्रोता बनाने और वसंत सुरक्षा संदर्भ के साथ पंजीकृत करने का सबसे अच्छा तरीका है।

import org.springframework.context.ApplicationListener; 
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent; 

public class AuthenticationSuccessListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent> { 

    @Override 
    public void onApplicationEvent(InteractiveAuthenticationSuccessEvent event) { 
     System.out.println("User Logged In"); 

    } 
} 

उपरोक्त वर्ग वसंत-सुरक्षा.एक्सएमएल को एक बीन के रूप में जोड़ना सुनिश्चित करें। कई प्रकार के सुरक्षा कार्यक्रम श्रोताओं को आप सुन सकते हैं, सभी प्रकार की सुरक्षा घटनाओं की सूची के लिए प्रकार पदानुक्रम की जांच करें जिन्हें आप सुन सकते हैं।

+0

स्थिति के आधार पर, लेकिन यह आमतौर पर जाने का मेरा तरीका होगा। यदि आपको प्रमाणीकरण ईवेंट का साइड इफेक्ट बनाने की आवश्यकता है तो एप्लिकेशन लिस्टनर का उपयोग करें। यदि आपको यह निर्दिष्ट करने की आवश्यकता है कि प्रमाणीकरण प्रक्रिया को हैंडलर का उपयोग कैसे किया जाना चाहिए। इस मामले में "ट्रैकिंग प्रमाणीकरण कार्रवाई" मैं घटना के लिए जाना होगा और साथ ही यह एक दुष्प्रभाव की तरह है। – wooki

30

शायद किसी के लिए उपयोगी हो जाएगा ... स्प्रिंग 3 के मामले में, सुरक्षा कॉन्फ़िगर करें:

<security:http use-expressions="true" auto-config="true"> 
    <security:intercept-url pattern="..."/> 
    <security:form-login 
      authentication-failure-handler-ref="authFailureHandler" 
      authentication-success-handler-ref="authSuccessHandler"/> 
    <security:logout success-handler-ref="logoutSuccessHandler" 
      invalidate-session="true"/> 
    <security:session-management session-fixation-protection="newSession"/> 
</security:http> 

<bean id="authFailureHandler" class="mine.AuthenticationFailureHandlerImpl"/> 
<bean id="authSuccessHandler" class="mine.AuthenticationSuccessHandlerImpl"/> 
<bean id="logoutSuccessHandler" class="mine.LogoutSuccessHandlerImpl"/> 

और एक उचित वर्ग को लागू:

public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler { 

    @Override 
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { 
     //do what you want with 
     response.getOutputStream().write("success".getBytes()); 
    } 
} 

आपको लगता है कि एक्सएमएल के माध्यम से संसाधनों लिंक कर सकते हैं config।

+1

अच्छी चीजें! प्रमाणीकरण-सफलता-हैंडलर-रेफ –

+0

के लिए धन्यवाद यदि मैं एक छोटी सी कार्रवाई जोड़ना चाहता हूं और फिर सामान्य हैंडलिंग के साथ जारी रहूं, तो यह कैसे होगा? – DiegoSahagun

6

यदि आप डिफ़ॉल्ट व्यवहार के साथ जारी रखना चाहते हैं, लेकिन बस अपने खुद के व्यवसाय तर्क के बीच में, तो आप extend SimpleUrlAuthenticationSuccessHandler पर लौट सकते हैं और super.onAuthenticationSuccess(request, response, authentication); वापस लौटने से पहले आ सकते हैं। अधिक जानकारी https://stackoverflow.com/a/6770785/418439

+0

यह वही है जो मैं आमतौर पर करता हूं और यदि आप मूल कार्यान्वयन में कुछ भी बदलने की आवश्यकता नहीं है, तो मुझे यह भी करने की सलाह है कि आपको अतिरिक्त कार्यक्षमता की आवश्यकता है। मैं एक चेन प्रमाणीकरण SUccessHandler बनाता हूं जो तब मेरे कस्टम हैंडलर और मौजूदा हैंडलर जैसे 'SimpleUrlAuthenticationSuccessHandler'' को कॉल करेगा। मुझे वसंत वर्ग को विस्तारित करने से अधिक विश्वसनीय और साफ लगता है। मुझे लगता है कि आप विरासत से बचने के लिए मूल हैंडलर के शीर्ष पर कुछ प्रकार की सजावटी कक्षा भी बना सकते हैं, लेकिन श्रृंखला समाधान सिर्फ मेरे लिए बेहतर अपील करता है। – wooki

1

प्रमाणीकरण आवश्यक रूप से सफल लॉगिन का संकेत देता है। उपयोगकर्ता को सफलतापूर्वक प्रमाणीकृत किया जा सकता है, उदाहरण के लिए, दो-तरफा एसएसएल (एक्स.50 9 सीर्ट), और फिर भी वसंत सुरक्षा आपको एक त्रुटि पृष्ठ पर रीडायरेक्ट करेगी यदि सत्र समेकन प्रबंधन max-sessions="1" के साथ स्थापित किया गया है और यह एक दूसरा समवर्ती लॉगिन प्रयास है। यदि आपका सेटअप सरल है, सत्र समवर्ती नियंत्रण के बिना, आप सभी व्यावहारिक उद्देश्यों के लिए लॉगिन = प्रमाणीकरण ग्रहण कर सकते हैं। अन्यथा, यदि आपके पास है, उदाहरण के लिए, तर्क है कि प्रत्येक डेटाबेस डेटाबेस में लॉगिन करता है, तो आपको प्रमाणीकरण के बिंदु पर वास्तविक लॉगिन के बिंदु पर इस तर्क को आमंत्रित करना होगा। ऐसा करने के लिए (स्प्रिंग सिक्योरिटी फ्रेमवर्क की मेरी सीमित समझ के अधीन) कोई भी तरीका नहीं है) ऐसा करने के लिए अपने ConcurrentSessionControlAuthenticationStrategy को लागू करना है (स्रोत कोड के लिए here पर क्लिक करें) और इसे अपने स्प्रिंग सिक्योरिटी (3.2 और ऊपर) में CompositeSessionAuthenticationStrategy में इंजेक्ट करें। विन्यास एक्सएमएल:

<http> 
    . 
    . 
    <session-management session-authentication-strategy-ref="sas" /> 
    . 
    . 
</http> 
. 
. 
<beans:bean id="sas" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy"> 
    <beans:constructor-arg> 
     <beans:list> 
      <beans:bean class="path.to.my.implementation.of.ConcurrentSessionControlAuthenticationStrategy"> 
       <beans:constructor-arg ref="sessionRegistry"/> 
       <beans:property name="maximumSessions" value="1"/> 
       <beans:property name="exceptionIfMaximumExceeded" value="true"/> 
      <beans:bean> 
      <beans:bean class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy"/> 
      <beans:bean class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy"/> 
       <beans:constructor-arg ref="sessionRegistry"/> 
      </beans:bean> 
     </beans:list> 
    </beans:constructor-arg> 
</beans:bean> 

<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/> 

मैं अपने कस्टम ConcurrentSessionControlAuthenticationStrategy और इसे करने के लिए संशोधन करने में से ढांचे के ConcurrentSessionControlAuthenticationStrategy में एक कस्टम PostLogin हैंडलर इंजेक्षन करने के लिए पसंद होता, कॉपी-पेस्ट करने के बजाय, लेकिन मैं एक तरह से की पता नहीं है इस समय यह करने के लिए।

एक और पूर्ण कॉन्फ़िगरेशन उदाहरण here पाया जा सकता है।

2

आप सभी धागा पढ़ने से बचना चाहते हैं: एनोटेशन & थोड़ा अधिक व्याख्यात्मक साथ क्यूरेट किया संस्करण:

import org.springframework.context.ApplicationListener; 
import org.springframework.security.authentication.event.AuthenticationSuccessEvent; 
import org.springframework.security.core.userdetails.User; 
import org.springframework.stereotype.Component; 

@Component 
public class LoginSuccessListener implements ApplicationListener<AuthenticationSuccessEvent{ 

    @Override 
    public void onApplicationEvent(AuthenticationSuccessEvent evt) { 

     // if you just need the login 
     String login = evt.getAuthentication().getName(); 
     System.out.println(login + " has just logged in"); 

     // if you need to access full user (ie only roles are interesting -- the rest is already verified as login is successful) 
     User user = (User) evt.getAuthentication().getPrincipal(); 
     System.out.println(user.getUsername() + " has just logged in"); 

    } 
} 
संबंधित मुद्दे