Auth 认证
git地址:
http://10.16.202.103:8089/component/component-ser/gosci-tech-auth-archetype
使用archetype骨架生成时,替换自己的gav:
mvn archetype:generate -DgroupId=com.gosci.tech -DartifactId=ocean-auth-ser -Dversion=0.0.1-SNAPSHOT -Dpackage=com.gosci.tech.ocean.auth -DarchetypeGroupId=com.gosci.tech -DarchetypeArtifactId=gosci-tech-auth-archetype -DarchetypeVersion=0.0.1-SNAPSHOT -DinteractiveMode=false
用户体系设计
底层使用和 OAuth2
和SpringSecurity
完成用户的认证,用户的登录信息存储在 oauth2 的principal
中。
基于RBAC的用户体系设计,最核心的三要素:用户、角色、权限。
oauth2 使用7张表,oauth_access_token
,oauth_approvals
,oauth_client_details
,oauth_client_token
,oauth_code
,oauth_refresh_token
,ClientDetails
。
用户和权限相关五张基础表:sys_user
、sys_role
、sys_permission
、sys_user_role
、sys_role_permission
。
用户登录
用户名密码+验证码方式登录,调用接口:
/captcha/get
:生成二维码/captcha/validate
:二维码验证/login/password
:登录。(其实也可以使用oauth的/oauth/token
接口,效果相同,但是需要在header添加一个basic认证,并且结果没有被Result
包裹,不利于前端统一处理)
在登录过程中,密码需要由前端使用SM2国密算法进行加密后传给后端,加密使用的公钥由后端提前生成并提供给前端。
身份认证
在网关模块介绍过,Gateway调用Auth服务中 LoginApi
的 checkToken()
接口进行认证,成功返回用户信息,失败则返回401。
与framework-core的集成
注意
下面这些内容其实都在framework-core中,但是和鉴权相关,所以放在这一块说明。
用户上下文信息获取
要使用该功能,必须在启动类添加注解:@EnableAuthContext
获取方法:
// 获取用户
AuthUser user = AuthUtil.getCurrentUser();
// 直接获取用户id
Long userId = AuthUtil.getUserId();
用户信息填充
在core包中提供了UserDetailService
接口,三个方法:
deSerializer
:反序列化用户信息字符串,并通过AuthFilter
进行填充getUserRoles
:获取用户角色列表getUserPermissions
:获取用户权限列表
目前骨架中生成的代码是搭配Auth服务使用,可以直接调用Auth服务的能力。如果不使用Auth服务的话,这三个方法可以自己重写,实现自己的逻辑。
Auth服务提供两个feign接口来获取用户的角色和权限:
/**
* @author: 杨轩-国实信息
* @desc: 获取用户角色
*/
@GetMapping(value = "/sys/role/userRoles")
Result<Set<String>> getUserRoles(@RequestParam("userId") Long userId );
/**
* @author: 杨轩-国实信息
* @desc: 获取用户权限
*/
@GetMapping(value = "/sys/permission/userPerms")
Result<Set<String>> getUserPermissions(@RequestParam("userId") Long userId );
注意,由项目骨架生成的项目中引入的auth服务也是auth骨架的,需要自行把这个改称自己的auth服务:
<!-- 实际项目中,把这个替换成项目的auth-api模块依赖 -->
<dependency>
<groupId>com.gosci.tech</groupId>
<artifactId>gosci-tech-auth-archetype-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
Feign调用间的用户透传
Feign调用间的用户信息传递,通过Feign全局拦截器实现,在Feign调用中添加Header:
requestTemplate.header(Constants.USER_HEADER,
Base64Utils.encodeToString(JsonUtils.toString(authUser).getBytes(StandardCharsets.UTF_8)));
接口级别的权限
本来SpringSecurity就能实现接口级别的权限校验,但是现在SpringSecurity放在Auth服务中,每个服务中没有独立的鉴权模块了,所以重写了切面,来实现方法级别的鉴权。
两种鉴权方式,可以在Controller方法上添加注解:
@HasRole("ADMIN")
:检测调用接口的用户是否有该角色@HasPermit("MODIFY")
:检测调用接口的用户是否有该权限
角色和权限的校验由core包中RoleCheckAop
和PermitCheckAop
这两个切面完成。
数据权限
建设中…