Exemple #1
0
def before_request():
    g.signin = verify_sessionId(request.cookies.get("sessionId"))
    g.sid, g.uid = analysis_sessionId(request.cookies.get("sessionId"),
                                      "tuple") if g.signin else (None, None)
    g.ip = request.headers.get('X-Real-Ip', request.remote_addr)
    # 仅是重定向页面快捷定义
    g.redirect_uri = get_redirect_url()
Exemple #2
0
def before_request():
    g.startTime = time.time()
    g.redis = create_redis_engine()
    g.mysql = create_mysql_engine()
    g.signin = verify_sessionId(request.cookies.get("sessionId"))
    g.sid, g.uid = analysis_sessionId(request.cookies.get("sessionId"),
                                      "tuple") if g.signin else (None, None)
    app.logger.debug("uid: {}, sid: {}".format(g.uid, g.sid))
    g.api = api
    g.ip = request.headers.get('X-Real-Ip', request.remote_addr)
    g.agent = request.headers.get("User-Agent")
    # 仅是重定向页面快捷定义
    g.redirect_uri = get_redirect_url()
    # 上下文扩展点之请求后(返回前)
    before_request_hook = plugin.get_all_cep.get("before_request_hook")
    for cep_func in before_request_hook():
        cep_func(request=request, g=g)
    before_request_return = plugin.get_all_cep.get("before_request_return")
    for cep_func in before_request_return():
        resp = cep_func(request=request, g=g)
        try:
            success = resp.is_before_request_return
        except:
            logger.warn(
                "Plugin returns abnormalities when before_request_return")
        else:
            if success is True:
                return resp
Exemple #3
0
def before_request():
    g.signin = verify_sessionId(request.cookies.get("sessionId"))
    g.sid, g.uid = analysis_sessionId(request.cookies.get("sessionId"), "tuple") if g.signin else (None, None)
    g.ip = request.headers.get('X-Real-Ip', request.remote_addr)
    # 仅是重定向页面快捷定义
    g.redirect_uri = get_redirect_url()
    # 上下文扩展点之请求后(返回前)
    before_request_hook = plugin.get_all_cep.get("before_request_hook")
    for cep_func in before_request_hook():
        cep_func(request=request, g=g)
Exemple #4
0
def authorized():
    """ Client SSO 单点登录、注销入口, 根据`Action`参数判断是`ssoLogin`还是`ssoLogout` """
    Action = request.args.get("Action")
    if Action == "ssoLogin":
        # 单点登录
        ticket = request.args.get("ticket")
        if request.method == "GET" and ticket and g.signin == False:
            resp = sso_request("{}/sso/validate".format(sso_server), dict(Action="validate_ticket"), dict(ticket=ticket, app_name=SSO["app_name"], get_userinfo=True, get_userbind=False))
            logger.debug("SSO check ticket resp: {}".format(resp))
            if resp and isinstance(resp, dict) and "success" in resp and "uid" in resp:
                if resp["success"] is True:
                    uid = resp["uid"]
                    sid = resp["sid"]
                    expire = int(resp["expire"])
                    # 获取用户信息,若不需要,可将get_userinfo=True改为False,并注释下两行
                    g.userinfo = resp["userinfo"].get("data") or dict()
                    set_userinfo(uid, g.userinfo, expire)
                    logger.debug(g.userinfo)
                    # 授权令牌验证通过,设置局部会话,允许登录
                    sessionId = set_sessionId(uid=uid, seconds=expire, sid=sid)
                    response = make_response(redirect(get_redirect_url("front.index")))
                    response.set_cookie(key="sessionId", value=sessionId, max_age=expire, httponly=True, secure=False if request.url_root.split("://")[0] == "http" else True)
                    return response
    elif Action == "ssoLogout":
        # 单点注销
        ReturnUrl = request.args.get("ReturnUrl") or get_referrer_url() or url_for("front.index", _external=True)
        NextUrl   = "{}/signOut?ReturnUrl={}".format(sso_server, ReturnUrl)
        app_name  = request.args.get("app_name")
        if request.method == "GET" and NextUrl and app_name and g.signin == True and app_name == SSO["app_name"]:
            response = make_response(redirect(NextUrl))
            response.set_cookie(key="sessionId", value="", expires=0)
            return response
    elif Action == "ssoConSync":
        # 数据同步:参数中必须包含大写的hmac_sha256(app_name:app_id:app_secret)的signature值
        signature = request.args.get("signature")
        if request.method == "POST" and signature and signature == hmac_sha256("{}:{}:{}".format(SSO["app_name"], SSO["app_id"], SSO["app_secret"])).upper():
            try:
                data = json.loads(request.form.get("data"))
                ct = data["CallbackType"]
                cd = data["CallbackData"]
                uid = data["uid"]
                token = data["token"]
            except Exception,e:
                logger.warning(e)
            else:
                logger.info("ssoConSync with uid: {} -> {}: {}".format(uid, ct, cd))
                resp = sso_request("{}/sso/validate".format(sso_server), dict(Action="validate_sync"), dict(token=token, uid=uid))
                if resp and isinstance(resp, dict) and resp.get("success") is True:
                    # 之后根据不同类型的ct处理cd
                    logger.debug("ssoConSync is ok")
                    if ct == "user_profile":
                        g.userinfo.update(cd)
                    elif ct == "user_avatar":
                        g.userinfo["avatar"] = cd
                    return jsonify(msg="Synchronization completed", success=set_userinfo(uid, g.userinfo), app_name=SSO["app_name"])
