2016-02-17 77 views
2

我需要通過對外部系統進行身份驗證來登錄Liferay中的用戶。不過,我仍然需要有一個有效的Liferay會話。所以,我需要通過在沒有密碼的情況下登錄Liferay用戶

  1. 登錄到Liferay從用戶詢問用戶名/密碼,
  2. 使用它們來對外部系統進行身份驗證。
  3. 只使用用戶名(而不是密碼)對Liferay登錄進行身份驗證。
  4. 如果外部系統登錄成功,則登錄用戶。

我做了幾件事情:

  1. 自動登錄
  2. 掛鉤UserLocalService.authenticateByScreenName覆蓋
  3. auth.pipeline前和檢查=假
  4. LoginFilter。

這些沒有奏效。這是對這些方法的解釋。這個想法是包括 //如果這些方法的工作,調用外部系統進行身份驗證將被包括在內。 請糾正我犯錯的地方,如果某種方法比其他方法更好。

1.自動登錄:

一個。設置portal-ext.properties

auto.login.hooks=com.poc.AutoLoginFil 

b。創建班級

public class AutoLoginFilter implements AutoLogin { 

    public AutoLoginFilter() { 
     super(); 
    } 

    @Override 
    public String[] login(HttpServletRequest req, HttpServletResponse arg1) throws AutoLoginException { 

//Call external system to authenticate 
     User user = UserLocalServiceUtil.getUserByScreenName(company.getCompanyId(), login); 
     credentials[0] = String.valueOf(user.getUserId()); 

     credentials[1] = "undefined"; 
     credentials[2] = Boolean.TRUE.toString(); 

      return credentials; 
    } 
} 

c。部署插件項目,重新啓動服務器並轉至http:// localhost:8080/web/guest/home。這應該登錄爲joebloggs

這不起作用

2.掛鉤UserLocalService.authenticateByScreenName覆蓋

一個。在liferay-hook.xml中

<service> 
     <service-type> 
      com.liferay.portal.service.UserLocalService 
     </service-type> 
     <service-impl> 
      com.test.UserService 
     </service-impl> 
    </service> 

b。擴展UserLocalServiceWrapper並使用自定義類。

public class UserService extends UserLocalServiceWrapper 
{ 

@Override 
    public int authenticateByScreenName(long companyId, String screenName, String password, Map headerMap, Map parameterMap, Map resultsMap) 
    { 
//Call external system to authenticate 
     String name = ""; 
     log.info(screenName); 
     return SUCCESS; 
    } 

} 

當我登錄時,它應該使用任何密碼。它不是。

3. auth.pipeline前和檢查=假

一個。在portal-ext.properties中

auth.pipeline.enable.liferay.check=false 
auth.pipeline.pre=com.test.AutoLoginCustom 

b。然後,在

