def Login(): """ Client登录地址,需要跳转到SSO Server上 """ ReturnUrl = request.args.get("ReturnUrl") or get_referrer_url() or url_for("front.index", _external=True) if url_check(sso_server): NextUrl = "{}/sso/?sso={}".format(sso_server, set_ssoparam(ReturnUrl)) return redirect(NextUrl) else: return "Invalid Configuration"
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"])
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"])
def Logout(): """ Client注销地址,需要跳转到SSO Server上 """ ReturnUrl = request.args.get("ReturnUrl") or get_referrer_url() or url_for( "front.index", _external=True) NextUrl = "{}/signOut?ReturnUrl={}".format(sso_server, ReturnUrl) return redirect(NextUrl)