Exemple #5
0
def before_request():
    g.startTime = time.time()
    g.signin    = verify_sessionId(request.cookies.get("sessionId"))
    g.sid,g.uid = analysis_sessionId(request.cookies.get("sessionId"), "tuple") if g.signin else (None, None)
    g.username  = g.uid
    g.api       = api
    g.plugins   = PLUGINS
    g.userinfo  = api.sso_get_userinfo(g.uid)
    # 仅是重定向页面快捷定义
    g.redirect_uri = get_redirect_url()
    logger.access.debug("sid: {}, uid: {}, userinfo: {}".format(g.sid, g.uid, g.userinfo))
Exemple #6
0
def before_request():
    g.signin = verify_sessionId(request.cookies.get("sessionId"))
    g.sid, g.uid = analysis_sessionId(request.cookies.get("sessionId"),
                                      "tuple") if g.signin else (None, None)
    # 用户信息
    g.userinfo = get_userinfo(g.uid)
    app.logger.debug(g.userinfo)
    # 客户端IP地址
    g.ip = request.headers.get('X-Real-Ip', request.remote_addr)
    # 仅是重定向页面快捷定义
    g.redirect_uri = get_redirect_url()
Exemple #7
0
def before_request():
    g.rc = rc
    g.site = get_site_config()
    g.cfg = Attribute(g.site)
    g.signin, g.userinfo = default_login_auth()
    #: Trigger hook, you can modify flask.g
    hm.call("before_request")
    #: (Logged-on state)required field: username, is_admin
    g.userinfo = Attribute(change_userinfo(g.userinfo))
    g.is_admin = is_true(g.userinfo.is_admin)
    g.next = get_redirect_url()
Exemple #8
0
def before_request():
    g.signin = verify_sessionId(request.cookies.get("sessionId"))
    g.sid, g.uid = analysis_sessionId(request.cookies.get("sessionId"), "tuple") if g.signin else (None, None)
    g.redis = from_url(REDIS)
    g.site = getSystem(g.redis, sysKey)["data"]
    print g.uid
    # 仅是重定向页面快捷定义
    g.redirect_uri = get_redirect_url()
    # 上下文扩展点之请求后(返回前)
    before_request_hook = plugin.get_all_cep.get("before_request_hook")
    for cep_func in before_request_hook():
        cep_func(request=request, g=g)
Exemple #9
0
def before_request():
    sessionId = request.cookies.get("sessionId",
                                    request.headers.get("sessionId"))
    g.startTime = time.time()
    g.redis = create_redis_engine()
    g.mysql = create_mysql_engine()
    g.signin = verify_sessionId(sessionId)
    g.sid, g.uid = analysis_sessionId(sessionId,
                                      "tuple") if g.signin else (None, None)
    logger.debug("uid: {}, sid: {}".format(g.uid, g.sid))
    g.api = api
    g.ip = request.headers.get('X-Real-Ip', request.remote_addr)
    g.agent = request.headers.get("User-Agent")
    # 仅是重定向页面快捷定义
    g.redirect_uri = get_redirect_url()
