Java 无密码登录Liferay用户

Java 无密码登录Liferay用户,java,authentication,login,liferay,hook,Java,Authentication,Login,Liferay,Hook,我需要通过对外部系统进行身份验证来登录Liferay中的用户。但是,我仍然需要一个有效的Liferay会话。所以,我需要通过登录Liferay 向用户询问用户名/密码 使用它们对外部系统进行身份验证 仅使用用户名(而不是密码)对Liferay登录进行身份验证 如果外部系统登录成功,请登录用户 我做了几件事: 自动登录 挂钩到UserLocalService.authenticateByScreenName覆盖 auth.pipeline pre和check=false 登录过滤器 这些都不起作用

我需要通过对外部系统进行身份验证来登录Liferay中的用户。但是,我仍然需要一个有效的Liferay会话。所以,我需要通过登录Liferay

  • 向用户询问用户名/密码
  • 使用它们对外部系统进行身份验证
  • 仅使用用户名(而不是密码)对Liferay登录进行身份验证
  • 如果外部系统登录成功,请登录用户
  • 我做了几件事:

  • 自动登录
  • 挂钩到UserLocalService.authenticateByScreenName覆盖
  • auth.pipeline pre和check=false
  • 登录过滤器 这些都不起作用。下面是对这些方法的解释。这个想法包括 //如果这些方法有效,将包括调用外部系统进行身份验证。 请纠正我在哪里犯的错误,以及与其他方法相比,某些方法是否更好

    1。自动登录:

    a。设置portal-ext.properties

     auto.login.hooks=com.poc.AutoLoginFil
    
    auth.pipeline.enable.liferay.check=false
    auth.pipeline.pre=com.test.AutoLoginCustom
    
    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覆盖

    a。在liferay-hook.xml中

    <service>
            <service-type>
                com.liferay.portal.service.UserLocalService
            </service-type>
            <service-impl>
                com.test.UserService
            </service-impl>
        </service>
    
    当我登录时,它应该可以使用任何密码。事实并非如此

    3。auth.pipeline pre and check=false

    a。在portal-ext.properties中

     auto.login.hooks=com.poc.AutoLoginFil
    
    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。部署项目并重新启动服务器。去。使用用户名和不同密码登录。它不登录。它甚至没有达到自定义java中的调试点

    4。登录过滤器 在liferay-hook.xml中

    <servlet-filter>
            <servlet-filter-name>Login</servlet-filter-name>
            <servlet-filter-impl>com.test.AutoLoginFilter</servlet-filter-impl>
        </servlet-filter>
    
    未调用调试筛选器

    这些方法中是否有错误?如果有,是什么错误?是否有不同的方法? 我已经看过以下参考资料


    我又做了一些尝试,我找到了解决这个问题的方法


    2.挂钩到UserLocalService.authenticateByScreenName覆盖

    步骤1:

    <service>
            <service-type>
                com.liferay.portal.service.UserLocalService
            </service-type>
            <service-impl>
                com.test.UserService
            </service-impl>
        </service>
    
    这在部署时有效

    这在我发布问题时不起作用,因为:

  • 我在服务器上安装了Tomcat。在进行此更改之前,我部署了该项目
  • 完成更新后,我使用Liferay插件并使用右键单击Project->Liferay->deploy进行部署
  • 我在代码中使用了断点,以查看它是否会在登录时捕获它
  • 这并没有被捕获,因为我使用的EclipseIDE需要通过服务器下的重新部署来部署项目,而不是Liferay插件命令 当我使用EclipseTomcat服务器部署时,它捕获了断点

    答案

  • auth.pipeline pre和check=false

    在portal-ext.properties中

     auto.login.hooks=com.poc.AutoLoginFil
    
    auth.pipeline.enable.liferay.check=false
    auth.pipeline.pre=com.test.AutoLoginCustom
    
    auth.pipeline.enable.liferay.check=false 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; 
        } 
    
    
        }
    }
    
    公共类CustomAuthenticator实现验证器
    {
    @凌驾
    public int authenticateByScreenName(长公司ID、字符串屏幕名、字符串密码、,
    映射头映射、映射参数映射)引发AuthException{
    //调用外部系统进行身份验证
    if(externalAuthenticationSuccess)
    {
    返回Authenticator.SUCCESS;
    }
    其他的
    {
    返回Authenticator.FAILURE;
    } 
    }
    }
    
  • 这也行得通,但它只在JBoss中起作用,而在Tomcat中不起作用。我在中部署了portal-ext.properties

    TOMCAT\u HOME\webapps\ROOT\WEB-INF\classes

    在JBoss EAP中,它位于Liferay_Home下。它可能没有在Tomcat中获得属性,但在JBoss中获得了

    问题中发布的其他可能的解决方案也可能有效,但我并没有探究所有问题以发现配置中的错误


    如果对这些解决方案有任何意见或疑问,请发布,我很乐意提供进一步的步骤。多谢各位

    外部系统调用可以通过任何方式进行(Db、LDAP等)。下面的示例显示ldap调用Hashtable env=new Hashtable();put(Context.INITIAL\u Context\u工厂,“com.sun.jndi.ldap.LdapCtxFactory”);env.put(Context.PROVIDER\u URL,“ldap://host:port"); 环境put(Context.SECURITY_认证,“simple”);环境放置(Context.SECURITY\u主体,屏幕名称)//可能需要域env.put(Context.SECURITY\u凭据、密码);DirContext ctx=新的初始DirContext(env);externalAuthenticationSuccess=(ctx!=null);很抱歉格式化。我不知道如何使注释成为代码,即使在我缩进空格之后。我无法使1和4工作。我不需要为第2点和第3点进行autologin定制。很抱歉,我无法提供这些步骤。很抱歉我没有及时回复。是的,我必须调用user=UserLocalServiceUtil.getUserByScreenName(主题显示.getCompanyId(),用户名);该用户仍存在于Liferay中的用户中。只是没有使用它进行身份验证。你是说当添加新用户时?当它们注册时,我们调用常规的Liferay注册步骤,除非我们将autopassword参数设置为true。这将让Liferay选择一个密码,而不管它是什么。用户将不会使用该选项。如果您正在谈论从外部系统导入一个新用户,是的,我们正在使用一个注册脚本,该脚本在用户不参与的情况下进行Liferay注册。