Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

wuyuw/uam

Repository files navigation

UAM

统一访问管理中心--UAM (Unify Access Management Center)

UAM是基于RBCA模型的统一用户权限管理中心,支持任意需要进行访问控制的系统来接入,支持Rest API及RPC接入。

本项目包含多个服务,包括"UAM-后台管理-后端"、"UAM-API服务"、"UAM-RPC服务"、"UAM-Job任务调度服务", UAM-后台管理-前端项目在这里

技术栈:go-zerogormMysqlRedisKafkaetcd

系统架构

UAM架构

架构说明

系统提供了一个后台管理平台,UAM管理员和各应用管理员可登录后台对各种资源实体进行CRUD操作。

应用接入后会获得app_idapp_secret,按照接入规范即可访问Rest API服务获取权限相关资源,从而实现访问控制。

UAM-AdminRest API均通过调用RPC Service实现对数据层的操作,通过etcd实现服务注册、发现。

对于一些异步操作,通过基于Kafka实现的异步任务队列在Task Worker中异步执行,另外定时任务类需求可通过Cron Job来配置执行。

目前UAM-Admin提供了一套简单的登录注册模块来实现用户添加,后续可同步企业内部用户表替换现有用户表,可接入OAuth认证方式替换账号密码登录。

当前登录用户是通过JWT实现认证,通过redis缓存实现JWT Token续期,避免Token过期造成用户体验问题。

应用接入流程

假设应用App01需要接入UAM系统,App01管理员需要向UAM系统管理员提交接入申请,

申请通过后UAM系统管理员在UAM后台添加客户端接入记录,并将系统生成的app_idapp_secret发给App01管理员, 并授予App01管理员在UAM后台操作App01资源的权限。

后续App01管理员也可登录UAM后台对App01系统下的资源实体进行CURD操作和用户访问权限管理,

App01开发人员通过app_idapp_secret即可访问UAM开放的Rest API服务获取App01下的资源数据和用户权限数据, 以实现访问控制管理。

资源实体关系

UAM资源实体

1 开发环境搭建

1.1 环境依赖

自行搭建以下组件

  • Mysql

  • Redis

  • etcd

  • Kafka

