• oauth2单点登录集成


    单点登陆

    概念: 单点登录其实就是在多个系统之间建立链接, 打通登录系统, 让同一个账号在多个系统中通用

    举个例子: 登录Gmail的时候可以用账号密码登录, 也可以用google账号登录, 而使用google账号登录就是这里的单点登录

    下面我将记录一下我们系统集成明道云(低代码平台)的单点登录功能

    单点登录流程图

    1. 集成明道云的单点登录功能

    这是开发文档(虽然写的比较烂)
    https://docs.pd.mingdao.com/faq/sso/oauth
    

    有几个比较恶心的点

    • 挂载配置文件sso.json, 这个配置文件一定要配置好, 否则后患无穷

    • 另外还有一个就是几个请求的入出参数, 这两个请求都是需要在自己系统开发, 提供给明道云调用

      • /access_token
      • /userInfoUrl
    • 另外可以去私有化部署后台查看错误日志, 搜索sso

    至此, 明道云算是集成完成, 这是我在本地测试环境下配置的sso.json

    2. 本地测试环境搭建

    这里我用flask搭建了一个测试平台, 对接第三方Github的oauth2单点登录, 如何去对接第三方github测试平台可以参考下面的文档

    https://blog.csdn.net/CSDN2497242041/article/details/120416969
    

    这里后端的思路(这里提供的后端接口都要和配置文件相对应):

    1. /login 接收明道云跳转到本地的地址
    2. /callback 对接第三方Github的回调地址(返回时会携带授权码code)
    3. /access_token 提供给明道云获取token的接口
    4. /getUserInfo 提供给明道云获取用户信息的接口

    3. 本地测试源码

    这些都是本地测试的情况下, 故很多数据是模拟的

    from flask import Flask, request, redirect, url_for, jsonify
    from oauthlib.oauth2 import WebApplicationClient
    import requests
    
    app = Flask(__name__)
    
    # 定义OAuth2客户端配置
    client_id = 'd0477fd462f8cc3a22a'
    client_secret = 'be3c5c91d0d67c92217c9a20674749e316d9c11'
    authorization_endpoint = 'https://github.com/login/oauth/authorize'
    token_endpoint = 'http://106.15.59.77:8880/orgsso/oauth2'
    redirect_uri = 'https://ae50-180-164-83-69.ngrok-free.app/callback'  # 替换成你的后端服务器的回调URL
    
    client = WebApplicationClient(client_id)
    access_token = "kl34j23kl4j23lk4jkl23"  # kl34j23kl4j23lk4jkl23
    USER_INFO = {
        "uid": "112",  # 111, 112
        "name": "帅哥",
        "email": "nbaba@qq.com",
        "mobilePhone": "11111111111",
        "positions": ["职位1", "职位2"],
        "departments": ["部门1", "部门2"]
    }
    
    
    # 启动OAuth2认证流程
    @app.route('/login')
    def login():
        username = request.args.get("username")
        password = request.args.get("password")
        USER_INFO['name'] = username
        # 创建OAuth2授权请求 -> github
        authorization_url, state, _ = client.prepare_authorization_request(
            authorization_endpoint,
            redirect_url=redirect_uri
        )
        print(authorization_url)
        return redirect(authorization_url)
    
    
    # 处理OAuth2回调
    @app.route('/callback')
    def callback():
        # 获取授权码
        code = request.args.get('code')
        print(code)
    
        # 到github中获取access_token
        # access_token_url = "https://github.com/login/oauth/access_token?code=%s&client_id=%s&client_secret=%s" % (
        # code, client_id, client_secret)
        # resp = requests.get(access_token_url)
        # access_token = resp.text.split("&")[0].split('=')[-1]
        # print(access_token)
    
        # getUserInfo_url = "https://api.github.com/user?access_token=%s" % access_token
        # headers = {
        #     "Authorization": "token %s" % access_token
        # }
        # resp = requests.get(getUserInfo_url, headers=headers)
        # print(resp.text)
    
        # 使用授权码请求访问令牌
    
        token_url = "http://106.15.59.77:8880/orgsso/oauth2"
        # params = {
        #     "code": code
        # }
        # token_response = requests.get(token_url, params=params)
        # print(token_response, token_response.text)
        return redirect(token_url + "?code=%s" % code)
    
    
    @app.route('/access_token', methods=['POST'])
    def token():
        data = {
            "access_token": access_token,
            "expires_in": 7200
        }
        print(data)
        return jsonify(data)
    
    
    @app.route('/getUserInfo', methods=['GET'])
    def get_user_info():
        response = {
            "data": USER_INFO
        }
        return jsonify(response)
    
    
    if __name__ == '__main__':
        import os
    
        os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
        app.run(debug=True)
    
    

    4. 前端代码

    html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
        <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js">script>
        <link rel="stylesheet" href="bootstrap-3.4.1-dist/css/bootstrap.min.css">
        <script src="bootstrap-3.4.1-dist/js/bootstrap.min.js">script>
    head>
    <body>
        <div class="container-fluid">
            <div class="row">
                <div class="col-md-6 col-md-offset-3">
                    <form action="http://106.15.59.77:8880/orgsso/sso?returnUrl=http://106.15.59.77:8880/app/my">
                        <h1 class="text-center">这是Linkda的主站h1>
                        <p>
                           <label for="username">username:label>
                            <input type="text" class="form-control" name="username" id="username">
                        p>
                        <p>
                            <label for="password">password:label>
                            <input type="password" class="form-control" name="password" id="password">
                        p>
                        <p>
                            <input type="submit" value="登录" class="btn btn-primary btn-block">
                        p>
                    form>
                div>
            div>
        div>
    body>
    html>
    

    从最上面的思路流程图中我们可以看出来, 前端最主要的是点击提交后我们跳转的地址是http://106.15.59.77:8880/orgsso/sso?returnUrl=http://106.15.59.77:8880/app/my, 而这个地址会由明道云转发到本地的/login, 再进行后续操作

    5. 单点登录效果

    1. 前端登录界面点击登录

    2. 跳转到后台, 且获取github授权码

    3. 携带code发送到明道云之后, 明道云会发两个请求 /access_token /getUserInfo 获取到用户信息就是单点登录成功

    • 这是后台接收日志

    • 会根据ReturnUrl跳转到明道云界面, 此时单点登录完成

    补充:

    1. 服务器如何访问本地测试地址

    相信看到这里, 会有很多人问: 你后台明明是测试环境, 为什么地址是这玩意儿

    "oauth2Url": "https://ae50-180-164-83-69.ngrok-free.app"
    

    这其实就涉及到一个内网穿透的问题, 为了方便测试, 没问在本地搭的服务也就是127.0.0.1:5000在明道云私有部署的服务器之间肯定是无法访问的, 那么我们就需要去借助一个工具Ngrok将本地地址暴露到公网上, 让服务器能访问到, 这个工具的功能就类似于代理

    使用起来也比较简单, 直接点击ngrok.exe文件, 在终端输入命令

    ngork http 5000
    # 5000可以换成本地的其他端口
    

    此时Forwarding后面就是暴露到公网的地址

    我们可以在明道云的服务器上测试, 如果又返回, 说明暴露成功

    curl -X POST https://ae50-180-164-83-69.ngrok-free.app/access_token
    

    注意: 此时的网址, 当出现302跳转的时候还是会报错, 这需要我们登录ngrok账号, 拿到Authtoken且执行以下命令才可以完成302redirect

    ngrok config add-authtoken 2WvKgyYxeIpT3wyToJOwNEwXbkF_47CPhYhHcTKnyNv5qw81D
    

    2.不使用第三方Github实现oauth2

    oauth2只是一个协议, 我们可以跟着官网的规范来, 在自己的系统中跟着流程搭建自己系统的oauth2服务, 自己搭建服务有两个好处

    • 第三方Github链接不稳定, 反应迟钝用户体验感差
    • 使用Github第三方会出现授权界面(Authorize), 这样会对有自己品牌的系统产生影响(你懂的)

    后面我会继续跟新关于我们系统集成oauth2授权的相关思路

  • 相关阅读:
    mybatisPlus批量插入性能优化
    WIFI功耗计算器
    c++入门必学算法 并查集
    mermaid - markdown的mermaid语法解析渲染
    网络安全(黑客)自学
    这波操作看麻了!十亿行数据,从71s到1.7s的优化之路。
    软考系统架构师知识点集锦四:信息安全技术基础知识
    数据结构线性表之顺序表
    论如何直接用EF Core实现创建更新时间、用户审计,自动化乐观并发、软删除和树形查询(中)
    java实现对指定的敏感词汇进行过滤
  • 原文地址:https://www.cnblogs.com/huxiaofeng1029/p/17775255.html