2012-06-07 18 views
5

स्प्रिंग सिक्योरिटी के साथ ओपनआईडी प्रमाणीकरण को लागू करने का सही तरीका समझने की कोशिश कर रहा है।स्प्रिंग सिक्योरिटी ओपनआईडी - उपयोगकर्ता डिस्प्ले सर्विस, प्रमाणीकरण यूज़र डिस्प्ले सर्विस

public class OpenIDUserDetailsService implements 
    UserDetailsService, 
    AuthenticationUserDetailsService { 

    @Override 
    public UserDetails loadUserByUsername(String openId) throws 
    UsernameNotFoundException, DataAccessException { 

    // I either want user email here 
    // or immediately delegate the request to loadUserDetails 

    } 

    @Override 
    public UserDetails loadUserDetails(Authentication token) throws 
    UsernameNotFoundException { 

    // This never gets called if I throw from loadUserByUsername() 

    } 

    private MyCustomUserDetails registerUser(String openId, String email) { 
    ... 
    } 
} 

मैं परिदृश्य पर विचार कर रहा हूं जब उपयोगकर्ता अभी तक मेरे आवेदन में पंजीकृत नहीं है। उपयोगकर्ता को पंजीकृत करने के लिए, मुझे इसके ओपनआईडी और ईमेल को जानना होगा।

जब ओपनआईडी प्रदाता उपयोगकर्ता को मेरे एप्लिकेशन पर वापस रीडायरेक्ट करता है, तो loadUserByUsername() कहा जाता है, लेकिन इस मामले में मुझे केवल उपयोगकर्ता के ओपनआईडी के बारे में पता है। तो, मैं UsernameNotFoundException फेंक रहा हूं और फिर loadUserDetails() कभी नहीं बुलाया जाता है, इसलिए मैं उपयोगकर्ता को पंजीकृत नहीं कर सकता।

यहां सामान्य समाधान क्या है? क्या होगा यदि मैं से loadUserByUsername() से कुछ वापस लौटाता हूं और फिर, जब loadUserDetails() कहा जाता है, तो मैं उपयोगकर्ता को पंजीकृत करता हूं और फिर वास्तविक MyCustomUserDetails देता हूं?

मैं वसंत सुरक्षा 3.0.7.RELEASE

उत्तर

1

कि मज़ेदार है का उपयोग कर रहा है, लेकिन स्प्रिंग सुरक्षा 3.1.0.RELEASE में जाने से इसे हल करने में कामयाब रहे। loadUserByUsername() नहीं बुलाया जाता है और loadUserDetails() बजाय कहा जाता है -

एक ही परिदृश्य के लिए, व्यवहार बिल्कुल अलग है।

+4

यह सही नहीं है। 3.1 में, OpenIDAuthenticationProvider में UserDetailsService और प्रमाणीकरणUserDetailsService दोनों के लिए सेटर्स हैं और जो सेटटर का उपयोग किया जाता है, उसके आधार पर loadUserByUsername या loadUserDetails को कॉल करता है। 3.0.7 में, प्रमाणीकरण उपयोगकर्ता जानकारी के लिए कोई सेटटर नहीं था और इसलिए यह हमेशा loadUserByUsername का उपयोग करता था। – Ritesh

0

मैं अपने UserDetailsService में

AuthenticationUserDetailsService<OpenIDAuthenticationToken> 

को लागू करने से एक ही स्थिति को हल किया।

public class OpenIdUserDetailsService implements UserDetailsService, 
    AuthenticationUserDetailsService<OpenIDAuthenticationToken> { 

@Autowired(required = true) 
@Qualifier(value = "jdbcUserDetailsService") 
private UserDetailsService localUserDetailsService; 

/** 
* @return the localUserDetailsService 
*/ 
public UserDetailsService getLocalUserDetailsService() { 
    return localUserDetailsService; 
} 

/** 
* @param localUserDetailsService 
*   the localUserDetailsService to set 
*/ 
public void setLocalUserDetailsService(
     UserDetailsService localUserDetailsService) { 
    this.localUserDetailsService = localUserDetailsService; 
} 

@Override 
public UserDetails loadUserDetails(OpenIDAuthenticationToken token) 
     throws UsernameNotFoundException { 
    String email = getEmail(token); 
    return loadUserByUsername(email); 
} 

@Override 
public UserDetails loadUserByUsername(String username) 
     throws UsernameNotFoundException { 
    return localUserDetailsService.loadUserByUsername(username); 
} 

private String getEmail(OpenIDAuthenticationToken token) { 
    for (OpenIDAttribute attribute : token.getAttributes()) { 
     if (attribute.getName().equals("email")) { 
      return attribute.getValues().get(0); 
     } 
    } 
    return null; 
} 

} 

बस openid फार्म कॉन्फ़िगर करते समय UserDetailsService के रूप में सेवा के ऊपर का उपयोग सुनिश्चित करें। इसके अलावा, ओपनिड को कॉन्फ़िगर करते समय 'ईमेल' विशेषता के लिए विशेषता एक्सचेंज कॉन्फ़िगर करें। सफल प्रमाणीकरण के बाद लौटाया गया ईमेल तब 'ओपनआईड प्रमाणीकरण टोकन' से प्राप्त किया जा सकता है जो अंततः loadUserByUsername फ़ंक्शन को पैरामीटर के रूप में पारित किया जाता है।

यदि आपके पास उस ईमेल के साथ पंजीकृत उपयोगकर्ता है, प्रमाणीकरण पूर्ण हो गया है। अन्यथा आप उस ईमेल द्वारा पंजीकृत होने या लॉगिन विफलता पृष्ठ दिखाने के लिए उपयोगकर्ता को सुझाव दे सकते हैं।

+0

ओपी के लिए वास्तविक कारण ऋषि द्वारा उत्तर दिया गया है (स्वीकृत उत्तर के लिए टिप्पणी!) – manikanta

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