认证
每个服务之间RPC调用是否需要认证,如果需要,肯定不能每次调用都查数据库判断账号密码验证因此
- 这里建议一个微服务专门作为认证服务,给所有访问认证服务的微服务发token,然后之后其他服务之间请求都带着token
- 然后token可以直接用jwt技术,自身包含一些如用户名等非敏感信息
这样我们只需要一个认证微服务,其余的每个服务都作为资源微服务,无论是前端请求后端,还是后端多个微服务间调用,都先请求认证微服务,获取jwt格式的token,之后每次请求都带着token即可
实现
我们直接使用 spring-security-oauth2 去实现token认证和 jwt 解析
需要先在认证微服务中配置好认证配置(OAuth2Config ),拦截配置(SecurityConfiguration)等
然后之后的所有其他微服务只需要配置好资源配置(ResourceServerConfiguration)即可
因此认证微服务需要两个配置,一个是配置框架的,一个是配置拦截规则的,其余的微服务只需要配置一个拦截规则即可
jwt附带用户信息
JWTokenEnhancer 中可以
MyUser myUser = (MyUser) oAuth2Authentication.getPrincipal();
Map<String, Object> info = new HashMap<>();
info.put("xxx", JSONObject.toJSONString(myUser));
((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(info);
这样jwt传输中就附带用户信息了
获取用户信息
这里有两种方式,在认证微服务中,可以
·SecurityContextHolder.getContext().getAuthentication().getPrincipal()·
获取登录用户信息
或者解析token,解析其中jwt中自己配置的附带用户信息
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
String token = request.getHeader("Authorization");
token = token.replace("bearer ", "");
Claims claims = Jwts.parser()
.setSigningKey(JWT_KEY.getBytes(StandardCharsets.UTF_8))
.parseClaimsJws(token)
.getBody();
MyUser myUser = claims.get("xxx");
认证系统就做完了
然后我们需要鉴权
鉴权
每个角色有不同的菜单和按钮读取权限,每个用户可以配置不同角色
因此我们需要用户表,角色表,菜单表,角色关联菜单表
其中菜单表存储一级目录,每个页面的URL,和按钮,每条记录都有一个key
我们可以给角色配置拥有哪些权限key,然后全部放到一个Map里返给前端,前端根据这个map,动态渲染路由和控制哪些按钮可以点击
然后前端还需要做用户管理,其中用户管理中可以配置角色,
菜单管理,
角色管理的页面,其中角色管理页面中可以配置菜单,
后端的每个接口也需要做权限认证,使用如下注解@PreAuthorize(“hasAnyRole(‘ROLE_ADMIN’)”)