添加手动生成token

This commit is contained in:
zjf committed 2024-12-06 17:39:41 +08:00
1 parent aff77150d6
commit 0c3f96a1a1
5 files changed
+324 -1

No files matched your search

@@ -21,6 +21,7 @@ import cn.hutool.core.date.TemporalAccessorUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.admin.api.dto.UserTokenDTO;
import com.bsd.pjcloud.admin.api.entity.SysOauthClientDetails;
import com.bsd.pjcloud.admin.api.entity.SysTenant;
import com.bsd.pjcloud.admin.api.feign.RemoteClientDetailsService;
@@ -47,19 +48,31 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.event.LogoutSuccessEvent;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.core.*;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.context.AuthorizationServerContextHolder;
import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import org.springframework.security.oauth2.server.authorization.token.DefaultOAuth2TokenContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.security.Principal;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -88,6 +101,76 @@ public class PjcloudTokenEndpoint {
private final CacheManager cacheManager;
private final OAuth2TokenGenerator<? extends OAuth2Token> tokenGenerator;
@Inner
@SneakyThrows
@PostMapping("/generate-token")
public R generateToken(@RequestBody UserTokenDTO userTokenDTO) {
// 构建授权信息
RegisteredClient registeredClient = RegisteredClient.withId(SecurityConstants.FROM).clientId(SecurityConstants.FROM)
.authorizationGrantType(AuthorizationGrantType.PASSWORD)
.tokenSettings(TokenSettings.builder()
.accessTokenTimeToLive(Duration.ofHours(24)) // token 有效期 24 小时
.refreshTokenTimeToLive(Duration.ofDays(7)) // refresh token 有效期 7 天
.accessTokenFormat(OAuth2TokenFormat.REFERENCE)
.build())
.build();
// 构建用户信息 , 这里只拼接了 UserTokenDTO 中的 username 和 authorities ,其他字段写死,可以自行场地;
PjcloudUser pigUser = new PjcloudUser(1L, userTokenDTO.getUsername(),1L,null,"","","", "", 1L
, "", true, true,"1", true,false, userTokenDTO.getAuthorities()
.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()));
Authentication usernamePasswordAuthentication = new UsernamePasswordAuthenticationToken(pigUser, StrUtil.EMPTY);
DefaultOAuth2TokenContext.Builder tokenContextBuilder = DefaultOAuth2TokenContext.builder()
.registeredClient(registeredClient)
.principal(usernamePasswordAuthentication)
.authorizationServerContext(AuthorizationServerContextHolder.getContext());
OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization
.withRegisteredClient(registeredClient)
.principalName(usernamePasswordAuthentication.getName());
// ----- Access token -----
OAuth2TokenContext tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.ACCESS_TOKEN)
.authorizationGrantType(AuthorizationGrantType.PASSWORD)
.authorizationGrant(new OAuth2ClientAuthenticationToken(registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, null))
.build();
OAuth2Token generatedAccessToken = this.tokenGenerator.generate(tokenContext);
OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER,
generatedAccessToken.getTokenValue(), generatedAccessToken.getIssuedAt(),
generatedAccessToken.getExpiresAt(), tokenContext.getAuthorizedScopes());
if (generatedAccessToken instanceof ClaimAccessor) {
authorizationBuilder.id(accessToken.getTokenValue())
.token(accessToken,
(metadata) -> metadata.put(OAuth2Authorization.Token.CLAIMS_METADATA_NAME,
((ClaimAccessor) generatedAccessToken).getClaims()))
.attribute(Principal.class.getName(), usernamePasswordAuthentication);
} else {
authorizationBuilder.id(accessToken.getTokenValue()).accessToken(accessToken);
}
// ----- Refresh token -----
OAuth2RefreshToken refreshToken;
tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.REFRESH_TOKEN).build();
OAuth2Token generatedRefreshToken = this.tokenGenerator.generate(tokenContext);
refreshToken = (OAuth2RefreshToken) generatedRefreshToken;
authorizationBuilder.refreshToken(refreshToken);
OAuth2Authorization authorization = authorizationBuilder
.authorizationGrantType(AuthorizationGrantType.PASSWORD)
.build();
this.authorizationService.save(authorization);
return R.ok(new OAuth2AccessTokenAuthenticationToken(registeredClient, usernamePasswordAuthentication, accessToken,
refreshToken, authorization.getAccessToken().getClaims()));
}
/**
* 认证页面
* @param modelAndView