jfinal与kisso跨域单点登陆

来源:https://www.itdaan.com/blog/2016/12/27/f5f37de997975cf2edcfd7f955dab754.html

1. 引言

之前介绍了kisso与jfinal的简单使用,但是单单这种方式满足不了一些需求,举个例子,一个系统的中分别有很多的子系统,这样的情况下我们做单点登陆,就面临着一个问题,在不同的子系统中IP地址不一样,域名不一样,相对的用户登陆自后所对应的cookie就不能带到其他系统上去。相当于之前登陆的是无效的,又要重新进行登陆。这就所谓的跨域问题。

2. 流程

kisso解决跨域的流程:

大致意思是,用户登陆,访问sso服务器,进行账户密码校验,如果登陆成功则返回一个token给用户返回的形式为cookie。然后 用户又去访问其他的子系统,这是由于域名不一样,先前的登陆成功的token就不会被带过去,子系统发现用户没有token,就跳转sso系统询问用户是否登陆,这时跳转就会带上我们之前的token了,sso系统拿到用户的token就代表着用户登陆过。然后返回一个应答给子系统也就是这里的my了。子系统收到sso的应答信息,判断用户是否登陆过,如果登陆过就重新生成一个token,注意这里的token跟先前的token是不会冲突的,因为domain不一样。最后就返回给用户想访问的页面。

3. 具体过程

先配置sso系统。

1.1 添加依赖

        <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>kisso</artifactId>
        <version>3.6.13</version>
    </dependency>

1.2 kisso配置文件

image.png

因为kisso的默认的加密机制是RC4,这个加密方式是可以更改的。sso系统必须的保存各个系统的公钥,以及自己的私钥,为什么呢?因为涉及到数据的验证以及数据的加密。这不是废话么,好了,子系统向sso询问用户是否登陆的时候会发送一些加密信息,然后sso系统拿到这些信息后就要用子系统的公钥来验证是否是子系统所发送的,然后在向子系统发送应答信息,当然这也是加密的,子系统拿到以后在进行验证。从而保证了一定的安全性。上面的篇日志文件还有一点需要注意的是sso.authcookie.secretkey这个属性每个系统都要写成一样的,方便加密与解密。

1.3 插件代码如下

/**
 * Kisso jfinal 插件形式初始化
 * jfinal 拦截器不够灵活,因此写在 demo 中,方便您自己修改。

 */
public class KissoJfinalPlugin implements IPlugin {

protected static final Logger logger = Logger.getLogger("WebKissoConfigurer");
/**
 * 初始化
 */
public boolean start() {
    WebKissoConfigurer ssoConfig = new WebKissoConfigurer("sso.properties");
    // 此处可以实现自己的 KISSO 插件,也可动态注入 SSO 配置属性。
    // ssoConfig.setPluginList(pluginList);
    //运行模式设置,可选择指定模式的配置
    ssoConfig.setRunMode("test_mode");
    ssoConfig.initKisso();
    return true;
}


/**
 * 销毁
 */
public boolean stop() {
    logger.info("Uninstalling Kisso ");
    return true;
}

}

1.4 jfinal的配置如下

public class DemoConfig extends JFinalConfig {



//配置设置
@Override
public void configConstant(Constants constants) {
        constants.setDevMode(true);
        constants.setEncoding("utf-8");
}
//配置路由
@Override
public void configRoute(Routes routes) {
        routes.add("/", IndexController.class);
        routes.add("/login", LoginController.class);
        routes.add("/logout", LogoutController.class);
        routes.add("/reply", ReplyLoginController.class);
}

@Override
public void configPlugin(Plugins plugins) {
    KissoJFinalPlugin kissoJFinalPlugin = new KissoJFinalPlugin();
    //初始化插件
    plugins.add(kissoJFinalPlugin);


}

@Override
public void configInterceptor(Interceptors interceptors) {

}

@Override
public void configHandler(Handlers handlers) {

}
}

