登录用户支持多表存储
登录用户支持多表存储
新增 租户客户表
CREATE TABLE `toc_custom` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nickname` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
`username` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
`password` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='客户表';
INSERT INTO `toc_custom`(`id`, `nickname`, `username`, `password`) VALUES (1, 'test', 'test', '123456');
新增 TocCustom 实体
@Data
public class TocCustom implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String nickname;
private String username;
private String password;
}
新增 TocCustomMapper 查询工具
@Mapper
public interface TocCustomMapper extends BaseMapper<TocCustom> {
}
新增 custom 查询接口
@Inner
@GetMapping("/custom/{username}")
public R customInfo(@PathVariable String username) {
TocCustom custom = customMapper.selectOne(Wrappers.<TocCustom>lambdaQuery()
.eq(TocCustom::getUsername, username));
return R.ok(custom);
}
增加调用 custom 接口
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.UPMS_SERVICE)
public interface RemoteUserService {
@GetMapping("/user/custom/{username}")
R<TocCustom> custom(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM) String from);
}
修改认证中心代码
增加 custom 客户端
INSERT INTO `sys_oauth_client_details` (`id`,`client_id`,`resource_ids`,`client_secret`,`scope`,`authorized_grant_types`,`web_server_redirect_uri`,`authorities`,`access_token_validity`,`refresh_token_validity`,`additional_information`,`autoapprove`) VALUES (20000,'custom',NULL,'custom','server','password,refresh_token',NULL,NULL,10000,11111111,'','true');
修改整个框架最核心的代码 custom 客户端的专用 UserDetailsService
@Slf4j
@RequiredArgsConstructor
public class JmakeTenantUserDetailsServiceImpl implements JmakeUserDetailsService {
private final RemoteTenantUserService remoteTenantUserService;
private final CacheManager cacheManager;
/**
* 用户名密码登录
* @param username 用户名
* @return
*/
@Override
@SneakyThrows
public UserDetails loadUserByUsername(String username) {
Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
if (cache != null && cache.get(username) != null) {
return (JmakeUser) cache.get(username).get();
}
R<TenantUser> result = remoteTenantUserService.tenantUser(username, SecurityConstants.FROM_IN);
// 根据 result 构建security 框架需要的 用户对象
TenantUser custom = result.getData();
if (custom == null) {
throw new UsernameNotFoundException("用户不存在");
}
JmakeUser jmakeUser = new JmakeUser(custom.getId(), null, custom.getUsername(), "{noop}" + custom.getPassword(),
null, true, true, true, true, AuthorityUtils.NO_AUTHORITIES);
if (cache != null) {
cache.put(username, jmakeUser);
}
// 构造security用户
return jmakeUser;
}
/**
* 是否支持此客户端校验
* @param clientId 目标客户端
* @param grantType
* @return true/false
*/
@Override
public boolean support(String clientId, String grantType) {
return "custom".equals(clientId);
}
@Override
public int getOrder() {
return Integer.MIN_VALUE + 1;
}
}
配置SPI 加载 CustomUserDetailsService
调用测试
注意需要在网关关闭验证码
# 不校验验证码终端
gateway:
ignore-clients:
- test
- XXX
curl --location --request POST 'http://127.0.0.1:3000/oauth2/token?grant_type=password' \
--header 'Authorization: Basic Y3VzdG9tOmN1c3RvbQ==' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'username=test' \
--data-urlencode 'password=123456' \
--data-urlencode 'scope=server'