Add OpenID Connect 1.0 Logout Endpoint
Closes gh-266
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2022 the original author or authors.
|
||||
* Copyright 2020-2023 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.
|
||||
@@ -39,6 +39,8 @@ public class Client {
|
||||
@Column(length = 1000)
|
||||
private String redirectUris;
|
||||
@Column(length = 1000)
|
||||
private String postLogoutRedirectUris;
|
||||
@Column(length = 1000)
|
||||
private String scopes;
|
||||
@Column(length = 2000)
|
||||
private String clientSettings;
|
||||
@@ -118,6 +120,14 @@ public class Client {
|
||||
this.redirectUris = redirectUris;
|
||||
}
|
||||
|
||||
public String getPostLogoutRedirectUris() {
|
||||
return this.postLogoutRedirectUris;
|
||||
}
|
||||
|
||||
public void setPostLogoutRedirectUris(String postLogoutRedirectUris) {
|
||||
this.postLogoutRedirectUris = postLogoutRedirectUris;
|
||||
}
|
||||
|
||||
public String getScopes() {
|
||||
return scopes;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
* Copyright 2022-2023 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.
|
||||
@@ -30,10 +30,12 @@ public interface AuthorizationRepository extends JpaRepository<Authorization, St
|
||||
Optional<Authorization> findByAuthorizationCodeValue(String authorizationCode);
|
||||
Optional<Authorization> findByAccessTokenValue(String accessToken);
|
||||
Optional<Authorization> findByRefreshTokenValue(String refreshToken);
|
||||
Optional<Authorization> findByOidcIdTokenValue(String idToken);
|
||||
@Query("select a from Authorization a where a.state = :token" +
|
||||
" or a.authorizationCodeValue = :token" +
|
||||
" or a.accessTokenValue = :token" +
|
||||
" or a.refreshTokenValue = :token"
|
||||
" or a.refreshTokenValue = :token" +
|
||||
" or a.oidcIdTokenValue = :token"
|
||||
)
|
||||
Optional<Authorization> findByStateOrAuthorizationCodeValueOrAccessTokenValueOrRefreshTokenValue(@Param("token") String token);
|
||||
Optional<Authorization> findByStateOrAuthorizationCodeValueOrAccessTokenValueOrRefreshTokenValueOrOidcIdTokenValue(@Param("token") String token);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
* Copyright 2022-2023 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.
|
||||
@@ -35,6 +35,7 @@ import org.springframework.security.oauth2.core.OAuth2RefreshToken;
|
||||
import org.springframework.security.oauth2.core.OAuth2Token;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
|
||||
import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationCode;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
|
||||
@@ -88,7 +89,7 @@ public class JpaOAuth2AuthorizationService implements OAuth2AuthorizationService
|
||||
|
||||
Optional<Authorization> result;
|
||||
if (tokenType == null) {
|
||||
result = this.authorizationRepository.findByStateOrAuthorizationCodeValueOrAccessTokenValueOrRefreshTokenValue(token);
|
||||
result = this.authorizationRepository.findByStateOrAuthorizationCodeValueOrAccessTokenValueOrRefreshTokenValueOrOidcIdTokenValue(token);
|
||||
} else if (OAuth2ParameterNames.STATE.equals(tokenType.getValue())) {
|
||||
result = this.authorizationRepository.findByState(token);
|
||||
} else if (OAuth2ParameterNames.CODE.equals(tokenType.getValue())) {
|
||||
@@ -97,6 +98,8 @@ public class JpaOAuth2AuthorizationService implements OAuth2AuthorizationService
|
||||
result = this.authorizationRepository.findByAccessTokenValue(token);
|
||||
} else if (OAuth2ParameterNames.REFRESH_TOKEN.equals(tokenType.getValue())) {
|
||||
result = this.authorizationRepository.findByRefreshTokenValue(token);
|
||||
} else if (OidcParameterNames.ID_TOKEN.equals(tokenType.getValue())) {
|
||||
result = this.authorizationRepository.findByOidcIdTokenValue(token);
|
||||
} else {
|
||||
result = Optional.empty();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
* Copyright 2022-2023 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.
|
||||
@@ -78,6 +78,8 @@ public class JpaRegisteredClientRepository implements RegisteredClientRepository
|
||||
client.getAuthorizationGrantTypes());
|
||||
Set<String> redirectUris = StringUtils.commaDelimitedListToSet(
|
||||
client.getRedirectUris());
|
||||
Set<String> postLogoutRedirectUris = StringUtils.commaDelimitedListToSet(
|
||||
client.getPostLogoutRedirectUris());
|
||||
Set<String> clientScopes = StringUtils.commaDelimitedListToSet(
|
||||
client.getScopes());
|
||||
|
||||
@@ -94,6 +96,7 @@ public class JpaRegisteredClientRepository implements RegisteredClientRepository
|
||||
authorizationGrantTypes.forEach(grantType ->
|
||||
grantTypes.add(resolveAuthorizationGrantType(grantType))))
|
||||
.redirectUris((uris) -> uris.addAll(redirectUris))
|
||||
.postLogoutRedirectUris((uris) -> uris.addAll(postLogoutRedirectUris))
|
||||
.scopes((scopes) -> scopes.addAll(clientScopes));
|
||||
|
||||
Map<String, Object> clientSettingsMap = parseMap(client.getClientSettings());
|
||||
@@ -124,6 +127,7 @@ public class JpaRegisteredClientRepository implements RegisteredClientRepository
|
||||
entity.setClientAuthenticationMethods(StringUtils.collectionToCommaDelimitedString(clientAuthenticationMethods));
|
||||
entity.setAuthorizationGrantTypes(StringUtils.collectionToCommaDelimitedString(authorizationGrantTypes));
|
||||
entity.setRedirectUris(StringUtils.collectionToCommaDelimitedString(registeredClient.getRedirectUris()));
|
||||
entity.setPostLogoutRedirectUris(StringUtils.collectionToCommaDelimitedString(registeredClient.getPostLogoutRedirectUris()));
|
||||
entity.setScopes(StringUtils.collectionToCommaDelimitedString(registeredClient.getScopes()));
|
||||
entity.setClientSettings(writeMap(registeredClient.getClientSettings().getSettings()));
|
||||
entity.setTokenSettings(writeMap(registeredClient.getTokenSettings().getSettings()));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2022 the original author or authors.
|
||||
* Copyright 2020-2023 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.
|
||||
@@ -102,7 +102,8 @@ public class SecurityConfigTests {
|
||||
assertThatAuthorization(refreshToken, null).isNotNull();
|
||||
|
||||
String idToken = (String) tokenResponse.get(OidcParameterNames.ID_TOKEN);
|
||||
assertThatAuthorization(idToken, OidcParameterNames.ID_TOKEN).isNull(); // id_token is not searchable
|
||||
assertThatAuthorization(idToken, OidcParameterNames.ID_TOKEN).isNotNull();
|
||||
assertThatAuthorization(idToken, null).isNotNull();
|
||||
|
||||
OAuth2Authorization authorization = findAuthorization(accessToken, OAuth2ParameterNames.ACCESS_TOKEN);
|
||||
assertThat(authorization.getToken(idToken)).isNotNull();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2022 the original author or authors.
|
||||
* Copyright 2020-2023 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.
|
||||
@@ -117,7 +117,8 @@ public class JpaTests {
|
||||
assertThatAuthorization(refreshToken, null).isNotNull();
|
||||
|
||||
String idToken = (String) tokenResponse.get(OidcParameterNames.ID_TOKEN);
|
||||
assertThatAuthorization(idToken, OidcParameterNames.ID_TOKEN).isNull(); // id_token is not searchable
|
||||
assertThatAuthorization(idToken, OidcParameterNames.ID_TOKEN).isNotNull();
|
||||
assertThatAuthorization(idToken, null).isNotNull();
|
||||
|
||||
OAuth2Authorization authorization = findAuthorization(accessToken, OAuth2ParameterNames.ACCESS_TOKEN);
|
||||
assertThat(authorization.getToken(idToken)).isNotNull();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2022 the original author or authors.
|
||||
* Copyright 2020-2023 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.
|
||||
@@ -37,6 +37,7 @@ public class RegisteredClients {
|
||||
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
|
||||
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
|
||||
.redirectUri("http://127.0.0.1:8080/authorized")
|
||||
.postLogoutRedirectUri("http://127.0.0.1:8080/index")
|
||||
.scope(OidcScopes.OPENID)
|
||||
.scope("message.read")
|
||||
.scope("message.write")
|
||||
|
||||
@@ -45,6 +45,7 @@ CREATE TABLE client (
|
||||
clientAuthenticationMethods varchar(1000) NOT NULL,
|
||||
authorizationGrantTypes varchar(1000) NOT NULL,
|
||||
redirectUris varchar(1000) DEFAULT NULL,
|
||||
postLogoutRedirectUris varchar(1000) DEFAULT NULL,
|
||||
scopes varchar(1000) NOT NULL,
|
||||
clientSettings varchar(2000) NOT NULL,
|
||||
tokenSettings varchar(2000) NOT NULL,
|
||||
|
||||
Reference in New Issue
Block a user