1.5 登录设置

      public void index(){
      HttpServletRequest request = getRequest();
    HttpServletResponse Response = getResponse();
    String returnURL = getPara("returnURL");
    String referer = getPara("referer");
    String str = getPara("str");
    String info = getPara("info","");
    MyToken mt = SSOHelper.getToken(request);
    if(info.contains("异常登录")){
        mt=null;
        SSOHelper.clearLogin(request, Response);
    }
    if(mt!=null)
        forwardAction("/login");  //如果sso有Cookie,则直接尝试登录
    else{
        System.err.println("没有 Token");
        setAttr("str", str);
        setAttr("info", info);
        setAttr("returnURL", returnURL);
        setAttr("referer", referer);
        render("login.html");   //弹出登录页面
    }
}
public void login() throws IOException{
    HttpServletRequest request = getRequest();
    HttpServletResponse Response = getResponse();
    String returnURL = getPara("returnURL");
    String referer = getPara("referer");
    String str = getPara("str");
    Integer remember = getParaToInt("remember",0);
    String username = getPara("username");
    String password = getPara("password");
    MyToken mt = SSOHelper.getToken(request);
    if(mt!=null){
        username = mt.getUsername();
        password = mt.getPassword();
        System.err.println("从Token登录");
    }
    User u = User.dao.findByUsername(username);
    if(u!=null){
        UserService userService = new UserService();
        if(!userService.passwdValidate(u, password))
            u=null;
    }
    if(u!=null){     //用户验证
        if(mt==null){
            if(remember==1)
                request.setAttribute(SSOConfig.SSO_COOKIE_MAXAGE, 3600*24*5);//保存5天
            else
                request.setAttribute(SSOConfig.SSO_COOKIE_MAXAGE, -1);//浏览器关闭就清除
            mt = new MyToken();
            mt.setUsername(username);
            mt.setPassword(password);
            SSOHelper.setSSOCookie(request, Response, mt, false);
        }
        if(StrKit.isBlank(returnURL) || StrKit.isBlank(str)) {
            setAttr("username", username);
            render("index.html"); //sso系统主页面
        } else {
            HttpClient http=new HttpClient(Response);
            String validate = str + salt + username;
            validate = EncryptStr.encodeByMD5(validate);
            http.setParameter("validate",validate);
            http.setParameter("username",username);
            http.setParameter("referer",referer);
            http.sendByPost(returnURL);    //验证通过,重定向到子系统
            System.err.println("sso login登录成功:"+username+"   "+returnURL+"   rememberPW:"+remember);
            renderNull();
        }
    }else{
        setAttr("str", str);
        setAttr("returnURL", returnURL);
        setAttr("referer", referer);
        setAttr("info", "用户名或者密码错误");
        render("login.html");
        SSOHelper.clearLogin(getRequest(), getResponse());
    }
}

子系统接收响应,判断用户是否通过,通过直接登录

      public void login() {
       String validate = getPara("validate");
       String username = getPara("username");
       User loginUser = getSessionAttr("user");
       if(loginUser != null) {
           userLogin(loginUser.getUsername());
       } else if(StrKit.isBlank(validate)) {
           toSSO("", RETURN_URL, SSO_URL);
       } else {
           String str = getSessionAttr("str");
           if(validate.equals(EncryptStr.encodeByMD5(str +  ConfigConsts.SALT + username))){
               System.err.println("通过验证,使用用户名称登录");
               removeSessionAttr("str");
               userLogin(username);   //用户登录
           }else{
               toSSO("异常登录", RETURN_URL, SSO_URL);
           }
       }
   }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 224,467评论 6 522
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,079评论 3 402
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 171,600评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,835评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,848评论 6 399
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,348评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,735评论 3 428
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,705评论 0 279
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,238评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,268评论 3 345
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,395评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,012评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,704评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,177评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,309评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,925评论 3 381
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,457评论 2 365

推荐阅读更多精彩内容

  • 作者:刘宾, thomas_liub@hotmail.com 请尊重作者著作权,转载请注明出处,谢谢! SSO笔...
    橄榄树下的托马斯阅读 2,138评论 0 5
  • Q:什么是单点登陆 在多系统应用群众登陆一个系统,便可在其他所有系统中得到授权而无需再次登陆,包括单点登陆和单点注...
    BubbleM阅读 995评论 0 2
  • 定义:在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统。 例子:比如淘宝和天猫,只要登陆其中一个...
    胖三斤66阅读 562评论 0 1
  • 前言 在我实习之前我就已经在看单点登录的是什么了,但是实习的时候一直在忙其他的事,所以有几个网站就一直躺在我的收藏...
    程序人生a阅读 1,776评论 0 0
  • 单系统登陆 普通的单个系统登陆流程是什么样子的呢?用户访问系统,如果访问的是受限制的资源,比如http://loc...
    小吴可是全村的希望阅读 460评论 0 2