Add "How-to: Implement core services with JPA"
This commit is contained in:
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package sample.jpa;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
// tag::class[]
|
||||
@Entity
|
||||
public class Authorization {
|
||||
@Id
|
||||
private String id;
|
||||
private String registeredClientId;
|
||||
private String principalName;
|
||||
private String authorizationGrantType;
|
||||
@Column(length = 4000)
|
||||
private String attributes;
|
||||
@Column(length = 500)
|
||||
private String state;
|
||||
|
||||
@Column(length = 4000)
|
||||
private String authorizationCodeValue;
|
||||
private Instant authorizationCodeIssuedAt;
|
||||
private Instant authorizationCodeExpiresAt;
|
||||
private String authorizationCodeMetadata;
|
||||
|
||||
@Column(length = 4000)
|
||||
private String accessTokenValue;
|
||||
private Instant accessTokenIssuedAt;
|
||||
private Instant accessTokenExpiresAt;
|
||||
@Column(length = 2000)
|
||||
private String accessTokenMetadata;
|
||||
private String accessTokenType;
|
||||
@Column(length = 1000)
|
||||
private String accessTokenScopes;
|
||||
|
||||
@Column(length = 4000)
|
||||
private String refreshTokenValue;
|
||||
private Instant refreshTokenIssuedAt;
|
||||
private Instant refreshTokenExpiresAt;
|
||||
@Column(length = 2000)
|
||||
private String refreshTokenMetadata;
|
||||
|
||||
@Column(length = 4000)
|
||||
private String oidcIdTokenValue;
|
||||
private Instant oidcIdTokenIssuedAt;
|
||||
private Instant oidcIdTokenExpiresAt;
|
||||
@Column(length = 2000)
|
||||
private String oidcIdTokenMetadata;
|
||||
@Column(length = 2000)
|
||||
private String oidcIdTokenClaims;
|
||||
|
||||
// getters and setters
|
||||
// end::class[]
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getRegisteredClientId() {
|
||||
return registeredClientId;
|
||||
}
|
||||
|
||||
public void setRegisteredClientId(String registeredClientId) {
|
||||
this.registeredClientId = registeredClientId;
|
||||
}
|
||||
|
||||
public String getPrincipalName() {
|
||||
return principalName;
|
||||
}
|
||||
|
||||
public void setPrincipalName(String principalName) {
|
||||
this.principalName = principalName;
|
||||
}
|
||||
|
||||
public String getAuthorizationGrantType() {
|
||||
return authorizationGrantType;
|
||||
}
|
||||
|
||||
public void setAuthorizationGrantType(String authorizationGrantType) {
|
||||
this.authorizationGrantType = authorizationGrantType;
|
||||
}
|
||||
|
||||
public String getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(String attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getAuthorizationCodeValue() {
|
||||
return authorizationCodeValue;
|
||||
}
|
||||
|
||||
public void setAuthorizationCodeValue(String authorizationCode) {
|
||||
this.authorizationCodeValue = authorizationCode;
|
||||
}
|
||||
|
||||
public Instant getAuthorizationCodeIssuedAt() {
|
||||
return authorizationCodeIssuedAt;
|
||||
}
|
||||
|
||||
public void setAuthorizationCodeIssuedAt(Instant authorizationCodeIssuedAt) {
|
||||
this.authorizationCodeIssuedAt = authorizationCodeIssuedAt;
|
||||
}
|
||||
|
||||
public Instant getAuthorizationCodeExpiresAt() {
|
||||
return authorizationCodeExpiresAt;
|
||||
}
|
||||
|
||||
public void setAuthorizationCodeExpiresAt(Instant authorizationCodeExpiresAt) {
|
||||
this.authorizationCodeExpiresAt = authorizationCodeExpiresAt;
|
||||
}
|
||||
|
||||
public String getAuthorizationCodeMetadata() {
|
||||
return authorizationCodeMetadata;
|
||||
}
|
||||
|
||||
public void setAuthorizationCodeMetadata(String authorizationCodeMetadata) {
|
||||
this.authorizationCodeMetadata = authorizationCodeMetadata;
|
||||
}
|
||||
|
||||
public String getAccessTokenValue() {
|
||||
return accessTokenValue;
|
||||
}
|
||||
|
||||
public void setAccessTokenValue(String accessToken) {
|
||||
this.accessTokenValue = accessToken;
|
||||
}
|
||||
|
||||
public Instant getAccessTokenIssuedAt() {
|
||||
return accessTokenIssuedAt;
|
||||
}
|
||||
|
||||
public void setAccessTokenIssuedAt(Instant accessTokenIssuedAt) {
|
||||
this.accessTokenIssuedAt = accessTokenIssuedAt;
|
||||
}
|
||||
|
||||
public Instant getAccessTokenExpiresAt() {
|
||||
return accessTokenExpiresAt;
|
||||
}
|
||||
|
||||
public void setAccessTokenExpiresAt(Instant accessTokenExpiresAt) {
|
||||
this.accessTokenExpiresAt = accessTokenExpiresAt;
|
||||
}
|
||||
|
||||
public String getAccessTokenMetadata() {
|
||||
return accessTokenMetadata;
|
||||
}
|
||||
|
||||
public void setAccessTokenMetadata(String accessTokenMetadata) {
|
||||
this.accessTokenMetadata = accessTokenMetadata;
|
||||
}
|
||||
|
||||
public String getAccessTokenType() {
|
||||
return accessTokenType;
|
||||
}
|
||||
|
||||
public void setAccessTokenType(String accessTokenType) {
|
||||
this.accessTokenType = accessTokenType;
|
||||
}
|
||||
|
||||
public String getAccessTokenScopes() {
|
||||
return accessTokenScopes;
|
||||
}
|
||||
|
||||
public void setAccessTokenScopes(String accessTokenScopes) {
|
||||
this.accessTokenScopes = accessTokenScopes;
|
||||
}
|
||||
|
||||
public String getRefreshTokenValue() {
|
||||
return refreshTokenValue;
|
||||
}
|
||||
|
||||
public void setRefreshTokenValue(String refreshToken) {
|
||||
this.refreshTokenValue = refreshToken;
|
||||
}
|
||||
|
||||
public Instant getRefreshTokenIssuedAt() {
|
||||
return refreshTokenIssuedAt;
|
||||
}
|
||||
|
||||
public void setRefreshTokenIssuedAt(Instant refreshTokenIssuedAt) {
|
||||
this.refreshTokenIssuedAt = refreshTokenIssuedAt;
|
||||
}
|
||||
|
||||
public Instant getRefreshTokenExpiresAt() {
|
||||
return refreshTokenExpiresAt;
|
||||
}
|
||||
|
||||
public void setRefreshTokenExpiresAt(Instant refreshTokenExpiresAt) {
|
||||
this.refreshTokenExpiresAt = refreshTokenExpiresAt;
|
||||
}
|
||||
|
||||
public String getRefreshTokenMetadata() {
|
||||
return refreshTokenMetadata;
|
||||
}
|
||||
|
||||
public void setRefreshTokenMetadata(String refreshTokenMetadata) {
|
||||
this.refreshTokenMetadata = refreshTokenMetadata;
|
||||
}
|
||||
|
||||
public String getOidcIdTokenValue() {
|
||||
return oidcIdTokenValue;
|
||||
}
|
||||
|
||||
public void setOidcIdTokenValue(String idToken) {
|
||||
this.oidcIdTokenValue = idToken;
|
||||
}
|
||||
|
||||
public Instant getOidcIdTokenIssuedAt() {
|
||||
return oidcIdTokenIssuedAt;
|
||||
}
|
||||
|
||||
public void setOidcIdTokenIssuedAt(Instant idTokenIssuedAt) {
|
||||
this.oidcIdTokenIssuedAt = idTokenIssuedAt;
|
||||
}
|
||||
|
||||
public Instant getOidcIdTokenExpiresAt() {
|
||||
return oidcIdTokenExpiresAt;
|
||||
}
|
||||
|
||||
public void setOidcIdTokenExpiresAt(Instant idTokenExpiresAt) {
|
||||
this.oidcIdTokenExpiresAt = idTokenExpiresAt;
|
||||
}
|
||||
|
||||
public String getOidcIdTokenMetadata() {
|
||||
return oidcIdTokenMetadata;
|
||||
}
|
||||
|
||||
public void setOidcIdTokenMetadata(String idTokenMetadata) {
|
||||
this.oidcIdTokenMetadata = idTokenMetadata;
|
||||
}
|
||||
|
||||
public String getOidcIdTokenClaims() {
|
||||
return oidcIdTokenClaims;
|
||||
}
|
||||
|
||||
public void setOidcIdTokenClaims(String idTokenClaims) {
|
||||
this.oidcIdTokenClaims = idTokenClaims;
|
||||
}
|
||||
// tag::class[]
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package sample.jpa;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
|
||||
/**
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
// tag::class[]
|
||||
@Entity
|
||||
@IdClass(AuthorizationConsent.AuthorizationConsentId.class)
|
||||
public class AuthorizationConsent {
|
||||
@Id
|
||||
private String registeredClientId;
|
||||
@Id
|
||||
private String principalName;
|
||||
@Column(length = 1000)
|
||||
private String authorities;
|
||||
|
||||
// getters and setters
|
||||
// end::class[]
|
||||
public String getRegisteredClientId() {
|
||||
return registeredClientId;
|
||||
}
|
||||
|
||||
public void setRegisteredClientId(String registeredClientId) {
|
||||
this.registeredClientId = registeredClientId;
|
||||
}
|
||||
|
||||
public String getPrincipalName() {
|
||||
return principalName;
|
||||
}
|
||||
|
||||
public void setPrincipalName(String principalName) {
|
||||
this.principalName = principalName;
|
||||
}
|
||||
|
||||
public String getAuthorities() {
|
||||
return authorities;
|
||||
}
|
||||
|
||||
public void setAuthorities(String authorities) {
|
||||
this.authorities = authorities;
|
||||
}
|
||||
// tag::class[]
|
||||
|
||||
public static class AuthorizationConsentId implements Serializable {
|
||||
private String registeredClientId;
|
||||
private String principalName;
|
||||
|
||||
// getters and setters
|
||||
// end::class[]
|
||||
public String getRegisteredClientId() {
|
||||
return registeredClientId;
|
||||
}
|
||||
|
||||
public void setRegisteredClientId(String registeredClientId) {
|
||||
this.registeredClientId = registeredClientId;
|
||||
}
|
||||
|
||||
public String getPrincipalName() {
|
||||
return principalName;
|
||||
}
|
||||
|
||||
public void setPrincipalName(String principalName) {
|
||||
this.principalName = principalName;
|
||||
}
|
||||
// tag::class[]
|
||||
|
||||
// equals and hashCode
|
||||
// end::class[]
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AuthorizationConsentId that = (AuthorizationConsentId) o;
|
||||
return registeredClientId.equals(that.registeredClientId) && principalName.equals(that.principalName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(registeredClientId, principalName);
|
||||
}
|
||||
// tag::class[]
|
||||
}
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package sample.jpa;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
// tag::class[]
|
||||
@Repository
|
||||
public interface AuthorizationConsentRepository extends JpaRepository<AuthorizationConsent, AuthorizationConsent.AuthorizationConsentId> {
|
||||
Optional<AuthorizationConsent> findByRegisteredClientIdAndPrincipalName(String registeredClientId, String principalName);
|
||||
void deleteByRegisteredClientIdAndPrincipalName(String registeredClientId, String principalName);
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package sample.jpa;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
// tag::class[]
|
||||
@Repository
|
||||
public interface AuthorizationRepository extends JpaRepository<Authorization, String> {
|
||||
Optional<Authorization> findByState(String state);
|
||||
Optional<Authorization> findByAuthorizationCodeValue(String authorizationCode);
|
||||
Optional<Authorization> findByAccessTokenValue(String accessToken);
|
||||
Optional<Authorization> findByRefreshTokenValue(String refreshToken);
|
||||
@Query("select a from Authorization a where a.state = :token" +
|
||||
" or a.authorizationCodeValue = :token" +
|
||||
" or a.accessTokenValue = :token" +
|
||||
" or a.refreshTokenValue = :token"
|
||||
)
|
||||
Optional<Authorization> findByStateOrAuthorizationCodeValueOrAccessTokenValueOrRefreshTokenValue(@Param("token") String token);
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package sample.jpa;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
// tag::class[]
|
||||
@Entity
|
||||
public class Client {
|
||||
@Id
|
||||
private String id;
|
||||
private String clientId;
|
||||
private Instant clientIdIssuedAt;
|
||||
private String clientSecret;
|
||||
private Instant clientSecretExpiresAt;
|
||||
private String clientName;
|
||||
@Column(length = 1000)
|
||||
private String clientAuthenticationMethods;
|
||||
@Column(length = 1000)
|
||||
private String authorizationGrantTypes;
|
||||
@Column(length = 1000)
|
||||
private String redirectUris;
|
||||
@Column(length = 1000)
|
||||
private String scopes;
|
||||
@Column(length = 2000)
|
||||
private String clientSettings;
|
||||
@Column(length = 2000)
|
||||
private String tokenSettings;
|
||||
|
||||
// getters and setters
|
||||
// end::class[]
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public Instant getClientIdIssuedAt() {
|
||||
return clientIdIssuedAt;
|
||||
}
|
||||
|
||||
public void setClientIdIssuedAt(Instant clientIdIssuedAt) {
|
||||
this.clientIdIssuedAt = clientIdIssuedAt;
|
||||
}
|
||||
|
||||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
|
||||
public void setClientSecret(String clientSecret) {
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
public Instant getClientSecretExpiresAt() {
|
||||
return clientSecretExpiresAt;
|
||||
}
|
||||
|
||||
public void setClientSecretExpiresAt(Instant clientSecretExpiresAt) {
|
||||
this.clientSecretExpiresAt = clientSecretExpiresAt;
|
||||
}
|
||||
|
||||
public String getClientName() {
|
||||
return clientName;
|
||||
}
|
||||
|
||||
public void setClientName(String clientName) {
|
||||
this.clientName = clientName;
|
||||
}
|
||||
|
||||
public String getClientAuthenticationMethods() {
|
||||
return clientAuthenticationMethods;
|
||||
}
|
||||
|
||||
public void setClientAuthenticationMethods(String clientAuthenticationMethods) {
|
||||
this.clientAuthenticationMethods = clientAuthenticationMethods;
|
||||
}
|
||||
|
||||
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 getScopes() {
|
||||
return scopes;
|
||||
}
|
||||
|
||||
public void setScopes(String scopes) {
|
||||
this.scopes = scopes;
|
||||
}
|
||||
|
||||
public String getClientSettings() {
|
||||
return clientSettings;
|
||||
}
|
||||
|
||||
public void setClientSettings(String clientSettings) {
|
||||
this.clientSettings = clientSettings;
|
||||
}
|
||||
|
||||
public String getTokenSettings() {
|
||||
return tokenSettings;
|
||||
}
|
||||
|
||||
public void setTokenSettings(String tokenSettings) {
|
||||
this.tokenSettings = tokenSettings;
|
||||
}
|
||||
// tag::class[]
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package sample.jpa;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
// tag::class[]
|
||||
@Repository
|
||||
public interface ClientRepository extends JpaRepository<Client, String> {
|
||||
Optional<Client> findByClientId(String clientId);
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package sample.jpa;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsent;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
// tag::class[]
|
||||
@Component
|
||||
public class JpaOAuth2AuthorizationConsentService implements OAuth2AuthorizationConsentService {
|
||||
private final AuthorizationConsentRepository authorizationConsentRepository;
|
||||
private final RegisteredClientRepository registeredClientRepository;
|
||||
|
||||
public JpaOAuth2AuthorizationConsentService(AuthorizationConsentRepository authorizationConsentRepository, RegisteredClientRepository registeredClientRepository) {
|
||||
Assert.notNull(authorizationConsentRepository, "authorizationConsentRepository cannot be null");
|
||||
Assert.notNull(registeredClientRepository, "registeredClientRepository cannot be null");
|
||||
this.authorizationConsentRepository = authorizationConsentRepository;
|
||||
this.registeredClientRepository = registeredClientRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(OAuth2AuthorizationConsent authorizationConsent) {
|
||||
Assert.notNull(authorizationConsent, "authorizationConsent cannot be null");
|
||||
this.authorizationConsentRepository.save(toEntity(authorizationConsent));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(OAuth2AuthorizationConsent authorizationConsent) {
|
||||
Assert.notNull(authorizationConsent, "authorizationConsent cannot be null");
|
||||
this.authorizationConsentRepository.deleteByRegisteredClientIdAndPrincipalName(
|
||||
authorizationConsent.getRegisteredClientId(), authorizationConsent.getPrincipalName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2AuthorizationConsent findById(String registeredClientId, String principalName) {
|
||||
Assert.hasText(registeredClientId, "registeredClientId cannot be empty");
|
||||
Assert.hasText(principalName, "principalName cannot be empty");
|
||||
return this.authorizationConsentRepository.findByRegisteredClientIdAndPrincipalName(
|
||||
registeredClientId, principalName).map(this::toObject).orElse(null);
|
||||
}
|
||||
|
||||
private OAuth2AuthorizationConsent toObject(AuthorizationConsent authorizationConsent) {
|
||||
String registeredClientId = authorizationConsent.getRegisteredClientId();
|
||||
RegisteredClient registeredClient = this.registeredClientRepository.findById(registeredClientId);
|
||||
if (registeredClient == null) {
|
||||
throw new DataRetrievalFailureException(
|
||||
"The RegisteredClient with id '" + registeredClientId + "' was not found in the RegisteredClientRepository.");
|
||||
}
|
||||
|
||||
OAuth2AuthorizationConsent.Builder builder = OAuth2AuthorizationConsent.withId(
|
||||
registeredClientId, authorizationConsent.getPrincipalName());
|
||||
if (authorizationConsent.getAuthorities() != null) {
|
||||
for (String authority : StringUtils.commaDelimitedListToSet(authorizationConsent.getAuthorities())) {
|
||||
builder.authority(new SimpleGrantedAuthority(authority));
|
||||
}
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private AuthorizationConsent toEntity(OAuth2AuthorizationConsent authorizationConsent) {
|
||||
AuthorizationConsent entity = new AuthorizationConsent();
|
||||
entity.setRegisteredClientId(authorizationConsent.getRegisteredClientId());
|
||||
entity.setPrincipalName(authorizationConsent.getPrincipalName());
|
||||
|
||||
Set<String> authorities = new HashSet<>();
|
||||
for (GrantedAuthority authority : authorizationConsent.getAuthorities()) {
|
||||
authorities.add(authority.getAuthority());
|
||||
}
|
||||
entity.setAuthorities(StringUtils.collectionToCommaDelimitedString(authorities));
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package sample.jpa;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.Module;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
import org.springframework.security.jackson2.SecurityJackson2Modules;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthorizationCode;
|
||||
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
|
||||
import org.springframework.security.oauth2.core.OAuth2Token;
|
||||
import org.springframework.security.oauth2.core.OAuth2TokenType;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationServerJackson2Module;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
// tag::class[]
|
||||
@Component
|
||||
public class JpaOAuth2AuthorizationService implements OAuth2AuthorizationService {
|
||||
private final AuthorizationRepository authorizationRepository;
|
||||
private final RegisteredClientRepository registeredClientRepository;
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
public JpaOAuth2AuthorizationService(AuthorizationRepository authorizationRepository, RegisteredClientRepository registeredClientRepository) {
|
||||
Assert.notNull(authorizationRepository, "authorizationRepository cannot be null");
|
||||
Assert.notNull(registeredClientRepository, "registeredClientRepository cannot be null");
|
||||
this.authorizationRepository = authorizationRepository;
|
||||
this.registeredClientRepository = registeredClientRepository;
|
||||
|
||||
ClassLoader classLoader = JpaOAuth2AuthorizationService.class.getClassLoader();
|
||||
List<Module> securityModules = SecurityJackson2Modules.getModules(classLoader);
|
||||
this.objectMapper.registerModules(securityModules);
|
||||
this.objectMapper.registerModule(new OAuth2AuthorizationServerJackson2Module());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(OAuth2Authorization authorization) {
|
||||
Assert.notNull(authorization, "authorization cannot be null");
|
||||
this.authorizationRepository.save(toEntity(authorization));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(OAuth2Authorization authorization) {
|
||||
Assert.notNull(authorization, "authorization cannot be null");
|
||||
this.authorizationRepository.deleteById(authorization.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2Authorization findById(String id) {
|
||||
Assert.hasText(id, "id cannot be empty");
|
||||
return this.authorizationRepository.findById(id).map(this::toObject).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2Authorization findByToken(String token, OAuth2TokenType tokenType) {
|
||||
Assert.hasText(token, "token cannot be empty");
|
||||
|
||||
Optional<Authorization> result;
|
||||
if (tokenType == null) {
|
||||
result = this.authorizationRepository.findByStateOrAuthorizationCodeValueOrAccessTokenValueOrRefreshTokenValue(token);
|
||||
} else if (OAuth2ParameterNames.STATE.equals(tokenType.getValue())) {
|
||||
result = this.authorizationRepository.findByState(token);
|
||||
} else if (OAuth2ParameterNames.CODE.equals(tokenType.getValue())) {
|
||||
result = this.authorizationRepository.findByAuthorizationCodeValue(token);
|
||||
} else if (OAuth2ParameterNames.ACCESS_TOKEN.equals(tokenType.getValue())) {
|
||||
result = this.authorizationRepository.findByAccessTokenValue(token);
|
||||
} else if (OAuth2ParameterNames.REFRESH_TOKEN.equals(tokenType.getValue())) {
|
||||
result = this.authorizationRepository.findByRefreshTokenValue(token);
|
||||
} else {
|
||||
result = Optional.empty();
|
||||
}
|
||||
|
||||
return result.map(this::toObject).orElse(null);
|
||||
}
|
||||
|
||||
private OAuth2Authorization toObject(Authorization entity) {
|
||||
RegisteredClient registeredClient = this.registeredClientRepository.findById(entity.getRegisteredClientId());
|
||||
if (registeredClient == null) {
|
||||
throw new DataRetrievalFailureException(
|
||||
"The RegisteredClient with id '" + entity.getRegisteredClientId() + "' was not found in the RegisteredClientRepository.");
|
||||
}
|
||||
|
||||
OAuth2Authorization.Builder builder = OAuth2Authorization.withRegisteredClient(registeredClient)
|
||||
.id(entity.getId())
|
||||
.principalName(entity.getPrincipalName())
|
||||
.authorizationGrantType(resolveAuthorizationGrantType(entity.getAuthorizationGrantType()))
|
||||
.attributes(attributes -> attributes.putAll(parseMap(entity.getAttributes())));
|
||||
if (entity.getState() != null) {
|
||||
builder.attribute(OAuth2ParameterNames.STATE, entity.getState());
|
||||
}
|
||||
|
||||
if (entity.getAuthorizationCodeValue() != null) {
|
||||
OAuth2AuthorizationCode authorizationCode = new OAuth2AuthorizationCode(
|
||||
entity.getAuthorizationCodeValue(),
|
||||
entity.getAuthorizationCodeIssuedAt(),
|
||||
entity.getAuthorizationCodeExpiresAt());
|
||||
builder.token(authorizationCode, metadata -> metadata.putAll(parseMap(entity.getAuthorizationCodeMetadata())));
|
||||
}
|
||||
|
||||
if (entity.getAccessTokenValue() != null) {
|
||||
OAuth2AccessToken accessToken = new OAuth2AccessToken(
|
||||
OAuth2AccessToken.TokenType.BEARER,
|
||||
entity.getAccessTokenValue(),
|
||||
entity.getAccessTokenIssuedAt(),
|
||||
entity.getAccessTokenExpiresAt());
|
||||
builder.token(accessToken, metadata -> metadata.putAll(parseMap(entity.getAccessTokenMetadata())));
|
||||
}
|
||||
|
||||
if (entity.getRefreshTokenValue() != null) {
|
||||
OAuth2RefreshToken refreshToken = new OAuth2RefreshToken(
|
||||
entity.getRefreshTokenValue(),
|
||||
entity.getRefreshTokenIssuedAt(),
|
||||
entity.getRefreshTokenExpiresAt());
|
||||
builder.token(refreshToken, metadata -> metadata.putAll(parseMap(entity.getRefreshTokenMetadata())));
|
||||
}
|
||||
|
||||
if (entity.getOidcIdTokenValue() != null) {
|
||||
OidcIdToken idToken = new OidcIdToken(
|
||||
entity.getOidcIdTokenValue(),
|
||||
entity.getOidcIdTokenIssuedAt(),
|
||||
entity.getOidcIdTokenExpiresAt(),
|
||||
parseMap(entity.getOidcIdTokenClaims()));
|
||||
builder.token(idToken, metadata -> metadata.putAll(parseMap(entity.getOidcIdTokenMetadata())));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private Authorization toEntity(OAuth2Authorization authorization) {
|
||||
Authorization entity = new Authorization();
|
||||
entity.setId(authorization.getId());
|
||||
entity.setRegisteredClientId(authorization.getRegisteredClientId());
|
||||
entity.setPrincipalName(authorization.getPrincipalName());
|
||||
entity.setAuthorizationGrantType(authorization.getAuthorizationGrantType().getValue());
|
||||
entity.setAttributes(writeMap(authorization.getAttributes()));
|
||||
entity.setState(authorization.getAttribute(OAuth2ParameterNames.STATE));
|
||||
|
||||
OAuth2Authorization.Token<OAuth2AuthorizationCode> authorizationCode =
|
||||
authorization.getToken(OAuth2AuthorizationCode.class);
|
||||
setTokenValues(
|
||||
authorizationCode,
|
||||
entity::setAuthorizationCodeValue,
|
||||
entity::setAuthorizationCodeIssuedAt,
|
||||
entity::setAuthorizationCodeExpiresAt,
|
||||
entity::setAuthorizationCodeMetadata
|
||||
);
|
||||
|
||||
OAuth2Authorization.Token<OAuth2AccessToken> accessToken =
|
||||
authorization.getToken(OAuth2AccessToken.class);
|
||||
setTokenValues(
|
||||
accessToken,
|
||||
entity::setAccessTokenValue,
|
||||
entity::setAccessTokenIssuedAt,
|
||||
entity::setAccessTokenExpiresAt,
|
||||
entity::setAccessTokenMetadata
|
||||
);
|
||||
if (accessToken != null && accessToken.getToken().getScopes() != null) {
|
||||
entity.setAccessTokenScopes(StringUtils.collectionToDelimitedString(accessToken.getToken().getScopes(), ","));
|
||||
}
|
||||
|
||||
OAuth2Authorization.Token<OAuth2RefreshToken> refreshToken =
|
||||
authorization.getToken(OAuth2RefreshToken.class);
|
||||
setTokenValues(
|
||||
refreshToken,
|
||||
entity::setRefreshTokenValue,
|
||||
entity::setRefreshTokenIssuedAt,
|
||||
entity::setRefreshTokenExpiresAt,
|
||||
entity::setRefreshTokenMetadata
|
||||
);
|
||||
|
||||
OAuth2Authorization.Token<OidcIdToken> oidcIdToken =
|
||||
authorization.getToken(OidcIdToken.class);
|
||||
setTokenValues(
|
||||
oidcIdToken,
|
||||
entity::setOidcIdTokenValue,
|
||||
entity::setOidcIdTokenIssuedAt,
|
||||
entity::setOidcIdTokenExpiresAt,
|
||||
entity::setOidcIdTokenMetadata
|
||||
);
|
||||
if (oidcIdToken != null) {
|
||||
entity.setOidcIdTokenClaims(writeMap(oidcIdToken.getClaims()));
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private void setTokenValues(
|
||||
OAuth2Authorization.Token<?> token,
|
||||
Consumer<String> tokenValueConsumer,
|
||||
Consumer<Instant> issuedAtConsumer,
|
||||
Consumer<Instant> expiresAtConsumer,
|
||||
Consumer<String> metadataConsumer) {
|
||||
if (token != null) {
|
||||
OAuth2Token oAuth2Token = token.getToken();
|
||||
tokenValueConsumer.accept(oAuth2Token.getTokenValue());
|
||||
issuedAtConsumer.accept(oAuth2Token.getIssuedAt());
|
||||
expiresAtConsumer.accept(oAuth2Token.getExpiresAt());
|
||||
metadataConsumer.accept(writeMap(token.getMetadata()));
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> parseMap(String data) {
|
||||
try {
|
||||
return this.objectMapper.readValue(data, new TypeReference<>() {
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalArgumentException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private String writeMap(Map<String, Object> metadata) {
|
||||
try {
|
||||
return this.objectMapper.writeValueAsString(metadata);
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalArgumentException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static AuthorizationGrantType resolveAuthorizationGrantType(String authorizationGrantType) {
|
||||
if (AuthorizationGrantType.AUTHORIZATION_CODE.getValue().equals(authorizationGrantType)) {
|
||||
return AuthorizationGrantType.AUTHORIZATION_CODE;
|
||||
} else if (AuthorizationGrantType.CLIENT_CREDENTIALS.getValue().equals(authorizationGrantType)) {
|
||||
return AuthorizationGrantType.CLIENT_CREDENTIALS;
|
||||
} else if (AuthorizationGrantType.REFRESH_TOKEN.getValue().equals(authorizationGrantType)) {
|
||||
return AuthorizationGrantType.REFRESH_TOKEN;
|
||||
}
|
||||
return new AuthorizationGrantType(authorizationGrantType); // Custom authorization grant type
|
||||
}
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package sample.jpa;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
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.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ClientSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.config.TokenSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationServerJackson2Module;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
// tag::class[]
|
||||
@Component
|
||||
public class JpaRegisteredClientRepository implements RegisteredClientRepository {
|
||||
private final ClientRepository clientRepository;
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
public JpaRegisteredClientRepository(ClientRepository clientRepository) {
|
||||
Assert.notNull(clientRepository, "clientRepository cannot be null");
|
||||
this.clientRepository = clientRepository;
|
||||
|
||||
ClassLoader classLoader = JpaRegisteredClientRepository.class.getClassLoader();
|
||||
List<Module> securityModules = SecurityJackson2Modules.getModules(classLoader);
|
||||
this.objectMapper.registerModules(securityModules);
|
||||
this.objectMapper.registerModule(new OAuth2AuthorizationServerJackson2Module());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(RegisteredClient registeredClient) {
|
||||
Assert.notNull(registeredClient, "registeredClient cannot be null");
|
||||
this.clientRepository.save(toEntity(registeredClient));
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegisteredClient findById(String id) {
|
||||
Assert.hasText(id, "id cannot be empty");
|
||||
return this.clientRepository.findById(id).map(this::toObject).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegisteredClient findByClientId(String clientId) {
|
||||
Assert.hasText(clientId, "clientId cannot be empty");
|
||||
return this.clientRepository.findByClientId(clientId).map(this::toObject).orElse(null);
|
||||
}
|
||||
|
||||
private RegisteredClient toObject(Client client) {
|
||||
Set<String> clientAuthenticationMethods = StringUtils.commaDelimitedListToSet(
|
||||
client.getClientAuthenticationMethods());
|
||||
Set<String> authorizationGrantTypes = StringUtils.commaDelimitedListToSet(
|
||||
client.getAuthorizationGrantTypes());
|
||||
Set<String> redirectUris = StringUtils.commaDelimitedListToSet(
|
||||
client.getRedirectUris());
|
||||
Set<String> clientScopes = StringUtils.commaDelimitedListToSet(
|
||||
client.getScopes());
|
||||
|
||||
RegisteredClient.Builder builder = RegisteredClient.withId(client.getId())
|
||||
.clientId(client.getClientId())
|
||||
.clientIdIssuedAt(client.getClientIdIssuedAt())
|
||||
.clientSecret(client.getClientSecret())
|
||||
.clientSecretExpiresAt(client.getClientSecretExpiresAt())
|
||||
.clientName(client.getClientName())
|
||||
.clientAuthenticationMethods(authenticationMethods ->
|
||||
clientAuthenticationMethods.forEach(authenticationMethod ->
|
||||
authenticationMethods.add(resolveClientAuthenticationMethod(authenticationMethod))))
|
||||
.authorizationGrantTypes((grantTypes) ->
|
||||
authorizationGrantTypes.forEach(grantType ->
|
||||
grantTypes.add(resolveAuthorizationGrantType(grantType))))
|
||||
.redirectUris((uris) -> uris.addAll(redirectUris))
|
||||
.scopes((scopes) -> scopes.addAll(clientScopes));
|
||||
|
||||
Map<String, Object> clientSettingsMap = parseMap(client.getClientSettings());
|
||||
builder.clientSettings(ClientSettings.withSettings(clientSettingsMap).build());
|
||||
|
||||
Map<String, Object> tokenSettingsMap = parseMap(client.getTokenSettings());
|
||||
builder.tokenSettings(TokenSettings.withSettings(tokenSettingsMap).build());
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private Client toEntity(RegisteredClient registeredClient) {
|
||||
List<String> clientAuthenticationMethods = new ArrayList<>(registeredClient.getClientAuthenticationMethods().size());
|
||||
registeredClient.getClientAuthenticationMethods().forEach(clientAuthenticationMethod ->
|
||||
clientAuthenticationMethods.add(clientAuthenticationMethod.getValue()));
|
||||
|
||||
List<String> authorizationGrantTypes = new ArrayList<>(registeredClient.getAuthorizationGrantTypes().size());
|
||||
registeredClient.getAuthorizationGrantTypes().forEach(authorizationGrantType ->
|
||||
authorizationGrantTypes.add(authorizationGrantType.getValue()));
|
||||
|
||||
Client entity = new Client();
|
||||
entity.setId(registeredClient.getId());
|
||||
entity.setClientId(registeredClient.getClientId());
|
||||
entity.setClientIdIssuedAt(registeredClient.getClientIdIssuedAt());
|
||||
entity.setClientSecret(registeredClient.getClientSecret());
|
||||
entity.setClientSecretExpiresAt(registeredClient.getClientSecretExpiresAt());
|
||||
entity.setClientName(registeredClient.getClientName());
|
||||
entity.setClientAuthenticationMethods(StringUtils.collectionToCommaDelimitedString(clientAuthenticationMethods));
|
||||
entity.setAuthorizationGrantTypes(StringUtils.collectionToCommaDelimitedString(authorizationGrantTypes));
|
||||
entity.setRedirectUris(StringUtils.collectionToCommaDelimitedString(registeredClient.getRedirectUris()));
|
||||
entity.setScopes(StringUtils.collectionToCommaDelimitedString(registeredClient.getScopes()));
|
||||
entity.setClientSettings(writeMap(registeredClient.getClientSettings().getSettings()));
|
||||
entity.setTokenSettings(writeMap(registeredClient.getTokenSettings().getSettings()));
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private Map<String, Object> parseMap(String data) {
|
||||
try {
|
||||
return this.objectMapper.readValue(data, new TypeReference<>() {
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalArgumentException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private String writeMap(Map<String, Object> data) {
|
||||
try {
|
||||
return this.objectMapper.writeValueAsString(data);
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalArgumentException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static AuthorizationGrantType resolveAuthorizationGrantType(String authorizationGrantType) {
|
||||
if (AuthorizationGrantType.AUTHORIZATION_CODE.getValue().equals(authorizationGrantType)) {
|
||||
return AuthorizationGrantType.AUTHORIZATION_CODE;
|
||||
} else if (AuthorizationGrantType.CLIENT_CREDENTIALS.getValue().equals(authorizationGrantType)) {
|
||||
return AuthorizationGrantType.CLIENT_CREDENTIALS;
|
||||
} else if (AuthorizationGrantType.REFRESH_TOKEN.getValue().equals(authorizationGrantType)) {
|
||||
return AuthorizationGrantType.REFRESH_TOKEN;
|
||||
}
|
||||
return new AuthorizationGrantType(authorizationGrantType); // Custom authorization grant type
|
||||
}
|
||||
|
||||
private static ClientAuthenticationMethod resolveClientAuthenticationMethod(String clientAuthenticationMethod) {
|
||||
if (ClientAuthenticationMethod.CLIENT_SECRET_BASIC.getValue().equals(clientAuthenticationMethod)) {
|
||||
return ClientAuthenticationMethod.CLIENT_SECRET_BASIC;
|
||||
} else if (ClientAuthenticationMethod.CLIENT_SECRET_POST.getValue().equals(clientAuthenticationMethod)) {
|
||||
return ClientAuthenticationMethod.CLIENT_SECRET_POST;
|
||||
} else if (ClientAuthenticationMethod.NONE.getValue().equals(clientAuthenticationMethod)) {
|
||||
return ClientAuthenticationMethod.NONE;
|
||||
}
|
||||
return new ClientAuthenticationMethod(clientAuthenticationMethod); // Custom client authentication method
|
||||
}
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,6 @@
|
||||
server:
|
||||
port: 9000
|
||||
|
||||
logging:
|
||||
level:
|
||||
org.springframework.security: trace
|
||||
@@ -0,0 +1,6 @@
|
||||
CREATE TABLE authorizationConsent (
|
||||
registeredClientId varchar(255) NOT NULL,
|
||||
principalName varchar(255) NOT NULL,
|
||||
authorities varchar(1000) NOT NULL,
|
||||
PRIMARY KEY (registeredClientId, principalName)
|
||||
);
|
||||
@@ -0,0 +1,28 @@
|
||||
CREATE TABLE authorization (
|
||||
id varchar(255) NOT NULL,
|
||||
registeredClientId varchar(255) NOT NULL,
|
||||
principalName varchar(255) NOT NULL,
|
||||
authorizationGrantType varchar(255) NOT NULL,
|
||||
attributes varchar(4000) DEFAULT NULL,
|
||||
state varchar(500) DEFAULT NULL,
|
||||
authorizationCodeValue varchar(4000) DEFAULT NULL,
|
||||
authorizationCodeIssuedAt timestamp DEFAULT NULL,
|
||||
authorizationCodeExpiresAt timestamp DEFAULT NULL,
|
||||
authorizationCodeMetadata varchar(2000) DEFAULT NULL,
|
||||
accessTokenValue varchar(4000) DEFAULT NULL,
|
||||
accessTokenIssuedAt timestamp DEFAULT NULL,
|
||||
accessTokenExpiresAt timestamp DEFAULT NULL,
|
||||
accessTokenMetadata varchar(2000) DEFAULT NULL,
|
||||
accessTokenType varchar(255) DEFAULT NULL,
|
||||
accessTokenScopes varchar(1000) DEFAULT NULL,
|
||||
refreshTokenValue varchar(4000) DEFAULT NULL,
|
||||
refreshTokenIssuedAt timestamp DEFAULT NULL,
|
||||
refreshTokenExpiresAt timestamp DEFAULT NULL,
|
||||
refreshTokenMetadata varchar(2000) DEFAULT NULL,
|
||||
oidcIdTokenValue varchar(4000) DEFAULT NULL,
|
||||
oidcIdTokenIssuedAt timestamp DEFAULT NULL,
|
||||
oidcIdTokenExpiresAt timestamp DEFAULT NULL,
|
||||
oidcIdTokenMetadata varchar(2000) DEFAULT NULL,
|
||||
oidcIdTokenClaims varchar(2000) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
@@ -0,0 +1,15 @@
|
||||
CREATE TABLE client (
|
||||
id varchar(255) NOT NULL,
|
||||
clientId varchar(255) NOT NULL,
|
||||
clientIdIssuedAt timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
clientSecret varchar(255) DEFAULT NULL,
|
||||
clientSecretExpiresAt timestamp DEFAULT NULL,
|
||||
clientName varchar(255) NOT NULL,
|
||||
clientAuthenticationMethods varchar(1000) NOT NULL,
|
||||
authorizationGrantTypes varchar(1000) NOT NULL,
|
||||
redirectUris varchar(1000) DEFAULT NULL,
|
||||
scopes varchar(1000) NOT NULL,
|
||||
clientSettings varchar(2000) NOT NULL,
|
||||
tokenSettings varchar(2000) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
Reference in New Issue
Block a user