Exemple #10
0
def before_request():
    g.startTime = time.time()
    g.signin = verify_sessionId(request.cookies.get("sessionId"))
    g.sid, g.uid = analysis_sessionId(request.cookies.get("sessionId"),
                                      "tuple") if g.signin else (None, None)
    g.username = g.uid
    g.api = api
    g.plugins = PLUGINS
    g.userinfo = api.sso_get_userinfo(g.uid)
    # 仅是重定向页面快捷定义
    g.redirect_uri = get_redirect_url()
    #上下文扩展点之请求后(返回前)
    before_request_hook = plugin.get_all_cep.get("before_request_hook")
    for cep_func in before_request_hook():
        cep_func(request=request, g=g)
    logger.access.debug("sid: {}, uid: {}, userinfo: {}".format(
        g.sid, g.uid, g.userinfo))
Exemple #11
0
def authorized():
    """ Client SSO 单点登录、注销入口, 根据`Action`参数判断是`ssoLogin`还是`ssoLogout` """
    Action = request.args.get("Action")
    if Action == "ssoLogin":
        # 单点登录
        ticket = request.args.get("ticket")
        if request.method == "GET" and ticket and g.signin == False:
            resp = sso_request(
                "{}/sso/validate".format(sso_server),
                dict(Action="validate_ticket"),
                dict(ticket=ticket,
                     app_name=SSO["app_name"],
                     get_userinfo=True,
                     get_userbind=False))
            logger.sys.debug("SSO check ticket resp: {}".format(resp))
            if resp and isinstance(
                    resp, dict) and "success" in resp and "uid" in resp:
                if resp["success"] is True:
                    uid = resp["uid"]
                    sid = resp["sid"]
                    expire = int(resp["expire"])
                    g.userinfo = resp["userinfo"].get("data") or dict()
                    logger.sys.debug(g.userinfo)
                    # 授权令牌验证通过,设置局部会话,允许登录
                    sessionId = set_sessionId(uid=uid, seconds=expire, sid=sid)
                    response = make_response(
                        redirect(get_redirect_url("front.index")))
                    response.set_cookie(
                        key="sessionId",
                        value=sessionId,
                        max_age=expire,
                        httponly=True,
                        secure=False if request.url_root.split("://")[0]
                        == "http" else True)
                    return response
    elif Action == "ssoLogout":
        # 单点注销
        ReturnUrl = request.args.get("ReturnUrl") or get_referrer_url(
        ) or url_for("front.index", _external=True)
        NextUrl = "{}/signOut?ReturnUrl={}".format(sso_server, ReturnUrl)
        app_name = request.args.get("app_name")
        if request.method == "GET" and NextUrl and app_name and g.signin == True and app_name == SSO[
                "app_name"]:
            response = make_response(redirect(NextUrl))
            response.set_cookie(key="sessionId", value="", expires=0)
            return response
    elif Action == "ssoConSync":
        # 数据同步:参数中必须包含大写的hmac_sha256(app_name:app_id:app_secret)的signature值
        # 此处可以改为要求登录,passport sessionId可以解析出所需要的sid、uid
        signature = request.args.get("signature")
        if request.method == "POST" and signature and signature == hmac_sha256(
                "{}:{}:{}".format(SSO["app_name"], SSO["app_id"],
                                  SSO["app_secret"])).upper():
            try:
                data = json.loads(request.form.get("data"))
                ct = data["CallbackType"]
                cd = data["CallbackData"]
                uid = data["uid"]
                token = data["token"]
            except Exception, e:
                logger.plugin.warning(e)
            else:
                logger.plugin.info("ssoConSync with uid: {} -> {}: {}".format(
                    uid, ct, cd))
                resp = sso_request("{}/sso/validate".format(sso_server),
                                   dict(Action="validate_sync"),
                                   dict(token=token, uid=uid))
                if resp and isinstance(resp,
                                       dict) and resp.get("success") is True:
                    # 之后根据不同类型的ct处理cd
                    logger.plugin.debug("ssoConSync is ok")
                    if ct == "user_profile":
                        # like {u'nick_name': u'.\u5f18\u5f08', u'gender': u'1', u'domain_name': u'taochengwei', u'birthday': u'1995-04-22', u'location': u'\u5317\u4eac \u671d\u9633', u'signature': u'\u5c81\u6708\u5982\u5200\u65a9\u5929\u9a84'}
                        logger.plugin.debug(
                            "sync user_profile before: {}".format(g.userinfo))
                        g.userinfo.update(cd)
                        logger.plugin.debug(
                            "sync user_profile after: {}".format(g.userinfo))
                    elif ct == "user_avatar":
                        logger.plugin.debug(
                            "sync user_avatar before: {}".format(
                                g.userinfo["avatar"]))
                        g.userinfo["avatar"] = cd
                        logger.plugin.debug(
                            "sync user_avatar after: {}".format(
                                g.userinfo["avatar"]))
                    return jsonify(msg="Synchronization completed",
                                   success=g.api.sso_set_userinfo(
                                       uid, g.userinfo),
                                   app_name=SSO["app_name"])
