package cn.mb.cloud.auth.service;
|
|
import cn.mb.cloud.auth.config.SecurityEnum;
|
import cn.mb.cloud.auth.entity.User;
|
import cn.mb.cloud.auth.util.JWTTokenUtil;
|
import cn.mb.cloud.auth.util.RedisUtil;
|
import cn.mb.cloud.auth.util.TokenException;
|
import cn.mb.cloud.auth.util.httpClinet.HttpClientUtil;
|
import cn.mb.cloud.auth.util.httpClinet.HttpResult;
|
import cn.mb.cloud.auth.warpper.*;
|
import com.alibaba.fastjson.JSON;
|
import org.apache.commons.lang3.ObjectUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.security.core.authority.AuthorityUtils;
|
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.stereotype.Service;
|
|
import java.util.Base64;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
@Service
|
public class UserDetailsServiceImpl implements IUserDetailsService {
|
|
@Autowired
|
private PasswordEncoder passwordEncoder;
|
|
@Autowired
|
private HttpClientUtil httpClientUtil;
|
|
@Autowired
|
private RedisUtil redisUtil;
|
|
private final String password = "LEM5yk92jfi!0mjDzRXF";
|
|
@Value("${token.uri}")
|
private String uri;
|
|
|
|
|
@Override
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
String pass = passwordEncoder.encode(password);
|
User user = new User(username, pass, AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
|
return user;
|
}
|
|
|
/**
|
* 获取身份凭证
|
* @param request
|
* @return
|
* @throws Exception
|
*/
|
@Override
|
public TokenResponse getToken(GetTokenRequest request) throws Exception {
|
TokenResponse tokenResponse = new TokenResponse();
|
|
Map<String, Object> params = new HashMap<>();
|
params.put("grant_type", SecurityEnum.password);
|
params.put("username", request.getUsername());
|
params.put("password", password);
|
params.put("scope", "all");
|
|
Map<String, String> header = new HashMap<>();
|
String string = Base64.getEncoder().encodeToString("1Oy7OUJwHn4T1uSA:JvAdJCdqDCzKf1zZ".getBytes("UTF-8"));
|
header.put("Authorization", "Basic " + string);
|
HttpResult httpResult = httpClientUtil.pushHttpRequset("POST", uri + "/oauth/token", params, header, "form");
|
if(httpResult.getCode() == 200){
|
OauthToken oauthToken = JSON.parseObject(httpResult.getData(), OauthToken.class);
|
tokenResponse.setToken(oauthToken.getAccess_token());
|
tokenResponse.setRefresh_token(oauthToken.getRefresh_token());
|
tokenResponse.setExpiration_time(oauthToken.getExpires_in());
|
|
//缓存进redis
|
saveAuthTokenToRedis(request, oauthToken);
|
}
|
return tokenResponse;
|
}
|
|
|
/**
|
* 存储token信息到redis
|
* @param request
|
* @param oauthToken
|
*/
|
public void saveAuthTokenToRedis(GetTokenRequest request, OauthToken oauthToken) {
|
delRedisToken(request.getUsername());
|
|
String access_token = oauthToken.getAccess_token();
|
String key = access_token.substring(access_token.length() - 32);
|
redisUtil.setStrValue(key, request.getUsername(), SecurityEnum.token_effective_time);
|
redisUtil.setStrValue(request.getUsername(), JSON.toJSONString(request.getObject()));
|
redisUtil.setStrValue(request.getUsername() + ":auth-token", oauthToken.getAccess_token());
|
|
String refresh_token = oauthToken.getRefresh_token();
|
key = refresh_token.substring(refresh_token.length() - 32);
|
redisUtil.setStrValue(key, request.getUsername(), SecurityEnum.refresh_token_effective_time);
|
redisUtil.setStrValue(request.getUsername() + ":refresh-auth-token", oauthToken.getAccess_token());
|
}
|
|
|
/**
|
* 删除redis中的无效数据
|
* @param username
|
*/
|
public void delRedisToken(String username){
|
String token = redisUtil.getValue(username + ":auth-token");
|
if(ObjectUtils.isNotEmpty(token)){
|
String key = token.substring(token.length() - 32);
|
redisUtil.remove(key);
|
}
|
|
String refresh_token = redisUtil.getValue(username + ":refresh-auth-token");
|
if(ObjectUtils.isNotEmpty(refresh_token)){
|
String key = refresh_token.substring(refresh_token.length() - 32);
|
redisUtil.remove(key);
|
}
|
}
|
|
|
/**
|
* 刷新token
|
* @param request
|
* @return
|
* @throws Exception
|
*/
|
@Override
|
public TokenResponse refreshToken(RefreshTokenRequest request) throws Exception {
|
String user_name = null;
|
try {
|
ParseToken parseToken = JWTTokenUtil.parseToken(request.getToken());
|
user_name = parseToken.getUser_name();
|
}catch (TokenException e){
|
if(e.getCode() == 10003){//token过期,通过刷新凭证在缓存中获取用户名
|
String refresh_token = request.getRefresh_token();
|
String key = refresh_token.substring(refresh_token.length() - 32);
|
user_name = redisUtil.getValue(key);
|
}else{
|
throw e;
|
}
|
}
|
if(ObjectUtils.isEmpty(user_name)){
|
return null;
|
}
|
|
String obj = redisUtil.getValue(user_name);
|
|
TokenResponse tokenResponse = new TokenResponse();
|
Map<String, Object> params = new HashMap<>();
|
params.put("refresh_token", request.getRefresh_token());
|
params.put("grant_type", SecurityEnum.refresh_token);
|
|
Map<String, String> header = new HashMap<>();
|
String string = Base64.getEncoder().encodeToString("1Oy7OUJwHn4T1uSA:JvAdJCdqDCzKf1zZ".getBytes("UTF-8"));
|
header.put("Authorization", "Basic " + string);
|
HttpResult httpResult = httpClientUtil.pushHttpRequset("POST", uri + "/oauth/token", params, header, "form");
|
if(httpResult.getCode() == 200){
|
OauthToken oauthToken = JSON.parseObject(httpResult.getData(), OauthToken.class);
|
tokenResponse.setToken(oauthToken.getAccess_token());
|
tokenResponse.setRefresh_token(oauthToken.getRefresh_token());
|
tokenResponse.setExpiration_time(oauthToken.getExpires_in());
|
|
//缓存进redis
|
saveAuthTokenToRedis(user_name, obj, oauthToken);
|
}
|
return tokenResponse;
|
}
|
|
/**
|
* 保存缓存
|
* @param user_name
|
* @param obj
|
* @param oauthToken
|
*/
|
public void saveAuthTokenToRedis(String user_name, String obj, OauthToken oauthToken) {
|
delRedisToken(user_name);
|
|
String access_token = oauthToken.getAccess_token();
|
String key = access_token.substring(access_token.length() - 32);
|
redisUtil.setStrValue(key, user_name, SecurityEnum.token_effective_time);
|
redisUtil.setStrValue(user_name, obj);
|
redisUtil.setStrValue(user_name + ":auth-token", oauthToken.getAccess_token());
|
|
String refresh_token = oauthToken.getRefresh_token();
|
key = refresh_token.substring(refresh_token.length() - 32);
|
redisUtil.setStrValue(key, user_name, SecurityEnum.refresh_token_effective_time);
|
redisUtil.setStrValue(user_name + ":refresh-auth-token", oauthToken.getAccess_token());
|
}
|
}
|