2013-03-18 25 views
3

我正在使用Spring Security的一個項目中工作,它很好地從數據庫驗證用戶身份。使用Spring Security進行數據庫和LDAP驗證

現在我的需要是我想用LDAP來驗證用戶,並保留現有的數據庫身份驗證。

而且,我不能使用Spring安全使用標準的LDAP身份驗證方式,因爲我只有一個函數調用來驗證用戶是否存在或不喜歡的方法,

 com.company.ldap.Authentication auth = new com.company.ldap.Authentication(); 
     int status = auth.authenticate(userName, userPassword); 

如果我收到的狀態作爲1,那麼用戶被認證否則不是。

因此,對於這種情況下,我已經創建單獨的網址 「/ j_spring_facebook_security_check」(這裏的名字就是Facebook,但實際上它是LDAP)

我的applicationContext-security文件

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:security="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.0.xsd"> 

    <security:http auto-config="true" use-expressions="true" access-denied-page="/accessDenied.jsp"> 

     <security:form-login login-page="/index.jsp" 
      default-target-url="/jsp/home.jsp" 
      authentication-failure-handler-ref="authenticationFailureHandler" /> 


     <security:intercept-url pattern="/jsp/listInBetweenPlaces.jsp" 
      access="permitAll" /> 

     <security:intercept-url pattern="/jsp/home.jsp" 
      access="permitAll" /> 


     <security:intercept-url pattern="/jsp/*" 
      access="isAuthenticated()" /> 


     <security:logout logout-url="/j_spring_security_logout" logout-success-url="/index.jsp?logout=success" 
      invalidate-session="true" /> 


    <security:custom-filter before="FORM_LOGIN_FILTER" 
      ref="facebookAuthenticationFilter" /> 

    </security:http> 



    <bean id="facebookAuthenticationFilter" class="org.springframework.security.facebook.FacebookAuthenticationFilter"> 
     <property name="authenticationManager" ref="authenticationManager"/> 

     <property name = "authenticationSuccessHandler"> 
     <bean class = "org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler"> 
      <property name = "defaultTargetUrl" value = "/jsp/home.jsp" /> 
      <property name = "alwaysUseDefaultTargetUrl" value = "true" /> 
     </bean> 
     </property> 

     <property name = "authenticationFailureHandler"> 
     <bean class = "org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> 
      <property name = "defaultFailureUrl" value = "/fb/failure.jsp" /> 
     </bean> 
     </property> 

    </bean> 




    <bean id="ldapAuthenticationProvider" class="org.springframework.security.facebook.FacebookAuthenticationProvider"> 
     <property name="roles" value="ROLE_FACEBOOK_USER" /> 
    </bean> 


    <security:authentication-manager alias="authenticationManager"> 

     <security:authentication-provider user-service-ref="customUserDetailsService"> 
      <security:password-encoder hash="md5" /> 
     </security:authentication-provider> 

     <security:authentication-provider ref="ldapAuthenticationProvider"> 
     </security:authentication-provider> 

    </security:authentication-manager> 




    <bean id="customUserDetailsService" class="com.abc.carpool.authentication.CustomUserDetailsService"> 
    </bean> 

</beans> 

FacebookAuthenticationFilter。 java

public class FacebookAuthenticationFilter extends AbstractAuthenticationProcessingFilter implements ApplicationContextAware { 

    @Autowired 
    CarpoolService carpoolService=null; 

    public CarpoolService getCarpoolService() { 
     return carpoolService; 
    } 
    public void setCarpoolService(CarpoolService carpoolService) { 
     this.carpoolService = carpoolService; 
    } 


    public static final String DEFAULT_FILTER_PROCESS_URL = "/j_spring_facebook_security_check"; 

    private ApplicationContext ctx; 
    protected FacebookAuthenticationFilter() { 
     super(DEFAULT_FILTER_PROCESS_URL); 
    } 

    public Authentication attemptAuthentication(HttpServletRequest req, 
      HttpServletResponse res) throws AuthenticationException, 
      IOException, ServletException { 


     HttpServletRequest request = (HttpServletRequest) req; 

     String userName = request.getParameter("j_username"); 
     String userPassword = request.getParameter("j_password"); 


     System.out.println("Username and pswd is :"+userName + " " + userPassword); 
     System.out.println("SYS PATH :"+System.getenv("MC_ENV_PATH")); 

     User user = null; 

     try{ 
      com.abc.ldap.Authentication auth = new com.abc.ldap.Authentication(); 

      int status = auth.authenticate(userName, userPassword); 

      //int status=2; 
      if(status==1){ 

//CREATE NEW USER AND SAVE IN DB      



       } 

      }else{ 
       throw new UsernameNotFoundException("Incorrect Email Id or Password."); 
      } 

      System.out.println("status is :"+status); 
     }catch (Exception e) { 
      System.out.println("Exception is "+e.getMessage()); 
      e.printStackTrace(); 
      return null; 
     } 

     System.out.println("FacebookAuthenticationFilter.attemptAuthentication() :"+userName + " " + userPassword);  


     UsernamePasswordAuthenticationToken upatToken = new UsernamePasswordAuthenticationToken(userName, userPassword); 
     AuthenticationManager authenticationManager = getAuthenticationManager(); 
     Authentication auth = authenticationManager.authenticate(upatToken); 

     return auth; 
    } 

    public void setApplicationContext(ApplicationContext ctx) 
      throws BeansException { 
     this.ctx = ctx; 
    } 


} 

FacebookAuthenticationProvider .java

public class FacebookAuthenticationProvider implements AuthenticationProvider { 

    private String[] roles; 

    public Authentication authenticate(Authentication authentication) 
      throws AuthenticationException { 

     System.out.println("FacebookAuthenticationProvider.authenticate()"); 

     return authentication; 
    } 

    public boolean supports(Class<? extends Object> authentication) { 
     boolean supports = true; 
     return supports; 
    } 

    public void setRoles(String[] roles) { 
     this.roles = roles; 
    } 

    public String[] getRoles() { 
     return roles; 
    } 
} 

在事情做工精細上述情況下,控制是將過濾器類,並使用LDAP驗證的用戶時,如果用戶存在,那麼我節省了用戶一個副本我的數據庫,並希望與正常繼續下去流。

其實當我打電話

Authentication auth = authenticationManager.authenticate(upatToken); 

從FacebookAuthenticationFilter,控制,去CustomUserDetailsS​​ervice類。

我的需求是CustomUserDetailsS​​ervice僅用於數據庫身份驗證,我不想控制去那裏。

如何以一種很好的方式實現這件事。

回答

0

AuthenticationProvider.supports(Class<? extends Object> authentication)可以幫到你。此時,對於兩種情況(DB和LDAP),都使用UsernamePasswordAuthenticationToken。兩個身份驗證提供程序都支持這種類型,因此都使用這兩種身份驗在LDAP的情況下嘗試添加自定義的驗證對象:

public class CustomLdapAuthenticationToken extends AbstractAuthenticationToken { 

然後在你的FacebookAuthenticationFilter,而不是UsernamePasswordAuthenticationToken使用它。

更改FacebookAuthenticationProvider.supports(...)實現:

public boolean supports(Class<? extends Object> authentication) { 
    boolean result = false; 
    if(authentication instanceof CustomLdapAuthenticationToken) { 
     result = true; 
    } 
    return result; 
} 

從這一刻起每一個身份驗證提供者將僅處理相應的認證請求。

相關問題