Client /dto update

pull/4/head
shengzhaoli.shengz 2023-10-13 15:21:03 +08:00
parent a686b0b18b
commit 7e56e71335
12 changed files with 941 additions and 260 deletions

View File

@ -2,17 +2,32 @@ package com.monkeyk.sos.domain.oauth;
import com.monkeyk.sos.infrastructure.DateUtils;
import java.io.Serial;
import java.io.Serializable;
import java.time.Instant;
import java.time.LocalDateTime;
/**
* table: oauth2_registered_client
*
* @author Shengzhao Li
* @see org.springframework.security.oauth2.server.authorization.client.RegisteredClient
* @since 1.0.0
*/
public class OauthClientDetails implements Serializable {
@Serial
private static final long serialVersionUID = -6947822646185526939L;
/**
* id
*
* @since 3.0.0
*/
private String id;
/**
*
*/
@ -26,81 +41,151 @@ public class OauthClientDetails implements Serializable {
private String clientId;
/**
* @deprecated OAuth2.1 not used from v3.0.0
* client
*
*
* @since 3.0.0
*/
private String resourceIds;
private String clientName;
/**
* Encrypted
* client
*
* @since 3.0.0
*/
private Instant clientIdIssuedAt = Instant.now();
/**
* Encrypted
*/
private String clientSecret;
/**
* Available values: read,write
*/
private String scope;
/**
* grant types include
* "authorization_code", "password", "assertion", and "refresh_token".
* Default value is "authorization_code,refresh_token".
* secret
* null
* 使
*
* @since 3.0.0
*/
private String authorizedGrantTypes = "authorization_code,refresh_token";
private Instant clientSecretExpiresAt;
/**
*
* : client_secret_basic,client_secret_post
*
* @see org.springframework.security.oauth2.core.ClientAuthenticationMethod
* @since 3.0.0
*/
private String clientAuthenticationMethods;
/**
* OIDC scope ,
* : openid,profile,email
*
* @see org.springframework.security.oauth2.core.oidc.OidcScopes
*/
private String scopes;
/**
* grant_type (OAuth2.1),
* : authorization_code,refresh_token
*
* @see org.springframework.security.oauth2.core.AuthorizationGrantType
*/
private String authorizationGrantTypes;
/**
* OAuth2 uri code,
* The re-direct URI(s) established during registration (optional, comma separated).
*/
private String webServerRedirectUri;
private String redirectUris;
/**
* Authorities that are granted to the client (comma-separated). Distinct from the authorities
* granted to the user on behalf of whom the client is acting.
* <p/>
* For example: ROLE_USER
* OAuth2 退 post uri
*
* client
*
* @since 3.0.0
*/
private String authorities;
private String postLogoutRedirectUris;
/**
* The access token validity period in seconds (optional).
* If unspecified a global default will be applied by the token services.
*
* PKCE(consent)
* {ClientSettings}
*
* @see org.springframework.security.oauth2.server.authorization.settings.ClientSettings
* @since 3.0.0
*/
private Integer accessTokenValidity;
private String clientSettings;
/**
* The refresh token validity period in seconds (optional).
* If unspecified a global default will be applied by the token services.
* token
* tokenrefresh_token
* {TokenSettings}
*
* @see org.springframework.security.oauth2.server.authorization.settings.TokenSettings
* @since 3.0.0
*/
private Integer refreshTokenValidity;
private String tokenSettings;
// optional
private String additionalInformation;
/**
* The client is trusted or not. If it is trust, will skip approve step
* default false.
*/
private boolean trusted = false;
/**
* Value is 'true' or 'false', default 'false'
*/
private String autoApprove;
public OauthClientDetails() {
}
public String autoApprove() {
return autoApprove;
/**
* @since 3.0.0
*/
public String id() {
return id;
}
public OauthClientDetails autoApprove(String autoApprove) {
this.autoApprove = autoApprove;
/**
* @since 3.0.0
*/
public OauthClientDetails id(String id) {
this.id = id;
return this;
}
public boolean trusted() {
return trusted;
/**
* @since 3.0.0
*/
public String tokenSettings() {
return tokenSettings;
}
/**
* @since 3.0.0
*/
public OauthClientDetails tokenSettings(String tokenSettings) {
this.tokenSettings = tokenSettings;
return this;
}
/**
* @since 3.0.0
*/
public String clientSettings() {
return clientSettings;
}
/**
* @since 3.0.0
*/
public OauthClientDetails clientSettings(String clientSettings) {
this.clientSettings = clientSettings;
return this;
}
public LocalDateTime createTime() {
return createTime;
}
@ -118,42 +203,112 @@ public class OauthClientDetails implements Serializable {
return clientId;
}
public String resourceIds() {
return resourceIds;
}
public String clientSecret() {
return clientSecret;
}
public String scope() {
return scope;
/**
* @since 3.0.0
*/
public String clientName() {
return clientName;
}
public String authorizedGrantTypes() {
return authorizedGrantTypes;
/**
* @since 3.0.0
*/
public OauthClientDetails clientName(String clientName) {
this.clientName = clientName;
return this;
}
public String webServerRedirectUri() {
return webServerRedirectUri;
/**
* @since 3.0.0
*/
public Instant clientIdIssuedAt() {
return clientIdIssuedAt;
}
public String authorities() {
return authorities;
/**
* @since 3.0.0
*/
public OauthClientDetails clientIdIssuedAt(Instant clientIdIssuedAt) {
this.clientIdIssuedAt = clientIdIssuedAt;
return this;
}
public Integer accessTokenValidity() {
return accessTokenValidity;
/**
* @since 3.0.0
*/
public Instant clientSecretExpiresAt() {
return clientSecretExpiresAt;
}
public Integer refreshTokenValidity() {
return refreshTokenValidity;
/**
* @since 3.0.0
*/
public OauthClientDetails clientSecretExpiresAt(Instant clientSecretExpiresAt) {
this.clientSecretExpiresAt = clientSecretExpiresAt;
return this;
}
public String additionalInformation() {
return additionalInformation;
/**
* @since 3.0.0
*/
public String clientAuthenticationMethods() {
return clientAuthenticationMethods;
}
/**
* @since 3.0.0
*/
public OauthClientDetails clientAuthenticationMethods(String clientAuthenticationMethods) {
this.clientAuthenticationMethods = clientAuthenticationMethods;
return this;
}
public String scopes() {
return scopes;
}
public OauthClientDetails scopes(String scopes) {
this.scopes = scopes;
return this;
}
public String authorizationGrantTypes() {
return authorizationGrantTypes;
}
public OauthClientDetails authorizationGrantTypes(String authorizationGrantTypes) {
this.authorizationGrantTypes = authorizationGrantTypes;
return this;
}
public String redirectUris() {
return redirectUris;
}
public OauthClientDetails redirectUris(String redirectUris) {
this.redirectUris = redirectUris;
return this;
}
/**
* @since 3.0.0
*/
public String postLogoutRedirectUris() {
return postLogoutRedirectUris;
}
/**
* @since 3.0.0
*/
public OauthClientDetails postLogoutRedirectUris(String postLogoutRedirectUris) {
this.postLogoutRedirectUris = postLogoutRedirectUris;
return this;
}
@Override
public String toString() {
@ -162,15 +317,15 @@ public class OauthClientDetails implements Serializable {
sb.append("{createTime=").append(createTime);
sb.append(", archived=").append(archived);
sb.append(", clientId='").append(clientId).append('\'');
sb.append(", resourceIds='").append(resourceIds).append('\'');
sb.append(", scope='").append(scope).append('\'');
sb.append(", authorizedGrantTypes='").append(authorizedGrantTypes).append('\'');
sb.append(", webServerRedirectUri='").append(webServerRedirectUri).append('\'');
sb.append(", authorities='").append(authorities).append('\'');
sb.append(", accessTokenValidity=").append(accessTokenValidity);
sb.append(", refreshTokenValidity=").append(refreshTokenValidity);
sb.append(", additionalInformation='").append(additionalInformation).append('\'');
sb.append(", trusted=").append(trusted);
sb.append(", clientName='").append(clientName).append('\'');
sb.append(", scopes='").append(scopes).append('\'');
sb.append(", authorizationGrantTypes='").append(authorizationGrantTypes).append('\'');
sb.append(", redirectUris='").append(redirectUris).append('\'');
sb.append(", clientIdIssuedAt='").append(clientIdIssuedAt).append('\'');
sb.append(", clientSettings=").append(clientSettings);
sb.append(", tokenSettings=").append(tokenSettings);
sb.append(", postLogoutRedirectUris='").append(postLogoutRedirectUris).append('\'');
sb.append(", clientAuthenticationMethods=").append(clientAuthenticationMethods);
sb.append('}');
return sb.toString();
}
@ -185,53 +340,6 @@ public class OauthClientDetails implements Serializable {
return this;
}
/**
* @deprecated OAuth2.1 not used from v3.0.0
*/
public OauthClientDetails resourceIds(String resourceIds) {
this.resourceIds = resourceIds;
return this;
}
public OauthClientDetails authorizedGrantTypes(String authorizedGrantTypes) {
this.authorizedGrantTypes = authorizedGrantTypes;
return this;
}
public OauthClientDetails scope(String scope) {
this.scope = scope;
return this;
}
public OauthClientDetails webServerRedirectUri(String webServerRedirectUri) {
this.webServerRedirectUri = webServerRedirectUri;
return this;
}
public OauthClientDetails authorities(String authorities) {
this.authorities = authorities;
return this;
}
public OauthClientDetails accessTokenValidity(Integer accessTokenValidity) {
this.accessTokenValidity = accessTokenValidity;
return this;
}
public OauthClientDetails refreshTokenValidity(Integer refreshTokenValidity) {
this.refreshTokenValidity = refreshTokenValidity;
return this;
}
public OauthClientDetails trusted(boolean trusted) {
this.trusted = trusted;
return this;
}
public OauthClientDetails additionalInformation(String additionalInformation) {
this.additionalInformation = additionalInformation;
return this;
}
public OauthClientDetails archived(boolean archived) {
this.archived = archived;

View File

@ -6,6 +6,7 @@ import java.util.List;
/**
* @author Shengzhao Li
* @since 1.0.0
*/
public interface OauthRepository extends Repository {

View File

@ -0,0 +1,108 @@
package com.monkeyk.sos.infrastructure;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.jackson2.SecurityJackson2Modules;
import org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationServerJackson2Module;
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
import org.springframework.security.oauth2.server.authorization.settings.ConfigurationSettingNames;
import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import java.util.List;
import java.util.Map;
/**
* 2023/10/13 14:49
*
* @author Shengzhao Li
* @since 3.0.0
*/
public abstract class SettingsUtils {
private static ObjectMapper objectMapper = new ObjectMapper();
static {
// ClassLoader classLoader = JdbcRegisteredClientRepository.class.getClassLoader();
ClassLoader classLoader = SettingsUtils.class.getClassLoader();
List<Module> securityModules = SecurityJackson2Modules.getModules(classLoader);
objectMapper.registerModules(securityModules);
objectMapper.registerModule(new OAuth2AuthorizationServerJackson2Module());
}
private SettingsUtils() {
}
/**
* text settings -> TokenSettings
*
* @param settings text
* @return TokenSettings
*/
public static TokenSettings buildTokenSettings(String settings) {
Map<String, Object> map = parseMap(settings);
TokenSettings.Builder builder = TokenSettings.withSettings(map);
if (!map.containsKey(ConfigurationSettingNames.Token.ACCESS_TOKEN_FORMAT)) {
builder.accessTokenFormat(OAuth2TokenFormat.SELF_CONTAINED);
}
return builder.build();
}
/**
* TokenSettings -> text
*
* @param settings TokenSettings
* @return text
*/
public static String textTokenSettings(TokenSettings settings) {
Map<String, Object> map = settings.getSettings();
return writeMap(map);
}
/**
* ClientSettings -> text
*
* @param settings ClientSettings
* @return text
*/
public static String textClientSettings(ClientSettings settings) {
Map<String, Object> map = settings.getSettings();
return writeMap(map);
}
/**
* text settings -> ClientSettings
*
* @param settings text
* @return ClientSettings
*/
public static ClientSettings buildClientSettings(String settings) {
Map<String, Object> map = parseMap(settings);
return ClientSettings.withSettings(map)
.build();
}
private static Map<String, Object> parseMap(String data) {
try {
return objectMapper.readValue(data, new TypeReference<>() {
});
} catch (Exception ex) {
throw new IllegalArgumentException(ex.getMessage(), ex);
}
}
private static String writeMap(Map<String, Object> data) {
try {
return objectMapper.writeValueAsString(data);
} catch (Exception ex) {
throw new IllegalArgumentException(ex.getMessage(), ex);
}
}
}

View File

@ -34,23 +34,23 @@ public class OauthClientDetailsRowMapper implements RowMapper<OauthClientDetails
OauthClientDetails clientDetails = new OauthClientDetails();
clientDetails.clientId(rs.getString("client_id"));
clientDetails.resourceIds(rs.getString("resource_ids"));
// clientDetails.resourceIds(rs.getString("resource_ids"));
clientDetails.clientSecret(rs.getString("client_secret"));
clientDetails.scope(rs.getString("scope"));
clientDetails.authorizedGrantTypes(rs.getString("authorized_grant_types"));
clientDetails.webServerRedirectUri(rs.getString("web_server_redirect_uri"));
// clientDetails.scope(rs.getString("scope"));
// clientDetails.authorizedGrantTypes(rs.getString("authorized_grant_types"));
// clientDetails.webServerRedirectUri(rs.getString("web_server_redirect_uri"));
clientDetails.authorities(rs.getString("authorities"));
clientDetails.accessTokenValidity(getInteger(rs, "access_token_validity"));
clientDetails.refreshTokenValidity(getInteger(rs, "refresh_token_validity"));
// clientDetails.authorities(rs.getString("authorities"));
// clientDetails.accessTokenValidity(getInteger(rs, "access_token_validity"));
// clientDetails.refreshTokenValidity(getInteger(rs, "refresh_token_validity"));
clientDetails.additionalInformation(rs.getString("additional_information"));
// clientDetails.additionalInformation(rs.getString("additional_information"));
clientDetails.createTime(rs.getTimestamp("create_time").toLocalDateTime());
clientDetails.archived(rs.getBoolean("archived"));
clientDetails.trusted(rs.getBoolean("trusted"));
clientDetails.autoApprove(rs.getString("autoapprove"));
// clientDetails.trusted(rs.getBoolean("trusted"));
// clientDetails.autoApprove(rs.getString("autoapprove"));
return clientDetails;
}

View File

@ -62,22 +62,22 @@ public class OauthRepositoryJdbc implements OauthRepository {
this.jdbcTemplate.update(sql, ps -> {
ps.setString(1, clientDetails.clientId());
ps.setString(2, clientDetails.resourceIds());
// ps.setString(2, clientDetails.resourceIds());
ps.setString(3, clientDetails.clientSecret());
ps.setString(4, clientDetails.scope());
// ps.setString(4, clientDetails.scope());
ps.setString(5, clientDetails.authorizedGrantTypes());
ps.setString(6, clientDetails.webServerRedirectUri());
// ps.setString(5, clientDetails.authorizedGrantTypes());
// ps.setString(6, clientDetails.webServerRedirectUri());
ps.setString(7, clientDetails.authorities());
ps.setObject(8, clientDetails.accessTokenValidity());
// ps.setString(7, clientDetails.authorities());
// ps.setObject(8, clientDetails.accessTokenValidity());
ps.setObject(9, clientDetails.refreshTokenValidity());
ps.setString(10, clientDetails.additionalInformation());
// ps.setObject(9, clientDetails.refreshTokenValidity());
// ps.setString(10, clientDetails.additionalInformation());
ps.setBoolean(11, clientDetails.trusted());
ps.setString(12, clientDetails.autoApprove());
// ps.setBoolean(11, clientDetails.trusted());
// ps.setString(12, clientDetails.autoApprove());
});
}

View File

@ -0,0 +1,109 @@
package com.monkeyk.sos.service.dto;
import com.monkeyk.sos.infrastructure.SettingsUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.oauth2.jose.jws.JwsAlgorithm;
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
import java.io.Serial;
import java.io.Serializable;
import static org.springframework.security.oauth2.jose.jws.JwsAlgorithms.RS256;
/**
* 2023/10/13 11:52
* <p>
* .requireProofKey(false)
* .requireAuthorizationConsent(false);
*
* @author Shengzhao Li
* @see org.springframework.security.oauth2.server.authorization.settings.ClientSettings
* @since 3.0.0
*/
public class ClientSettingsDto implements Serializable {
@Serial
private static final long serialVersionUID = -7335241589844569340L;
/**
* PKCEtrue
* false
*/
private boolean requireProofKey;
/**
* true
* false
*/
private boolean requireAuthorizationConsent;
/**
* client jwk URL
* , null
*/
private String jwkSetUrl;
/**
* jwt token
* JwsAlgorithm
*
* @see JwsAlgorithm
*/
private String tokenEndpointAuthenticationSigningAlgorithm = RS256;
public ClientSettingsDto() {
}
public ClientSettingsDto(String clientSettings) {
ClientSettings settings = SettingsUtils.buildClientSettings(clientSettings);
this.requireAuthorizationConsent = settings.isRequireAuthorizationConsent();
this.requireProofKey = settings.isRequireProofKey();
this.tokenEndpointAuthenticationSigningAlgorithm = settings.getTokenEndpointAuthenticationSigningAlgorithm().getName();
this.jwkSetUrl = settings.getJwkSetUrl();
}
public ClientSettings toSettings() {
ClientSettings.Builder builder = ClientSettings.builder()
.requireProofKey(requireProofKey)
.tokenEndpointAuthenticationSigningAlgorithm(SignatureAlgorithm.valueOf(tokenEndpointAuthenticationSigningAlgorithm));
if (StringUtils.isNotBlank(jwkSetUrl)) {
builder.jwkSetUrl(jwkSetUrl);
}
return builder.build();
}
public boolean isRequireProofKey() {
return requireProofKey;
}
public void setRequireProofKey(boolean requireProofKey) {
this.requireProofKey = requireProofKey;
}
public boolean isRequireAuthorizationConsent() {
return requireAuthorizationConsent;
}
public void setRequireAuthorizationConsent(boolean requireAuthorizationConsent) {
this.requireAuthorizationConsent = requireAuthorizationConsent;
}
public String getJwkSetUrl() {
return jwkSetUrl;
}
public void setJwkSetUrl(String jwkSetUrl) {
this.jwkSetUrl = jwkSetUrl;
}
public String getTokenEndpointAuthenticationSigningAlgorithm() {
return tokenEndpointAuthenticationSigningAlgorithm;
}
public void setTokenEndpointAuthenticationSigningAlgorithm(String tokenEndpointAuthenticationSigningAlgorithm) {
this.tokenEndpointAuthenticationSigningAlgorithm = tokenEndpointAuthenticationSigningAlgorithm;
}
}

View File

@ -8,41 +8,126 @@ import org.apache.commons.lang3.StringUtils;
import java.io.Serial;
import java.io.Serializable;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
/**
* @author Shengzhao Li
* @since 1.0.0
*/
public class OauthClientDetailsDto implements Serializable {
@Serial
private static final long serialVersionUID = 4011292111995231569L;
/**
* id
*
* @since 3.0.0
*/
private String id;
private String createTime;
private boolean archived;
private String clientId = GuidGenerator.generate();
private String resourceIds;
/**
* client
*
*
* @since 3.0.0
*/
private String clientName;
/**
* client
*
* @since 3.0.0
*/
private String clientIdIssuedAt;
private String clientSecret = GuidGenerator.generateClientSecret();
private String scope;
private String authorizedGrantTypes;
/**
* secret
* null
* 使
*
* @since 3.0.0
*/
private String clientSecretExpiresAt;
private String webServerRedirectUri;
private String authorities;
/**
*
* : client_secret_basic,client_secret_post
*
* @see org.springframework.security.oauth2.core.ClientAuthenticationMethod
* @since 3.0.0
*/
private String clientAuthenticationMethods;
private Integer accessTokenValidity;
private Integer refreshTokenValidity;
/**
* OIDC scope ,
* : openid,profile,email
*
* @see org.springframework.security.oauth2.core.oidc.OidcScopes
*/
private String scopes;
// optional
private String additionalInformation;
/**
* grant_type (OAuth2.1),
* : authorization_code,refresh_token
*
* @see org.springframework.security.oauth2.core.AuthorizationGrantType
*/
private String authorizationGrantTypes;
/**
* OAuth2 uri code,
* The re-direct URI(s) established during registration (optional, comma separated).
*/
private String redirectUris;
/**
* OAuth2 退 post uri
*
* client
*
* @since 3.0.0
*/
private String postLogoutRedirectUris;
/**
*
* PKCE(consent)
* {ClientSettings}
*
* @see org.springframework.security.oauth2.server.authorization.settings.ClientSettings
* @since 3.0.0
*/
private ClientSettingsDto clientSettings;
/**
* token
* tokenrefresh_token
* {TokenSettings}
*
* @see org.springframework.security.oauth2.server.authorization.settings.TokenSettings
* @since 3.0.0
*/
private TokenSettingsDto tokenSettings;
private boolean trusted;
public OauthClientDetailsDto() {
}
@ -50,21 +135,26 @@ public class OauthClientDetailsDto implements Serializable {
public OauthClientDetailsDto(OauthClientDetails clientDetails) {
this.clientId = clientDetails.clientId();
this.clientSecret = clientDetails.clientSecret();
this.scope = clientDetails.scope();
this.scopes = clientDetails.scopes();
this.createTime = DateUtils.toDateTime(clientDetails.createTime());
this.archived = clientDetails.archived();
this.resourceIds = clientDetails.resourceIds();
this.postLogoutRedirectUris = clientDetails.postLogoutRedirectUris();
this.webServerRedirectUri = clientDetails.webServerRedirectUri();
this.authorities = clientDetails.authorities();
this.accessTokenValidity = clientDetails.accessTokenValidity();
this.redirectUris = clientDetails.redirectUris();
this.clientIdIssuedAt = clientDetails.clientIdIssuedAt().toString();
Instant clientSecretExpiresAt1 = clientDetails.clientSecretExpiresAt();
if (clientSecretExpiresAt1 != null) {
this.clientSecretExpiresAt = clientSecretExpiresAt1.toString();
}
this.refreshTokenValidity = clientDetails.refreshTokenValidity();
this.additionalInformation = clientDetails.additionalInformation();
this.trusted = clientDetails.trusted();
this.clientAuthenticationMethods = clientDetails.clientAuthenticationMethods();
this.clientName = clientDetails.clientName();
this.id = clientDetails.id();
this.authorizedGrantTypes = clientDetails.authorizedGrantTypes();
this.authorizationGrantTypes = clientDetails.authorizationGrantTypes();
this.clientSettings = new ClientSettingsDto(clientDetails.clientSettings());
this.tokenSettings = new TokenSettingsDto(clientDetails.tokenSettings());
}
@ -92,13 +182,6 @@ public class OauthClientDetailsDto implements Serializable {
this.clientId = clientId;
}
public String getResourceIds() {
return resourceIds;
}
public void setResourceIds(String resourceIds) {
this.resourceIds = resourceIds;
}
public String getClientSecret() {
return clientSecret;
@ -108,77 +191,6 @@ public class OauthClientDetailsDto implements Serializable {
this.clientSecret = clientSecret;
}
public String getScope() {
return scope;
}
public String getScopeWithBlank() {
if (scope != null && scope.contains(",")) {
return scope.replaceAll(",", " ");
}
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getAuthorizedGrantTypes() {
return authorizedGrantTypes;
}
public void setAuthorizedGrantTypes(String authorizedGrantTypes) {
this.authorizedGrantTypes = authorizedGrantTypes;
}
public String getWebServerRedirectUri() {
return webServerRedirectUri;
}
public void setWebServerRedirectUri(String webServerRedirectUri) {
this.webServerRedirectUri = webServerRedirectUri;
}
public String getAuthorities() {
return authorities;
}
public void setAuthorities(String authorities) {
this.authorities = authorities;
}
public Integer getAccessTokenValidity() {
return accessTokenValidity;
}
public void setAccessTokenValidity(Integer accessTokenValidity) {
this.accessTokenValidity = accessTokenValidity;
}
public Integer getRefreshTokenValidity() {
return refreshTokenValidity;
}
public void setRefreshTokenValidity(Integer refreshTokenValidity) {
this.refreshTokenValidity = refreshTokenValidity;
}
public String getAdditionalInformation() {
return additionalInformation;
}
public void setAdditionalInformation(String additionalInformation) {
this.additionalInformation = additionalInformation;
}
public boolean isTrusted() {
return trusted;
}
public void setTrusted(boolean trusted) {
this.trusted = trusted;
}
public static List<OauthClientDetailsDto> toDtos(List<OauthClientDetails> clientDetailses) {
List<OauthClientDetailsDto> dtos = new ArrayList<>(clientDetailses.size());
@ -190,51 +202,141 @@ public class OauthClientDetailsDto implements Serializable {
public boolean isContainsAuthorizationCode() {
return this.authorizedGrantTypes.contains("authorization_code");
return this.authorizationGrantTypes.contains("authorization_code");
}
public boolean isContainsPassword() {
return this.authorizedGrantTypes.contains("password");
return this.authorizationGrantTypes.contains("password");
}
public boolean isContainsImplicit() {
return this.authorizedGrantTypes.contains("implicit");
}
// public boolean isContainsImplicit() {
// return this.authorizationGrantTypes.contains("implicit");
// }
public boolean isContainsClientCredentials() {
return this.authorizedGrantTypes.contains("client_credentials");
return this.authorizationGrantTypes.contains("client_credentials");
}
public boolean isContainsRefreshToken() {
return this.authorizedGrantTypes.contains("refresh_token");
return this.authorizationGrantTypes.contains("refresh_token");
}
public OauthClientDetails createDomain() {
OauthClientDetails clientDetails = new OauthClientDetails()
.id(GuidGenerator.generate())
.clientId(clientId)
.clientName(clientName)
// encrypted client secret
.clientSecret(PasswordHandler.encode(clientSecret))
.resourceIds(resourceIds)
.authorizedGrantTypes(authorizedGrantTypes)
.scope(scope);
.postLogoutRedirectUris(postLogoutRedirectUris)
.authorizationGrantTypes(authorizationGrantTypes)
.scopes(scopes);
if (StringUtils.isNotEmpty(webServerRedirectUri)) {
clientDetails.webServerRedirectUri(webServerRedirectUri);
if (StringUtils.isNotBlank(clientIdIssuedAt)) {
clientDetails.clientIdIssuedAt(Instant.parse(this.clientIdIssuedAt));
}
if (StringUtils.isNotEmpty(authorities)) {
clientDetails.authorities(authorities);
if (StringUtils.isNotBlank(clientSecretExpiresAt)) {
clientDetails.clientSecretExpiresAt(Instant.parse(this.clientSecretExpiresAt));
}
clientDetails.accessTokenValidity(accessTokenValidity)
.refreshTokenValidity(refreshTokenValidity)
.trusted(trusted);
if (StringUtils.isNotEmpty(additionalInformation)) {
clientDetails.additionalInformation(additionalInformation);
if (StringUtils.isNotEmpty(redirectUris)) {
clientDetails.redirectUris(redirectUris);
}
clientDetails.clientSettings(this.clientSettings.toSettings().toString());
clientDetails.tokenSettings(this.tokenSettings.toSettings().toString());
return clientDetails;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public String getClientIdIssuedAt() {
return clientIdIssuedAt;
}
public void setClientIdIssuedAt(String clientIdIssuedAt) {
this.clientIdIssuedAt = clientIdIssuedAt;
}
public String getClientSecretExpiresAt() {
return clientSecretExpiresAt;
}
public void setClientSecretExpiresAt(String clientSecretExpiresAt) {
this.clientSecretExpiresAt = clientSecretExpiresAt;
}
public String getClientAuthenticationMethods() {
return clientAuthenticationMethods;
}
public void setClientAuthenticationMethods(String clientAuthenticationMethods) {
this.clientAuthenticationMethods = clientAuthenticationMethods;
}
public String getScopes() {
return scopes;
}
public void setScopes(String scopes) {
this.scopes = scopes;
}
public String getAuthorizationGrantTypes() {
return authorizationGrantTypes;
}
public void setAuthorizationGrantTypes(String authorizationGrantTypes) {
this.authorizationGrantTypes = authorizationGrantTypes;
}
public String getRedirectUris() {
return redirectUris;
}
public void setRedirectUris(String redirectUris) {
this.redirectUris = redirectUris;
}
public String getPostLogoutRedirectUris() {
return postLogoutRedirectUris;
}
public void setPostLogoutRedirectUris(String postLogoutRedirectUris) {
this.postLogoutRedirectUris = postLogoutRedirectUris;
}
public ClientSettingsDto getClientSettings() {
return clientSettings;
}
public void setClientSettings(ClientSettingsDto clientSettings) {
this.clientSettings = clientSettings;
}
public TokenSettingsDto getTokenSettings() {
return tokenSettings;
}
public void setTokenSettings(TokenSettingsDto tokenSettings) {
this.tokenSettings = tokenSettings;
}
}

View File

@ -0,0 +1,175 @@
package com.monkeyk.sos.service.dto;
import com.monkeyk.sos.infrastructure.SettingsUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import java.io.Serial;
import java.io.Serializable;
import java.time.Duration;
/**
* 2023/10/13 12:07
* <p>
* <p>
* .authorizationCodeTimeToLive(Duration.ofMinutes(5))
* .accessTokenTimeToLive(Duration.ofMinutes(5))
* .accessTokenFormat(OAuth2TokenFormat.SELF_CONTAINED)
* .deviceCodeTimeToLive(Duration.ofMinutes(5))
* .reuseRefreshTokens(true)
* .refreshTokenTimeToLive(Duration.ofMinutes(60))
* .idTokenSignatureAlgorithm(SignatureAlgorithm.RS256);
*
* @author Shengzhao Li
* @see org.springframework.security.oauth2.server.authorization.settings.TokenSettings
* @since 3.0.0
*/
public class TokenSettingsDto implements Serializable {
@Serial
private static final long serialVersionUID = -8918978047051059724L;
/**
* authorizationCode
* 300 5)
*/
private long authorizationCodeTimeToLive = 300L;
/**
* access_token
* 3600 1)
*/
private long accessTokenTimeToLive = 3600L;
/**
* token ,
* self-contained -> jwt
* reference -> uuid
*
* @see OAuth2TokenFormat
*/
private String accessTokenFormat = "self-contained";
/**
* device_code
* 300 5
*/
private long deviceCodeTimeToLive = 300L;
/**
* refresh_token
* true
*/
private boolean reuseRefreshTokens = true;
/**
* refresh_token
* 4320012
*/
private long refreshTokenTimeToLive = 43200L;
/**
* id_token使
* jwks
*
* @see SignatureAlgorithm
*/
private String idTokenSignatureAlgorithm;
public TokenSettingsDto() {
}
public TokenSettingsDto(String tokenSettings) {
TokenSettings settings = SettingsUtils.buildTokenSettings(tokenSettings);
this.accessTokenFormat = settings.getAccessTokenFormat().getValue();
this.idTokenSignatureAlgorithm = settings.getIdTokenSignatureAlgorithm().getName();
this.refreshTokenTimeToLive = settings.getRefreshTokenTimeToLive().toSeconds();
this.accessTokenFormat= settings.getAccessTokenFormat().getValue();
this.accessTokenTimeToLive=settings.getAccessTokenTimeToLive().toSeconds();
this.deviceCodeTimeToLive= settings.getDeviceCodeTimeToLive().toSeconds();
this.authorizationCodeTimeToLive= settings.getAuthorizationCodeTimeToLive().toSeconds();
}
public TokenSettings toSettings() {
TokenSettings.Builder builder = TokenSettings.builder()
.refreshTokenTimeToLive(Duration.ofSeconds(this.refreshTokenTimeToLive))
.accessTokenTimeToLive(Duration.ofSeconds(this.accessTokenTimeToLive))
.reuseRefreshTokens(this.reuseRefreshTokens)
.deviceCodeTimeToLive(Duration.ofSeconds(this.deviceCodeTimeToLive))
.authorizationCodeTimeToLive(Duration.ofSeconds(this.authorizationCodeTimeToLive));
if (StringUtils.isNotBlank(idTokenSignatureAlgorithm)) {
builder.idTokenSignatureAlgorithm(SignatureAlgorithm.valueOf(idTokenSignatureAlgorithm));
}
if (StringUtils.isNotBlank(accessTokenFormat)) {
builder.accessTokenFormat(new OAuth2TokenFormat(accessTokenFormat));
}
return builder.build();
}
public long getAuthorizationCodeTimeToLive() {
return authorizationCodeTimeToLive;
}
public void setAuthorizationCodeTimeToLive(long authorizationCodeTimeToLive) {
this.authorizationCodeTimeToLive = authorizationCodeTimeToLive;
}
public long getAccessTokenTimeToLive() {
return accessTokenTimeToLive;
}
public void setAccessTokenTimeToLive(long accessTokenTimeToLive) {
this.accessTokenTimeToLive = accessTokenTimeToLive;
}
public String getAccessTokenFormat() {
return accessTokenFormat;
}
public void setAccessTokenFormat(String accessTokenFormat) {
this.accessTokenFormat = accessTokenFormat;
}
public long getDeviceCodeTimeToLive() {
return deviceCodeTimeToLive;
}
public void setDeviceCodeTimeToLive(long deviceCodeTimeToLive) {
this.deviceCodeTimeToLive = deviceCodeTimeToLive;
}
public boolean isReuseRefreshTokens() {
return reuseRefreshTokens;
}
public void setReuseRefreshTokens(boolean reuseRefreshTokens) {
this.reuseRefreshTokens = reuseRefreshTokens;
}
public long getRefreshTokenTimeToLive() {
return refreshTokenTimeToLive;
}
public void setRefreshTokenTimeToLive(long refreshTokenTimeToLive) {
this.refreshTokenTimeToLive = refreshTokenTimeToLive;
}
public String getIdTokenSignatureAlgorithm() {
return idTokenSignatureAlgorithm;
}
public void setIdTokenSignatureAlgorithm(String idTokenSignatureAlgorithm) {
this.idTokenSignatureAlgorithm = idTokenSignatureAlgorithm;
}
}

View File

@ -35,14 +35,14 @@ public class OauthClientDetailsDtoValidator implements Validator {
}
private void validateGrantTypes(OauthClientDetailsDto clientDetailsDto, Errors errors) {
final String grantTypes = clientDetailsDto.getAuthorizedGrantTypes();
final String grantTypes = clientDetailsDto.getAuthorizationGrantTypes();
if (StringUtils.isEmpty(grantTypes)) {
errors.rejectValue("authorizedGrantTypes", null, "grant_type(s) is required");
errors.rejectValue("authorizationGrantTypes", null, "grant_type(s) is required");
return;
}
if ("refresh_token".equalsIgnoreCase(grantTypes)) {
errors.rejectValue("authorizedGrantTypes", null, "grant_type(s) 不能只是[refresh_token]");
errors.rejectValue("authorizationGrantTypes", null, "grant_type(s) 不能只是[refresh_token]");
}
}

View File

@ -0,0 +1,49 @@
package com.monkeyk.sos.infrastructure;
import org.junit.jupiter.api.Test;
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import static org.junit.jupiter.api.Assertions.*;
/**
* 2023/10/13 14:59
*
* @author Shengzhao Li
* @since 3.0.0
*/
class SettingsUtilsTest {
@Test
void textTokenSettings() {
TokenSettings settings = TokenSettings.builder()
.reuseRefreshTokens(false)
.build();
String s = SettingsUtils.textTokenSettings(settings);
assertNotNull(s);
// System.out.println(s);
TokenSettings tokenSettings = SettingsUtils.buildTokenSettings(s);
assertNotNull(tokenSettings);
}
@Test
void textClientSettings() {
ClientSettings settings = ClientSettings.builder()
.requireProofKey(true)
.build();
String s = SettingsUtils.textClientSettings(settings);
assertNotNull(s);
// System.out.println(s);
ClientSettings clientSettings = SettingsUtils.buildClientSettings(s);
assertNotNull(clientSettings);
}
}

View File

@ -53,10 +53,10 @@ public abstract class AbstractInlineAccessTokenInvokerTest extends AbstractRepos
OauthClientDetails clientDetails = new OauthClientDetails();
clientDetails.clientId(clientId)
.clientSecret(PasswordHandler.encode(clientSecret))
.authorizedGrantTypes(grantTypes())
.scope("read")
.accessTokenValidity(200)
.resourceIds(RESOURCE_ID);
.authorizationGrantTypes(grantTypes())
.scopes("openid");
// .accessTokenValidity(200)
// .resourceIds(RESOURCE_ID);
oauthRepository.saveOauthClientDetails(clientDetails);

View File

@ -0,0 +1,29 @@
package com.monkeyk.sos.service.dto;
import org.junit.jupiter.api.Test;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import static org.junit.jupiter.api.Assertions.*;
/**
* 2023/10/13 14:24
*
* @author Shengzhao Li
*/
class TokenSettingsDtoTest {
@Test
void toSettings() {
TokenSettingsDto settingsDto = new TokenSettingsDto();
TokenSettings tokenSettings = settingsDto.toSettings();
assertNotNull(tokenSettings);
// System.out.println(tokenSettings);
}
}