跟其他系統集成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:
实现拦截页面请求的方法:
- 扩展
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;
}
}));
}
}
- 修改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>
- 结合文档 处理社交服务响应 及楼上建议,在 RequestHandler中实现认证过程。
有一个A系统,是用其他框架开发的,B系统是基于cuba做的,A系统界面上有B系统的链接;当A系统登录成功后打开了A系统的界面,再点击B系统的链接,跳转到B系统,顺便把A系统的账户信息也带到了B系统;到了B系统以后从request里获取用户信息做验证,验证通过后打开B系统的主界面。这里重点是先打开A系统登录,登录完打开A系统的主界面,在跳转到B(cuba)系统;
那现在是哪一步有问题?
想知道是对外提供链接就是这个http://localhost:8080/app地址吗?然后用这个CubaApplicationServletExt就能获取用户信息吗
登录过程报空指针异常
空指针异常
你好,
之前的方式在处理AppUI时比较麻烦, 你可以用下面的方式,更简单一些:
- 扩展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);
}
}
- 替换框架内置AppUI bean:
在web-spring.xml 中添加:
<bean id="cuba_AppUI" class="com.xxx.web.app.AppUI" scope="prototype" />
用postman请求跳不到这个方法里,取不到数据,request.getHeader(“username”);能跳到CubaApplicationServletExt里。
没有明白你的意思 ,什么地方不安全?你是要通过header传递什么数据?怎样传递?能详细描述一下吗?
- 一般来说不要直接传递 username等凭据, 而是传递过来一个token,然后根据token去认证服务获取用户信 息。认证服务对token进行验证,验证通过再给username。
- 我有点好奇,你是通过什么方式跳转到 CUBA app的? 能贴出执行跳转那段代码吗?