Exemple #12
0
def signIn():
    """ 单点登录流程
        1. Client跳转到Server的登录页,携带参数sso(所需sso信息的加密串),验证并获取应用数据。
        2. 未登录时,GET请求显示登录表单,输入用户名密码或第三方POST登录成功后(一处是signIn post;一处是OAuthDirectLogin post;一处是OAuthBindAccount post),创建全局会话(设置Server登录态)、授权令牌ticket,根据ticket生成sid(全局会话id)写入redis,ReturnUrl组合ticket跳转;
           已登录后,检查是否有sid,没有则创建ticket,ReturnUrl组合ticket跳转。
        3. 校验参数通过后,设置ReturnUrl(从数据库读取)为Client登录地址;校验未通过时ReturnUrl为系统redirect_uri。
        4. Client用ticket到Server校验(通过api方式),通过redis校验cookie是否存在;存在则创建局部会话(设置Client登录态),否则登录失败。
        -- sso加密规则:
            aes_cbc(jwt_encrypt("app_name:app_id.app_secret"))
        -- sso校验流程:
            根据sso参数,验证是否有效,解析参数获取name、id、secret等,并用name获取到对应信息一一校验
        -- 备注:
            第3步,需要signIn、OAuthGuide方面路由设置
            第4步,需要在插件内增加api路由
    """
    # 加密的sso参数值
    sso = request.args.get("sso") or None
    sso_isOk, sso_returnUrl, sso_appName = checkGet_ssoRequest(sso)
    logger.debug("method: {}, sso_isOk: {}, ReturnUrl: {}".format(
        request.method, sso_isOk, sso_returnUrl))
    if g.signin:
        # 已登录后流程
        # 如果没有sid说明是本地登录,需要重置登录态
        if sso_isOk:
            if g.sid:
                # 创建ticket,返回为真即是ticket
                tickets = g.api.usersso.ssoCreateTicket(sid=g.sid,
                                                        agent=g.agent,
                                                        ip=g.ip)
                if tickets:
                    ticket, sid = tickets
                    returnUrl = "{}&ticket={}".format(sso_returnUrl, ticket)
                    return redirect(returnUrl)
                else:
                    flash(
                        dfr(dict(msg="Failed to create authorization ticket")))
            else:
                sessionId, returnUrl = checkSet_ssoTicketSid(
                    sso_isOk, sso_returnUrl, sso_appName, g.uid,
                    get_redirect_url("front.userset"))
                return set_redirectLoginstate(sessionId, returnUrl)
        return redirect(url_for("front.userset"))
    else:
        # 未登录时流程
        if request.method == 'POST':
            # POST请求不仅要设置登录态、还要设置全局会话
            res = dict(msg=None,
                       code=1,
                       nextUrl=url_for('.signIn', sso=sso)
                       if sso_isOk else url_for('.signIn'))
            if vaptcha.validate:
                auth = Authentication(g.mysql, g.redis)
                result = auth.signIn(account=request.form.get("account"),
                                     password=request.form.get("password"))
                if result["success"]:
                    # 记录登录日志
                    auth.brush_loginlog(result,
                                        login_ip=g.ip,
                                        user_agent=g.agent)
                    sessionId, returnUrl = checkSet_ssoTicketSid(
                        sso_isOk, sso_returnUrl, sso_appName, result["uid"],
                        get_redirect_url("front.userset"))
                    logger.debug("signIn post returnUrl: {}".format(returnUrl))
                    res.update(nextUrl=returnUrl, code=0)
                    return set_jsonifyLoginstate(sessionId, dfr(res))
                    #return set_redirectLoginstate(sessionId, returnUrl)
                else:
                    res.update(msg=result["msg"])
            else:
                res.update(msg="Man-machine verification failed")
            return jsonify(dfr(res))
            #return redirect(url_for('.signIn', sso=sso)) if sso_isOk else redirect(url_for('.signIn'))
        else:
            # GET请求仅用于渲染
            return render_template("auth/signIn.html",
                                   vaptcha=vaptcha.getChallenge)