public class AutoLoginCustom implements AutoLogin 
{ 

@Override 
public String[] login(HttpServletRequest arg0, HttpServletResponse arg1) 
      throws AutoLoginException { 

@Override 
    public String[] login(HttpServletRequest arg0, HttpServletResponse arg1) 
{ 
//Call external system to authenticate 
    credentials[0] = "joebloggs"; 

     credentials[1] = "undefined"; 
     credentials[2] = Boolean.TRUE.toString(); 

      return credentials; 
} 

c。部署項目並重新啓動服務器。請轉至http://localhost:8080/web/guest/home。使用用戶名和不同的密碼登錄。它不會登錄。它甚至沒有打到AutoLoginCustom java中的調試點。

4. LoginFilter 在liferay的-hook.xml,

<servlet-filter> 
     <servlet-filter-name>Login</servlet-filter-name> 
     <servlet-filter-impl>com.test.AutoLoginFilter</servlet-filter-impl> 
    </servlet-filter> 

在AutoLoginFilter

public class AutoLoginFil implements Filter 
{ 

    @Override 
    public void doFilter(ServletRequest arg0, ServletResponse arg1, 
      FilterChain arg2) throws IOException, ServletException { 

//Call external system to authenticate 
     log.debug("doFilter"); 

    } 
} 

調試濾波器不被調用。

在這些方法中是否有錯誤,如果是的話,它是什麼,是否有不同的方法來做到這一點? 我已經看過以下參考資料。

How do I use autologin in liferay?

Liferay - AutoLogin + Authenticator - Get Credentials From Request Header

回答

1

我做了一些更多的玩耍,我能想出辦法來解決這個問題。


2.鉤答案UserLocalService.authenticateByScreenName倍率

步驟1:

<service> 
     <service-type> 
      com.liferay.portal.service.UserLocalService 
     </service-type> 
     <service-impl> 
      com.test.UserService 
     </service-impl> 
    </service> 

步驟2:

擴展UserLocalServiceWrapper並使用自定義類。

public class UserService extends UserLocalServiceWrapper 
{ 

@Override 
    public int authenticateByScreenName(long companyId, String screenName, String password, Map headerMap, Map parameterMap, Map resultsMap) 
    { 
//Call external system to authenticate 

     if(externalAuthenticationSuccess) 
     { 
      return Authenticator.SUCCESS; 
     } 
     else 
     { 
     return Authenticator.FAILURE; 
     } 

} 

這在部署時有效。

這是不工作的時候我張貼的問題,因爲:

  1. 我的服務器有Tomcat的。我在做這個改變之前部署了這個項目。
  2. 一旦我做了更新,我使用了Liferay插件,並使用右鍵單擊項目 - > Liferay-> deploy進行部署。
  3. 我在代碼中使用斷點來查看它是否會在登錄時捕獲它。
  4. 這沒有被捕獲,因爲我使用的Eclipse IDE需要通過服務器下的ReDeploy部署的項目而不是Liferay Plugin命令。

當我使用Eclipse Tomcat服務器進行部署時,它也捕獲到了斷點。

答案

  • auth.pipeline前和檢查=假

    在portal-ext.properties

    auth.pipeline.enable.liferay 。檢查=假 auth.pipeline.pre = com.test.CustomAuthenticator

    public class CustomAuthenticator implements Authenticator 
    { 
        @Override 
        public int authenticateByScreenName(long companyId, String screenName, String password, 
          Map<String, String[]> headerMap, Map<String, String[]> parameterMap) throws AuthException { 
    
    
    
        //Call external system to authenticate 
        if(externalAuthenticationSuccess) 
        { 
         return Authenticator.SUCCESS; 
        } 
        else 
        { 
         return Authenticator.FAILURE; 
        } 
    
    
        } 
    } 
    
  • 這工作過,但它只有在JBoss中,而不是在Tomcat的工作。我部署的portal-ext.properties在

    TOMCAT_HOME \的webapps \ ROOT \ WEB-INF \類

    在JBoss中EAP,它是LIFERAY_HOME下。它可能沒有拿起Tomcat的財產,但在JBoss中。

    在問題中發佈的其他可能的解決方案也可能工作,但我沒有探索一切,找到配置中的錯誤。

    如果對這些解決方案有任何意見或問題,請發佈,我會很樂意提供進一步的步驟。謝謝。

    +0

    嗨,我正在尋找一個類似的項目來驗證外部系統。你還需要自動登錄定製嗎?如果你可以發佈你的外部系統調用,並且在這裏清除了敏感的細節,這將是非常好的。非常感謝! – VC1

    +1

    外部系統調用可以由任何東西(Db,LDAP等)。下面的示例顯示了ldap調用 Hashtable env = new Hashtable (); env.put(Context.INITIAL_CONTEXT_FACTORY,「com.sun.jndi.ldap.LdapCtxFactory」); env.put(Context.PROVIDER_URL,「ldap:// host:port」); env.put(Context.SECURITY_AUTHENTICATION,「simple」); env.put(Context.SECURITY_PRINCIPAL,screenName); //可能需要域 env.put(Context.SECURITY_CREDENTIALS,password); DirContext ctx = new InitialDirContext(env); externalAuthenticationSuccess =(ctx!= null); – user1592521

    +1

    抱歉格式化。我不知道如何使代碼作爲評論,即使我縮進空間後。 – user1592521

    相關問題