mirror of
https://gitee.com/log4j/pig.git
synced 2024-12-22 12:48:58 +08:00
♻️ Refactoring code. 重构 TokenEndpoint 修改 mapping path
This commit is contained in:
parent
baa890379b
commit
72d385bd0f
@ -78,157 +78,162 @@ import java.util.stream.Collectors;
|
||||
@RequestMapping("/token")
|
||||
public class PigTokenEndpoint {
|
||||
|
||||
private final HttpMessageConverter<OAuth2AccessTokenResponse> accessTokenHttpResponseConverter = new OAuth2AccessTokenResponseHttpMessageConverter();
|
||||
private final HttpMessageConverter<OAuth2AccessTokenResponse> accessTokenHttpResponseConverter = new OAuth2AccessTokenResponseHttpMessageConverter();
|
||||
|
||||
private final AuthenticationFailureHandler authenticationFailureHandler = new PigAuthenticationFailureEventHandler();
|
||||
private final AuthenticationFailureHandler authenticationFailureHandler = new PigAuthenticationFailureEventHandler();
|
||||
|
||||
private final OAuth2AuthorizationService authorizationService;
|
||||
private final OAuth2AuthorizationService authorizationService;
|
||||
|
||||
private final RemoteClientDetailsService clientDetailsService;
|
||||
private final RemoteClientDetailsService clientDetailsService;
|
||||
|
||||
private final RedisTemplate<String, Object> redisTemplate;
|
||||
private final RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
private final CacheManager cacheManager;
|
||||
private final CacheManager cacheManager;
|
||||
|
||||
/**
|
||||
* 认证页面
|
||||
* @param modelAndView
|
||||
* @param error 表单登录失败处理回调的错误信息
|
||||
* @return ModelAndView
|
||||
*/
|
||||
@GetMapping("/login")
|
||||
public ModelAndView require(ModelAndView modelAndView, @RequestParam(required = false) String error) {
|
||||
modelAndView.setViewName("ftl/login");
|
||||
modelAndView.addObject("error", error);
|
||||
return modelAndView;
|
||||
}
|
||||
/**
|
||||
* 认证页面
|
||||
*
|
||||
* @param modelAndView
|
||||
* @param error 表单登录失败处理回调的错误信息
|
||||
* @return ModelAndView
|
||||
*/
|
||||
@GetMapping("/login")
|
||||
public ModelAndView require(ModelAndView modelAndView, @RequestParam(required = false) String error) {
|
||||
modelAndView.setViewName("ftl/login");
|
||||
modelAndView.addObject("error", error);
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
@GetMapping("/confirm_access")
|
||||
public ModelAndView confirm(Principal principal, ModelAndView modelAndView,
|
||||
@RequestParam(OAuth2ParameterNames.CLIENT_ID) String clientId,
|
||||
@RequestParam(OAuth2ParameterNames.SCOPE) String scope,
|
||||
@RequestParam(OAuth2ParameterNames.STATE) String state) {
|
||||
SysOauthClientDetails clientDetails = RetOps
|
||||
.of(clientDetailsService.getClientDetailsById(clientId, SecurityConstants.FROM_IN))
|
||||
.getData()
|
||||
.orElseThrow(() -> new OAuthClientException("clientId 不合法"));
|
||||
@GetMapping("/confirm_access")
|
||||
public ModelAndView confirm(Principal principal, ModelAndView modelAndView,
|
||||
@RequestParam(OAuth2ParameterNames.CLIENT_ID) String clientId,
|
||||
@RequestParam(OAuth2ParameterNames.SCOPE) String scope,
|
||||
@RequestParam(OAuth2ParameterNames.STATE) String state) {
|
||||
SysOauthClientDetails clientDetails = RetOps
|
||||
.of(clientDetailsService.getClientDetailsById(clientId, SecurityConstants.FROM_IN))
|
||||
.getData()
|
||||
.orElseThrow(() -> new OAuthClientException("clientId 不合法"));
|
||||
|
||||
Set<String> authorizedScopes = StringUtils.commaDelimitedListToSet(clientDetails.getScope());
|
||||
modelAndView.addObject("clientId", clientId);
|
||||
modelAndView.addObject("state", state);
|
||||
modelAndView.addObject("scopeList", authorizedScopes);
|
||||
modelAndView.addObject("principalName", principal.getName());
|
||||
modelAndView.setViewName("ftl/confirm");
|
||||
return modelAndView;
|
||||
}
|
||||
Set<String> authorizedScopes = StringUtils.commaDelimitedListToSet(clientDetails.getScope());
|
||||
modelAndView.addObject("clientId", clientId);
|
||||
modelAndView.addObject("state", state);
|
||||
modelAndView.addObject("scopeList", authorizedScopes);
|
||||
modelAndView.addObject("principalName", principal.getName());
|
||||
modelAndView.setViewName("ftl/confirm");
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出并删除token
|
||||
* @param authHeader Authorization
|
||||
*/
|
||||
@DeleteMapping("/logout")
|
||||
public R<Boolean> logout(@RequestHeader(value = HttpHeaders.AUTHORIZATION, required = false) String authHeader) {
|
||||
if (StrUtil.isBlank(authHeader)) {
|
||||
return R.ok();
|
||||
}
|
||||
/**
|
||||
* 退出并删除token
|
||||
*
|
||||
* @param authHeader Authorization
|
||||
*/
|
||||
@DeleteMapping("/logout")
|
||||
public R<Boolean> logout(@RequestHeader(value = HttpHeaders.AUTHORIZATION, required = false) String authHeader) {
|
||||
if (StrUtil.isBlank(authHeader)) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
String tokenValue = authHeader.replace(OAuth2AccessToken.TokenType.BEARER.getValue(), StrUtil.EMPTY).trim();
|
||||
return removeToken(tokenValue);
|
||||
}
|
||||
String tokenValue = authHeader.replace(OAuth2AccessToken.TokenType.BEARER.getValue(), StrUtil.EMPTY).trim();
|
||||
return removeToken(tokenValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验token
|
||||
* @param token 令牌
|
||||
*/
|
||||
@SneakyThrows
|
||||
@GetMapping("/check_token")
|
||||
public void checkToken(String token, HttpServletResponse response, HttpServletRequest request) {
|
||||
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
|
||||
/**
|
||||
* 校验token
|
||||
*
|
||||
* @param token 令牌
|
||||
*/
|
||||
@SneakyThrows
|
||||
@GetMapping("/check_token")
|
||||
public void checkToken(String token, HttpServletResponse response, HttpServletRequest request) {
|
||||
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
|
||||
|
||||
if (StrUtil.isBlank(token)) {
|
||||
httpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
|
||||
this.authenticationFailureHandler.onAuthenticationFailure(request, response,
|
||||
new InvalidBearerTokenException(OAuth2ErrorCodesExpand.TOKEN_MISSING));
|
||||
return;
|
||||
}
|
||||
OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
|
||||
if (StrUtil.isBlank(token)) {
|
||||
httpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
|
||||
this.authenticationFailureHandler.onAuthenticationFailure(request, response,
|
||||
new InvalidBearerTokenException(OAuth2ErrorCodesExpand.TOKEN_MISSING));
|
||||
return;
|
||||
}
|
||||
OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
|
||||
|
||||
// 如果令牌不存在 返回401
|
||||
if (authorization == null || authorization.getAccessToken() == null) {
|
||||
this.authenticationFailureHandler.onAuthenticationFailure(request, response,
|
||||
new InvalidBearerTokenException(OAuth2ErrorCodesExpand.INVALID_BEARER_TOKEN));
|
||||
return;
|
||||
}
|
||||
// 如果令牌不存在 返回401
|
||||
if (authorization == null || authorization.getAccessToken() == null) {
|
||||
this.authenticationFailureHandler.onAuthenticationFailure(request, response,
|
||||
new InvalidBearerTokenException(OAuth2ErrorCodesExpand.INVALID_BEARER_TOKEN));
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Object> claims = authorization.getAccessToken().getClaims();
|
||||
OAuth2AccessTokenResponse sendAccessTokenResponse = OAuth2EndpointUtils.sendAccessTokenResponse(authorization,
|
||||
claims);
|
||||
this.accessTokenHttpResponseConverter.write(sendAccessTokenResponse, MediaType.APPLICATION_JSON, httpResponse);
|
||||
}
|
||||
Map<String, Object> claims = authorization.getAccessToken().getClaims();
|
||||
OAuth2AccessTokenResponse sendAccessTokenResponse = OAuth2EndpointUtils.sendAccessTokenResponse(authorization,
|
||||
claims);
|
||||
this.accessTokenHttpResponseConverter.write(sendAccessTokenResponse, MediaType.APPLICATION_JSON, httpResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* 令牌管理调用
|
||||
* @param token token
|
||||
*/
|
||||
@Inner
|
||||
@DeleteMapping("/{token}")
|
||||
public R<Boolean> removeToken(@PathVariable("token") String token) {
|
||||
OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
|
||||
if (authorization == null) {
|
||||
return R.ok();
|
||||
}
|
||||
/**
|
||||
* 令牌管理调用
|
||||
*
|
||||
* @param token token
|
||||
*/
|
||||
@Inner
|
||||
@DeleteMapping("/remove/{token}")
|
||||
public R<Boolean> removeToken(@PathVariable("token") String token) {
|
||||
OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
|
||||
if (authorization == null) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
OAuth2Authorization.Token<OAuth2AccessToken> accessToken = authorization.getAccessToken();
|
||||
if (accessToken == null || StrUtil.isBlank(accessToken.getToken().getTokenValue())) {
|
||||
return R.ok();
|
||||
}
|
||||
// 清空用户信息(立即删除)
|
||||
cacheManager.getCache(CacheConstants.USER_DETAILS).evictIfPresent(authorization.getPrincipalName());
|
||||
// 清空access token
|
||||
authorizationService.remove(authorization);
|
||||
// 处理自定义退出事件,保存相关日志
|
||||
SpringContextHolder.publishEvent(new LogoutSuccessEvent(new PreAuthenticatedAuthenticationToken(
|
||||
authorization.getPrincipalName(), authorization.getRegisteredClientId())));
|
||||
return R.ok();
|
||||
}
|
||||
OAuth2Authorization.Token<OAuth2AccessToken> accessToken = authorization.getAccessToken();
|
||||
if (accessToken == null || StrUtil.isBlank(accessToken.getToken().getTokenValue())) {
|
||||
return R.ok();
|
||||
}
|
||||
// 清空用户信息(立即删除)
|
||||
cacheManager.getCache(CacheConstants.USER_DETAILS).evictIfPresent(authorization.getPrincipalName());
|
||||
// 清空access token
|
||||
authorizationService.remove(authorization);
|
||||
// 处理自定义退出事件,保存相关日志
|
||||
SpringContextHolder.publishEvent(new LogoutSuccessEvent(new PreAuthenticatedAuthenticationToken(
|
||||
authorization.getPrincipalName(), authorization.getRegisteredClientId())));
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询token
|
||||
* @param params 分页参数
|
||||
* @return
|
||||
*/
|
||||
@Inner
|
||||
@PostMapping("/page")
|
||||
public R<Page> tokenList(@RequestBody Map<String, Object> params) {
|
||||
// 根据分页参数获取对应数据
|
||||
String key = String.format("%s::*", CacheConstants.PROJECT_OAUTH_ACCESS);
|
||||
int current = MapUtil.getInt(params, CommonConstants.CURRENT);
|
||||
int size = MapUtil.getInt(params, CommonConstants.SIZE);
|
||||
Set<String> keys = redisTemplate.keys(key);
|
||||
List<String> pages = keys.stream().skip((current - 1) * size).limit(size).collect(Collectors.toList());
|
||||
Page result = new Page(current, size);
|
||||
/**
|
||||
* 查询token
|
||||
*
|
||||
* @param params 分页参数
|
||||
* @return
|
||||
*/
|
||||
@Inner
|
||||
@PostMapping("/page")
|
||||
public R<Page> tokenList(@RequestBody Map<String, Object> params) {
|
||||
// 根据分页参数获取对应数据
|
||||
String key = String.format("%s::*", CacheConstants.PROJECT_OAUTH_ACCESS);
|
||||
int current = MapUtil.getInt(params, CommonConstants.CURRENT);
|
||||
int size = MapUtil.getInt(params, CommonConstants.SIZE);
|
||||
Set<String> keys = redisTemplate.keys(key);
|
||||
List<String> pages = keys.stream().skip((current - 1) * size).limit(size).collect(Collectors.toList());
|
||||
Page result = new Page(current, size);
|
||||
|
||||
List<TokenVo> tokenVoList = redisTemplate.opsForValue().multiGet(pages).stream().map(obj -> {
|
||||
OAuth2Authorization authorization = (OAuth2Authorization) obj;
|
||||
TokenVo tokenVo = new TokenVo();
|
||||
tokenVo.setClientId(authorization.getRegisteredClientId());
|
||||
tokenVo.setId(authorization.getId());
|
||||
tokenVo.setUsername(authorization.getPrincipalName());
|
||||
OAuth2Authorization.Token<OAuth2AccessToken> accessToken = authorization.getAccessToken();
|
||||
tokenVo.setAccessToken(accessToken.getToken().getTokenValue());
|
||||
List<TokenVo> tokenVoList = redisTemplate.opsForValue().multiGet(pages).stream().map(obj -> {
|
||||
OAuth2Authorization authorization = (OAuth2Authorization) obj;
|
||||
TokenVo tokenVo = new TokenVo();
|
||||
tokenVo.setClientId(authorization.getRegisteredClientId());
|
||||
tokenVo.setId(authorization.getId());
|
||||
tokenVo.setUsername(authorization.getPrincipalName());
|
||||
OAuth2Authorization.Token<OAuth2AccessToken> accessToken = authorization.getAccessToken();
|
||||
tokenVo.setAccessToken(accessToken.getToken().getTokenValue());
|
||||
|
||||
String expiresAt = TemporalAccessorUtil.format(accessToken.getToken().getExpiresAt(),
|
||||
DatePattern.NORM_DATETIME_PATTERN);
|
||||
tokenVo.setExpiresAt(expiresAt);
|
||||
String expiresAt = TemporalAccessorUtil.format(accessToken.getToken().getExpiresAt(),
|
||||
DatePattern.NORM_DATETIME_PATTERN);
|
||||
tokenVo.setExpiresAt(expiresAt);
|
||||
|
||||
String issuedAt = TemporalAccessorUtil.format(accessToken.getToken().getIssuedAt(),
|
||||
DatePattern.NORM_DATETIME_PATTERN);
|
||||
tokenVo.setIssuedAt(issuedAt);
|
||||
return tokenVo;
|
||||
}).collect(Collectors.toList());
|
||||
result.setRecords(tokenVoList);
|
||||
result.setTotal(keys.size());
|
||||
return R.ok(result);
|
||||
}
|
||||
String issuedAt = TemporalAccessorUtil.format(accessToken.getToken().getIssuedAt(),
|
||||
DatePattern.NORM_DATETIME_PATTERN);
|
||||
tokenVo.setIssuedAt(issuedAt);
|
||||
return tokenVo;
|
||||
}).collect(Collectors.toList());
|
||||
result.setRecords(tokenVoList);
|
||||
result.setTotal(keys.size());
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ public interface RemoteTokenService {
|
||||
* @param from 内部调用标志
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping("/token/{token}")
|
||||
@DeleteMapping("/token/remove/{token}")
|
||||
R<Boolean> removeTokenById(@PathVariable("token") String token, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
|
||||
/**
|
||||
|
@ -39,7 +39,7 @@ import java.util.Map;
|
||||
*/
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/token")
|
||||
@RequestMapping("/sys-token")
|
||||
@Tag(description = "token", name = "令牌管理模块")
|
||||
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
|
||||
public class SysTokenController {
|
||||
|
Loading…
Reference in New Issue
Block a user