KubeSphere第三方登录流程源码分析

背景

  最近开始接触KubeSphere,借助了两个小需求来实战一下kubesphere的源码浅析。1. 第三方登录后跳转到kubesphere指定页面;2. 打通发布平台用户和kubesphere的用户体系

环境搭建

  1. 因为KubeSphere是k8s的上层应用,所以首先需要安装k8s(基于docker-desktop的一键安装)
  2. 最小化启动KubeSphere(不然启动时同步资源会卡死)
  3. 下载GoLand并设置dlv,注意如下事项
    3.1 go的版本选择最新的(v1.20.1),否则可能会遭遇如下问题 KubeSphere第三方登录流程源码分析_第1张图片
    3.2 下载正确版本的Goland(本人升级Goland变为X86_64了,其实我的是mac arm64的机器)
    KubeSphere第三方登录流程源码分析_第2张图片
    3.3 下载dlv并在GoLand中进行配置
    KubeSphere第三方登录流程源码分析_第3张图片
  4. 拉取KubeSphere源码,切换到v3.3.2分支,启动apiServer(kubesphere->cmd->ks-apiserver->apiServer.go)
    4.1 启动依赖kubesphere.yaml配置文件(放在项目的根目录中)
    authentication:
      authenticateRateLimiterMaxTries: 10
      authenticateRateLimiterDuration: 10m0s
      loginHistoryRetentionPeriod: 168h
      maximumClockSkew: 10s
      multipleLogin: True
      kubectlImage: registry.cn-beijing.aliyuncs.com/kubesphereio/kubectl:v1.18.0
      jwtSecret: "xxxx"
      oauthOptions:
        accessTokenInactivityTimeout: 30m
        accessTokenMaxAge: 1h
        identityProviders:
          - mappingMethod: auto
            name: keycloak
            provider:
              clientID: client1
              clientSecret: secret
              idTokenSkipVerify: true
              issuer: http://localhost:39005/aco/operation
              redirectURL: http://localhost:39005/oauth/redirect/keycloak
              scopes:
                - openid
                - email
                - profile
            type: OIDCIdentityProvider
    network:
      ippoolType: none
    monitoring:
      endpoint: http://prometheus-operated.kubesphere-monitoring-system.svc:9090
    

源码分析

  1. 在分析之前先了解一下整体流程图

  2. 控制跳转的逻辑在kubesphere-console中
    2.1 在router.js中进行oauth/redirect/:name的路由注册 在这里插入图片描述
    2.2 handleOAuthLogin控制跳转逻辑

    const handleOAuthLogin = async ctx => {
    	// 向apiserver发送/oauth/callback/${oauthName}请求获取用户信息,apiserver如何处理见下面
    	user = await oAuthLogin({ ...oauthParams, oauthName: ctx.params.name })
    	if (user.username === 'system:pre-registration') { // 如果是预注册用户,则需要跳转到确认页面进行点击注册
    	    const extraname = safeBase64.safeBtoa(user.extraname)
    	    ctx.cookies.set('defaultUser', extraname)
    	    ctx.cookies.set('defaultEmail', user.email)
    	    return ctx.redirect('/login/confirm')
      }
      // 如果有redirect_url参数则跳转到redirect_url,否则跳转到首页(解决了第一个问题)
       if (redirect_url) {
    	const redirectHost = new URL(redirect_url).host
        if (redirectHost === ctx.headers.host) {
          ctx.redirect(redirect_url)
    	}
      } else {
        ctx.redirect('/')
      }
    }
    
  3. apiserver收到用户信息请求后在pkg/kapis/oauth/handler.go ->oauthCallback方法中处理

    func (h *handler) oauthCallback(req *restful.Request, response *restful.Response) {
    	// 向认证服务器发送请求,根据code获取token
    	// 根据token的sub信息查询k8s中是否有对应的用户,如果没有则新建一个预注册用户
    	authenticated, provider, err := h.oauthAuthenticator.Authenticate(req.Request.Context(), provider, req.Request)
    	// 将用户信息转换为自己的jwt token
    	result, err := h.issueTokenTo(authenticated)
    	// 将token返回给console
    	response.WriteEntity(result)
    }
    
  4. 创建用户在apiserver的pkg/kapis/iam/v1alpha2/handler.go -> CreateUser方法中处理

    func (h *iamHandler) CreateUser(req *restful.Request, resp *restful.Response) {
    	var user iamv1alpha2.User
    	// 读取请求body信息
    	err := req.ReadEntity(&user)
    	// 在WithAuthentication中读取认证信息会放入请求的上下文中
    	operator, ok := request.UserFrom(req.Request.Context())
    	// 区分第三方登录和普通登录: 是否有下面的labels信息
    	if ok && operator.GetName() == iamv1alpha2.PreRegistrationUser { 
    		extra := operator.GetExtra()
    		if user.Labels == nil {
    			user.Labels = make(map[string]string)
    		}
    		user.Labels[iamv1alpha2.IdentifyProviderLabel] = extra[iamv1alpha2.ExtraIdentityProvider][0]
    		user.Labels[iamv1alpha2.OriginUIDLabel] = extra[iamv1alpha2.ExtraUID][0]
    		// default role
    		delete(user.Annotations, iamv1alpha2.GlobalRoleAnnotation)
    	}
    	// 调用k8s接口创建用户
    	created, err := h.im.CreateUser(&user)
    }
    

    4.1 创建用户接口如下(解决第二问题)
    KubeSphere第三方登录流程源码分析_第4张图片

束语

   整个流程已经分析完了,通过简单的两个需求对Kubesphere的第三方登录相关代码进行源码调式,消除了对go的陌生感以及了解kubesphere是如何扩展k8s的。总之收货很多,以后继续加油

你可能感兴趣的:(kubernetes,docker,java)