跟其他系統集成SSO单点登录,怎么设置

跟其他系統集成SSO单点登录,怎么设置:从别的系统跳转到cuba

你好,
建议先参考文章:匿名访问 & 社交登录
特别是其中的处理社交服务响应 章节。

先尝试,然后针对具体问题讨论。

我这边的需求是cuba平台给别的系统提供一个url地址,把这个url集成到到别的系统里,然后从别的系统点击这个url,发送request请求,request的header里有用户信息;到了Cuba平台以后通过request.getHeader(“username”)获取用户信息,做校验,校验通过自动登录cuba平台,打开有权限的界面。

我现在想知道cuba用什么方式对外提供一个url,怎么获取request里的header信息


先看下这个帖子提了cuba目前SSO逻辑。

如果你需要跳到cuba的登录页让cuba管理登录的用户名密码,返回给其他应用的只是用户信息和token之类,那就需要仔细研究下目前的逻辑。
如果你的其他应用有用户名密码 只是去cuba验证一下,就简单,直接调用rest或idp的登录接口就可以。

在 CUBA 应用中,实现这个功能,不需要对外另外再提供URL,CUBA GUI 应用是基于Vaadin 的,所以使用 Vaadin 提供的 RequestHandler 来拦截页面请求即可。

要使用授权码处理社交服务响应,我们可以使用 Vaadin Request Handlers 机制 - 它允许我们使用函数式接口处理请求回调。

我们的回调处理器将使用 SocialLoginService 获取用户数据,所以它应该是一个 Bean。 请求处理器应该在请求前添加到当前 session, 并且在请求结束后移除。这表示我们可以将处理器实现为 prototype Bean:

实现拦截页面请求的方法:

  1. 扩展 CubaApplicationServlet
public class CubaApplicationServletExt extends CubaApplicationServlet {
    Logger logger= LoggerFactory.getLogger(CubaApplicationServletExt.class);
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        super.init(servletConfig);
        getService().addSessionInitListener((SessionInitListener) event -> event.getSession().addRequestHandler(new RequestHandler() {
            @Override
            public boolean handleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException {
              //TODO: 获取URL 参数、登录 CUBA App 或跳转
                return false;
            }
        }));
    }
}
  1. 修改web.xml, 使用 CubaApplicationServletExt 替换默认的CubaApplicationServlet :
  <servlet>
        <servlet-name>app_servlet</servlet-name>
        <servlet-class>com.xx.web.app.CubaApplicationServletExt</servlet-class>
        <async-supported>true</async-supported>
    </servlet>
  1. 结合文档 处理社交服务响应 及楼上建议,在 RequestHandler中实现认证过程。

有一个A系统,是用其他框架开发的,B系统是基于cuba做的,A系统界面上有B系统的链接;当A系统登录成功后打开了A系统的界面,再点击B系统的链接,跳转到B系统,顺便把A系统的账户信息也带到了B系统;到了B系统以后从request里获取用户信息做验证,验证通过后打开B系统的主界面。这里重点是先打开A系统登录,登录完打开A系统的主界面,在跳转到B(cuba)系统;

那现在是哪一步有问题?

想知道是对外提供链接就是这个http://localhost:8080/app地址吗?然后用这个CubaApplicationServletExt就能获取用户信息吗

是的,建议深入理解之前提到的文章:

结合文档 处理社交服务响应 及楼上建议,在 RequestHandler中实现认证过程。

登录过程报空指针异常
image
空指针异常
image

image

你好,
之前的方式在处理AppUI时比较麻烦, 你可以用下面的方式,更简单一些:

  1. 扩展AppUI类:
package com.xxx.web.app;

import com.haulmont.cuba.gui.navigation.NavigationState;
import com.haulmont.cuba.web.security.ExternalUserCredentials;
import com.vaadin.server.VaadinRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Locale;

public class AppUI extends com.haulmont.cuba.web.AppUI {
    Logger logger= LoggerFactory.getLogger(this.getClass());
    @Override
    protected void processRequest(NavigationState navigationState) {
        super.processRequest(navigationState);
    }

    void externalAuthenticate(String token){
      // 验证token、登录 
        Locale local = new Locale("zh","CN");
        ExternalUserCredentials credentials = new ExternalUserCredentials("sx_sdy", local);
        getApp().getConnection().login(credentials);
    }
    @Override
    protected void processExternalLink(VaadinRequest request, NavigationState requestedState) {
        String token = request.getParameter("token");
        if(!StringUtils.isEmpty(token)){
            try{
                externalAuthenticate(token);
            }catch (Throwable throwable){
                logger.error("外部登录出现异常",throwable);
            }finally {

            }
        }
        super.processExternalLink(request, requestedState);
    }
}

  1. 替换框架内置AppUI bean:
    在web-spring.xml 中添加:
    <bean id="cuba_AppUI" class="com.xxx.web.app.AppUI" scope="prototype" />

用postman请求跳不到这个方法里,取不到数据,request.getHeader(“username”);能跳到CubaApplicationServletExt里。

直接在地址栏输入app地址测试,比如 http://127.0.0.1:8080/app?token=xxxx

http://127.0.0.1:8080/app?token=xxxx这样是没问题的,但是需求为安全考虑,只通过request.setHeader来传数据呢,这样就request.getHeader收不到数据了

没有明白你的意思 ,什么地方不安全?你是要通过header传递什么数据?怎样传递?能详细描述一下吗?

[http://127.0.0.1:8080/app?username=xxxxx不安全,username信息别处通过request.setHeader(“usernmme”,“xxxxx”)来传递过来,cuba里用request.getHeader(“usernmme”)来获取信息,但是没获取到用户信息

  • 一般来说不要直接传递 username等凭据, 而是传递过来一个token,然后根据token去认证服务获取用户信 息。认证服务对token进行验证,验证通过再给username。
  • 我有点好奇,你是通过什么方式跳转到 CUBA app的? 能贴出执行跳转那段代码吗?