1.2 数据库准备

  1. 创建uam数据库

  2. 创建所需表:deploy/sql/*.sql

1.3 启动job服务

# 更新services/job/etc/uam-job.yaml配置文件
cd services/job
go run job.go

1.4 启动rpc服务

# 更新services/rpc/etc/uamrpc.yaml配置文件
cd services/rpc
go run uamrpc.go

1.4 启动Rest API服务

# 更新services/api/etc/uam-api.yaml配置文件
cd services/api
go run uam.go

1.5 启动Admin API服务

# 更新services/admin/etc/uam-admin-api.yaml配置文件
cd services/admin
go run uam-admin.go

2 定制开发

admin后端

新增接口

  1. 进入admin目录

    cd services/admin
  2. 创建新接口依赖的类型api文件

    mkdir desc/role
    vim desc/role/role.api
  3. 定义接口依赖的类型

    syntax = "v1"
    info(
     title: "角色管理"
     desc: "角色管理"
     author: "will515"
     email: "wuyuw515@gmail.com"
     version: 1.0
    )
    // 获取所有角色
    type (
     Role {
     Id int64 `json:"id"`
     ClientId int64 `json:"client_id"`
     Name string `json:"name"`
     Desc string `json:"desc"`
     Editable int64 `json:"editable"`
     CreateTime string `json:"create_time"`
     UpdateTime string `json:"update_time"`
     Permissions []string `json:"permissions"`
     }
     RoleListReq {
     ClientId int64 `form:"client_id"`
     Editable string `form:"editable,optional"`
     }
     RoleListResp {
     List []Role `json:"list"`
     }
    )
  4. 在desc/admin.api文件中导入刚创建的类型文件,并定义接口

    import (
     # "core/core.api"
     # "user/user.api"
     # "client/client.api"
     # "permission/permission.api"
     # 导入类型文件
     "role/role.api"
     # "group/group.api"
    )
    # 定义接口
    @server(
     prefix: "/uam/admin/v1"
     group: role
     middleware: JwtAuth, AccessControl
    )
    service uam-admin-api {
     @doc "获取角色列表"
     @handler RoleList
     get /roles (RoleListReq) returns (RoleListResp)
    }
  5. 使用命令行工具goctl生成代码模板

    # 在uam/services/admin目录下执行
    goctl api go -api desc/admin.api --dir .
  6. 修改生成的handler和logic目录下对应的包

定义数据表模型

  1. 创建表对应的包

    mkdir model/user
  2. 分别创建model/user/gorm.go和model/user/model.go两个文件,定义orm结构体和封装数据库操作的model

    gorm.go

    package user
    import "time"
    const TableUser = "user"
    type User struct {
    	Id int64 `gorm:"column:id;primaryKey;autoIncrement"`
    	Uid int64 `gorm:"column:uid"` // uid
    	Nickname string `gorm:"column:nickname"` // 花名
    	Email string `gorm:"column:email"` // 邮箱
    	Phone string `gorm:"column:phone"` // 手机
    	CreateTime time.Time `gorm:"column:create_time"`
    	UpdateTime time.Time `gorm:"column:update_time"`
    }
    func (User) TableName() string {
    	return TableUser
    }

    model.go

    package user
    import (
    	"context"
    	"fmt"
    	"uam/services/model"
    	"gorm.io/gorm"
    )
    type UserModel struct {
    	table string
    	db *gorm.DB
    }
    func NewUserModel(db *gorm.DB) *UserModel {
    	return &UserModel{
    		db: db,
    		table: TableUser,
    	}
    }
    // FindOneByUid 根据uid查询用户信息
    func (m *UserModel) FindOneByUid(ctx context.Context, uid int64) (*User, error) {
    	var (
    		err error
    		user User
    	)
    	db := m.db.Table(m.table)
    	err = db.Where("`uid` = ?", uid).First(&user).Error
    	switch err {
    	case nil:
    		return &user, nil
    	case gorm.ErrRecordNotFound:
    		return nil, model.ErrNotFound
    	default:
    		return nil, err
    	}
    }

RPC接口开发

  1. 更新proto文件,定义类型和接口

    services/rpc/uamprc.proto

    // 获取用户信息
    message GetUserInfoReq {
     int64 uid = 1;
    }
    message GetUserInfoResp {
     int64 uid = 1;
     string nickname = 2;
     string email = 3;
     string phone = 4;
    }
    // services
    service Uam {
     // 定义接口
     rpc getUserInfo(GetUserInfoReq) returns(GetUserInfoResp);
    }
  2. 生成rpc服务代码

    goctl rpc protoc uamrpc.proto --go_out=./pb --go-grpc_out=./pb --zrpc_out=.
  3. 添加RPC接口业务逻辑

3 基于 Github Actions 的 CI 执行自动构建镜像

  1. Fork 代码仓库

  2. 在仓库导航栏的Settings -> Secrets and variables -> Actions -> New repository secret 添加 Docker Hub 个人账户的账户名和密码

    账户变量名: DOCKERHUB_TOKEN

    密码变量名: DOCKERHUB_USERNAME

  3. 拉取代码

    $ git clone git@github.com:${usename}/uam.git
  4. 打 tag,CI会根据tag的前缀构建对应服务的docker镜像并上传到Docker Hub

    $ git tag admin-0.0.1
    $ git tag rpc-0.0.1
    $ git tag job-0.0.1
    $ git tag api-0.0.1
    $ git push origin admin-0.0.1
  5. 点击仓库导航栏的Actions选项卡查看 Workflow 执行情况

  6. 在 Docker Hub 仓库中确认镜像是否上传成功

About

UAM--统一访问管理中心

Resources

License

Stars

Watchers

Forks

Packages

No packages published

AltStyle によって変換されたページ (->オリジナル) /