最近工作需要研究了下Casdoor:
Casdoor is a UI-first Identity Access Management (IAM) / Single-Sign-On (SSO) platform based on OAuth 2.0, OIDC, SAML and CAS.
简介 Casdoor 是一个开源的单点登录系统,单点登录系统的好处就是集中管理用户,使的我们开发的应用只需要关心业务逻辑而不用每个应用都是去实现一套用户系统。
Casdoor 使用了 OAuth2 的方式来完成单点认证,大概逻辑如下图:
总结一下就是:
第一步 获取code
第二步 用code获取access_token
第三步 用access_token获取所需要的资源
安装 服务安装文档
文档说的很明白,我这里是下载源码使用的,因为我用的PostgreSQL,所以需要改一下app.conf
和adapter.go
。
然后后端启动:go run main.go
后端启动:
1 2 3 cd web yarn install yarn start
非常简单
界面配置 这里我是用最小的改动来完成对接demo的,首先需要添加一个组织 ,组织就是一堆资源,应用的的集合:
后面的用户,角色,权限,模型,提供商 都可以先不管,需要了解的可以看文档
然后需要添加一个新的应用 ,主要就是下图这些
客户端ID和客户端密钥,都是后面对接时候需要的
还有一个就是证书 ,这个不需要改,只需要点编辑进入将公钥拿到
上面就是在界面上需要完成的事情和完成一个对接demo所需要的数据了
web 对接 下面是和 Casdoor 对接的 web 接口代码,主要有两部分,第一部分是获取 code,第二部分是通过 code 获取 access_token,而这个 access_token 已经包含了用户信息,用对应的公钥进行解密,即可得到一个用户的 json 数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import loggingfrom urllib.parse import urljoinfrom casdoor import CasdoorSDK@route(r'/casdoor/sso-login' ) class CASDoorSSOLoginHandler (BaseHandler ): def save_user (self, user_data ): user = User.make_user(uid=user_data['id' ], ext_uname=user_data['name' ], username=user_data['name' ], _from ='casdoor' ) return user def get (self, *args, **kwargs ): code = self.get_argument('code' , None ) target_uri = self.get_argument('target_uri' ) subpath = config.get_config("webif.redirect_subpath" , '' ) trident_base = urljoin(self.origin_host, subpath.lstrip('/' )) endpoint = config.get_config('casdoor_auth.endpoint' ) client_id = config.get_config('casdoor_auth.client_id' ) client_secret = config.get_config('casdoor_auth.secret' ) org_name = config.get_config('casdoor_auth.org_name' ) certificate = config.get_config('casdoor_auth.cert' ) sdk = CasdoorSDK( endpoint, client_id, client_secret, certificate, org_name, ) if code: access_token = sdk.get_oauth_token(code) user_data = sdk.parse_jwt_token(access_token) user = self.save_user(user_data) self.session['proxy_user_id' ] = str (user.id ) redirect_url = urljoin(trident_base, target_uri) else : origin_url = '{}/api/v1/casdoor/sso-login?target_uri={}' .format (trident_base, target_uri) redirect_url = sdk.get_auth_link(origin_url, state='casdoor' ) logging.info('redirect to %s' , redirect_url) return self.redirect(redirect_url)
配置也比较简单:
这里需要特别注意的是,endpoint 配的是 Casdoor 访问的首页地址,也就是这里是前端地址,而不是后端地址。前端地址是:http://localhost:7001/
,后端地址是:http://localhost:8000/
,这里很有迷惑性,让我折腾了半天。