# 用户中心 user-center在项目中的位置 ![](https://box.kancloud.cn/03a212ca37ca4e242d12a2b482d40fb7_975x638.png) 用户中心作为认证授权分离架构的oauth资源服务器,需要引入 <!-- 资源服务器 --> <dependency> <groupId>com.open.capacity</groupId> <artifactId>security-core</artifactId> <version>${core.version}</version> </dependency> ## 携带access_token访问api >![](https://box.kancloud.cn/60c726e82b88f83ea730c0d2b0263ef9_1433x879.png) > access_token 放在请求头 OAuth2AuthentiactionProcessingFilter,从request中提取access_token,构建PreAuthenticatedAuthenticationToken并验证。 ![](https://box.kancloud.cn/23db16721cfdd972949e7032cf79e1a9_822x585.png) tokenExtractor.extract(request)实际调用的是BearTokenExtractor里的extract方法,从Authorization header   “Bearer  xxxx”中抽取token,或者从request parameters抽取名为“access_token”的参数值。 ![](https://box.kancloud.cn/2c39a98be4dbe6490bff15493c435718_820x215.png)  构建后的authentication参数如下,tokenType="Bearer",principal=token值。再根据**OAuth2AuthenticationManager**验证该authentication的合法性。 ![](https://box.kancloud.cn/cecda7b2bb306de6ac7c04533aa93f84_865x378.png) ## 通过arthas理解验证token流程 ![](https://box.kancloud.cn/be802311c108800f2fe480bb4a35b728_1573x299.png) ## user-center 登录核心图 ![](https://box.kancloud.cn/7eea410bb58d317640e825e7a3e7c20e_588x703.png) ``` public Authentication authenticate(Authentication authentication) throws AuthenticationException { if (authentication == null) { throw new InvalidTokenException("Invalid token (token not found)"); } String token = (String) authentication.getPrincipal(); OAuth2Authentication auth = tokenServices.loadAuthentication(token); if (auth == null) { throw new InvalidTokenException("Invalid token: " + token); } Collection<String> resourceIds = auth.getOAuth2Request().getResourceIds(); if (resourceId != null && resourceIds != null && !resourceIds.isEmpty() && !resourceIds.contains(resourceId)) { throw new OAuth2AccessDeniedException("Invalid token does not contain resource id (" + resourceId + ")"); } checkClientDetails(auth); if (authentication.getDetails() instanceof OAuth2AuthenticationDetails) { OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails(); // Guard against a cached copy of the same details if (!details.equals(auth.getDetails())) { // Preserve the authentication details from the one loaded by token services details.setDecodedDetails(auth.getDetails()); } } auth.setDetails(authentication.getDetails()); auth.setAuthenticated(true); return auth; } ``` ## 登录逻辑处理SysUserController,为auth-server认证中心服务 ``` @GetMapping(value = "/users-anon/login", params = "username") @ApiOperation(value = "根据用户名查询用户") public LoginAppUser findByUsername(String username) { String num = PointUtil.getRandom();//生成日志随机数 log.info("SysUserController|findByUsername|num:{}|input:{}",num , username ); return appUserService.findByUsername(username); } ``` ## RBAC模式 ### 表设计 | 表 | 备注 | | --- | --- | | sys_user| 用户表 | | sys_role | 角色表 | | sys_permission | 权限表 | | sys_menu | 菜单表 | | sys_role_menu | 角色菜单表 | | sys_role_permission | 角色权限表 | ### 实体类 ![](https://box.kancloud.cn/c33b7928b2593c6b1085df6aca2c5aac_1257x447.png) ### 用户实体类关联UML图 ![](https://box.kancloud.cn/5454fa4a1ff370d7c88acb8d33741949_1685x878.png) ``` /** * @author 作者 owen E-mail: 624191343@qq.com * @version 创建时间:2017年11月12日 上午22:57:51 * 用户实体绑定spring security */ @Getter @Setter public class LoginAppUser extends SysUser implements UserDetails { /** * */ private static final long serialVersionUID = -3685249101751401211L; private Set<SysRole> sysRoles; private Set<String> permissions; /*** * 权限重写 */ @JsonIgnore @Override public Collection<? extends GrantedAuthority> getAuthorities() { Collection<GrantedAuthority> collection = new HashSet<>(); if (!CollectionUtils.isEmpty(sysRoles)) { sysRoles.parallelStream().forEach(role -> { if (role.getCode().startsWith("ROLE_")) { collection.add(new SimpleGrantedAuthority(role.getCode())); } else { collection.add(new SimpleGrantedAuthority("ROLE_" + role.getCode())); } }); } if (!CollectionUtils.isEmpty(permissions)) { permissions.parallelStream().forEach(per -> { collection.add(new SimpleGrantedAuthority(per)); }); } return collection; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return getEnabled(); } } ``` ### 验证流程 ![](https://box.kancloud.cn/7eea410bb58d317640e825e7a3e7c20e_588x703.png) ### 授权流程 ![](https://box.kancloud.cn/53e8ffda6d12e4d48acdc6231bdafc4e_1408x773.png) >@PreAuthorize("hasAuthority('user:get/users/{id}')") 处理流程 ![](https://box.kancloud.cn/13cac94c70fd896a70529c980f06d32b_1203x579.png) ![](https://box.kancloud.cn/c0b1c59f82bc9cd4db41c44cbe375a2a_1532x760.png) ![](https://box.kancloud.cn/47bcbda1983dbdb464a22256bc35b632_1422x486.png) ![](https://box.kancloud.cn/5825a80d2cd81909226a8f5ccf4be5c0_1342x539.png) #### 启用授权 ``` @EnableGlobalMethodSecurity(prePostEnabled = true) /** * @author 作者 owen E-mail: 624191343@qq.com * @version 创建时间:2017年11月12日 上午22:57:51 */ @Component @Configuration @EnableResourceServer // 开启spring security 注解 // @EnableGlobalMethodSecurity(prePostEnabled = true) @EnableConfigurationProperties(PermitUrlProperties.class) public class OAuth2ClientConfig extends ResourceServerConfigurerAdapter { } ``` ### 配置接口权限 ![](https://box.kancloud.cn/84948f779bf0fff3da58b082606a9e46_1216x599.png) ![](https://box.kancloud.cn/2a449ba0e7e6a75348baf669607b43c5_1326x592.png) ## swagger ![](https://box.kancloud.cn/02d11c62a1c712b25ccd5a5504f9973c_1912x975.png) ## 项目pom依赖关系 ![](https://box.kancloud.cn/1fc409cb0880f3e9524482e202143972_1761x690.png)