Use account-console client for server-side auth check
- Also generate PKCE verifier and use challenge parameters Signed-off-by: Thomas Darimont <thomas.darimont@googlemail.com>
This commit is contained in:
parent
6a4ec24015
commit
729417b20a
3 changed files with 27 additions and 1 deletions
|
@ -42,6 +42,7 @@ public class AbstractOAuthClient {
|
||||||
protected String stateCookiePath;
|
protected String stateCookiePath;
|
||||||
protected boolean isSecure;
|
protected boolean isSecure;
|
||||||
protected boolean publicClient;
|
protected boolean publicClient;
|
||||||
|
protected boolean pkceEnabled;
|
||||||
protected String getStateCode() {
|
protected String getStateCode() {
|
||||||
return counter.getAndIncrement() + "/" + UUID.randomUUID().toString();
|
return counter.getAndIncrement() + "/" + UUID.randomUUID().toString();
|
||||||
}
|
}
|
||||||
|
@ -126,6 +127,14 @@ public class AbstractOAuthClient {
|
||||||
this.relativeUrlsUsed = relativeUrlsUsed;
|
this.relativeUrlsUsed = relativeUrlsUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPkceEnabled() {
|
||||||
|
return pkceEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPkceEnabled(boolean pkceEnabled) {
|
||||||
|
this.pkceEnabled = pkceEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
protected String stripOauthParametersFromRedirect(String uri) {
|
protected String stripOauthParametersFromRedirect(String uri) {
|
||||||
KeycloakUriBuilder builder = KeycloakUriBuilder.fromUri(uri)
|
KeycloakUriBuilder builder = KeycloakUriBuilder.fromUri(uri)
|
||||||
.replaceQueryParam(OAuth2Constants.CODE, null)
|
.replaceQueryParam(OAuth2Constants.CODE, null)
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
|
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
|
||||||
|
import org.keycloak.protocol.oidc.utils.PkceUtils;
|
||||||
import org.keycloak.services.managers.Auth;
|
import org.keycloak.services.managers.Auth;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.util.TokenUtil;
|
import org.keycloak.util.TokenUtil;
|
||||||
|
@ -44,6 +45,7 @@ import jakarta.ws.rs.core.UriBuilder;
|
||||||
import jakarta.ws.rs.core.UriInfo;
|
import jakarta.ws.rs.core.UriInfo;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class for securing local services. Provides login basics as well as CSRF check basics
|
* Helper class for securing local services. Provides login basics as well as CSRF check basics
|
||||||
|
@ -180,6 +182,20 @@ public abstract class AbstractSecuredLocalService {
|
||||||
.queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE)
|
.queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE)
|
||||||
.queryParam(OAuth2Constants.SCOPE, scopeParam);
|
.queryParam(OAuth2Constants.SCOPE, scopeParam);
|
||||||
|
|
||||||
|
if (isPkceEnabled()) {
|
||||||
|
String pkceChallenge;
|
||||||
|
try {
|
||||||
|
// TODO generate PKCE challenge based on server value
|
||||||
|
String codeVerifier = UUID.randomUUID().toString();
|
||||||
|
pkceChallenge = PkceUtils.generateS256CodeChallenge(codeVerifier);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
uriBuilder
|
||||||
|
.queryParam(OAuth2Constants.CODE_CHALLENGE, pkceChallenge)
|
||||||
|
.queryParam(OAuth2Constants.CODE_CHALLENGE_METHOD, OAuth2Constants.PKCE_METHOD_S256);
|
||||||
|
}
|
||||||
|
|
||||||
URI url = uriBuilder.build();
|
URI url = uriBuilder.build();
|
||||||
|
|
||||||
NewCookie cookie = new NewCookie(getStateCookieName(), state, getStateCookiePath(uriInfo), null, null, -1, isSecure, true);
|
NewCookie cookie = new NewCookie(getStateCookieName(), state, getStateCookiePath(uriInfo), null, null, -1, isSecure, true);
|
||||||
|
|
|
@ -215,7 +215,8 @@ public class AccountConsole implements AccountResourceProvider {
|
||||||
|
|
||||||
var oauthRedirect = new AbstractSecuredLocalService.OAuthRedirect();
|
var oauthRedirect = new AbstractSecuredLocalService.OAuthRedirect();
|
||||||
oauthRedirect.setAuthUrl(OIDCLoginProtocolService.authUrl(session.getContext().getUri()).build(realm.getName()).toString());
|
oauthRedirect.setAuthUrl(OIDCLoginProtocolService.authUrl(session.getContext().getUri()).build(realm.getName()).toString());
|
||||||
oauthRedirect.setClientId(client.getClientId());
|
oauthRedirect.setClientId(Constants.ACCOUNT_CONSOLE_CLIENT_ID);
|
||||||
|
oauthRedirect.setPkceEnabled(true);
|
||||||
oauthRedirect.setSecure(realm.getSslRequired().isRequired(session.getContext().getConnection()));
|
oauthRedirect.setSecure(realm.getSslRequired().isRequired(session.getContext().getConnection()));
|
||||||
return oauthRedirect.redirect(session.getContext().getUri(), targetUri.toString());
|
return oauthRedirect.redirect(session.getContext().getUri(), targetUri.toString());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue