langgenius/dify(v1.0.1) 实现自定义登录接口与企业内部已有SSO系统集成

SSO项目参考:一款基于.NET Core的认证授权解决方案-葫芦藤1.0开源啦

本文仅提供后端接口实现,不包含前端实现

流程分析

1、用户访问dify,前端服务判断用户身份信息(是否存在dify token,dify token是否过期)。

2、用户身份无效,将页面导航到SSO系统登录页面,用户登录后,重定向到dify前端页面,该页面请求SSO系统获取用户信息接口,拿到SSO用户信息。

3、调用dify后端提供的定制登录接口,获取dify token。(该接口内部自动创建用户和租户绑定关系,最终返回dify token)

最终实现效果

SSO单点登录(授权码登录)
SSO单点登录
拿到access_token后获取SSO用户信息
在这里插入图片描述
调用自定义dify登录接口获取dify token
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

自定义登录接口的实现

这里邮箱我们使用163邮箱,格式 手机号@163.com
密码使用用户id,如果用sso登录用不上,dify默认登录页面可用

dify/api/services/account_service.py

创建用户:get_create_account
创建租户成员:create_normal_tenant_member

class AccountService:
    @staticmethod
    def get_create_account(
        id:str,
        email: str,
        name: str,
        interface_language: str,
        password: Optional[str] = None,
        interface_theme: str = "light"
    ) -> Account:
        """get create account"""
        account = db.session.query(Account).filter_by(id=id).first()
        if not account:
            account = Account()
            account.email = email
            account.name = name

            if password:
                # generate password salt
                salt = secrets.token_bytes(16)
                base64_salt = base64.b64encode(salt).decode()

                # encrypt password with salt
                password_hashed = hash_password(password, salt)
                base64_password_hashed = base64.b64encode(password_hashed).decode()

                account.password = base64_password_hashed
                account.password_salt = base64_salt

            account.interface_language = interface_language
            account.interface_theme = interface_theme

            # Set timezone based on language
            account.timezone = language_timezone_mapping.get(interface_language, "UTC")
            account.id = id
            db.session.add(account)
            db.session.commit()
            return account
        return account        

                
class TenantService:
    @staticmethod
    def create_normal_tenant_member(tenant_id: str, account_id: str) -> TenantAccountJoin:
        """Create normal tenant member"""
        role="normal"
        ta = db.session.query(TenantAccountJoin).filter_by(tenant_id=tenant_id, account_id=account_id).first()
        if not ta:
            ta = TenantAccountJoin(tenant_id=tenant_id, account_id=account_id, role=role)
            db.session.add(ta)
            db.session.commit()
        return ta

通过Fiddler查看 /console/api/workspaces的请求响应包,得到默认租户id
在这里插入图片描述
dify/api/controllers/console/auth/login.py

class SsoUserLoginApi(Resource):
    @setup_required
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument("user_id", type=str, required=True, location="json")
        parser.add_argument("mobile", type=str, required=True, location="json")
        parser.add_argument("language", type=str, required=False, location="json")
        args = parser.parse_args()

        if args["language"] is None:
            language = "zh-Hans"
        
        user_id = args["user_id"]
        mobile = args["mobile"]

        tenant_id="0ac2808e-b7eb-4a74-88f2-26817af9717a"
        account = AccountService.get_create_account(user_id, mobile+"@163.com", mobile,language, user_id)

        TenantService.create_normal_tenant_member(tenant_id, account.id)
       
        token_pair = AccountService.login(account, ip_address=extract_remote_ip(request))
        return {"result": "success", "data": token_pair.model_dump()}

api.add_resource(SsoUserLoginApi, "/sso-login")

上传代码文件打包发版

sudo -s
cd /usr/local/dify/api/services/
rm account_service.py
rz

cd /usr/local/dify/api/controllers/console/auth/
rm login.py
rz

cd /usr/local/dify/
docker build -t langgenius/dify-api:1.0.1-xxx ./api

cd /usr/local/dify/docker/
docker compose down
rm docker-compose.yaml
rz
docker compose up -d

http://xxx/console/api/sso-login
Content-Type: application/json
{
 "user_id":"628xxxxx-xxxx-xxxx-xxxx-xxxx10e2b0",
 "mobile":"xxxx"
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值