Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
/*
* Copyright 2025 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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
*
* http://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 org.keycloak.protocol.oid4vc.model;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;

import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.util.Strings;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

import static org.keycloak.util.JsonSerialization.valueAsString;

/**
* The OID4VCI Authorization Request
*
* https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html
*
* @author <a href="mailto:tdiesler@ibm.com">Thomas Diesler</a>
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AuthorizationRequest {

// ===== Standard OIDC Parameters ======================================================

@JsonProperty("client_id")
private String clientId;

@JsonProperty("redirect_uri")
private String redirectUri;

@JsonProperty("response_type")
private String responseType;

@JsonProperty("response_mode")
private String responseMode;

@JsonProperty("request")
private String request;

@JsonProperty("request_uri")
private String requestUri;

@JsonProperty("response_uri")
private String responseUri;

@JsonProperty("scope")
private String scope;

@JsonProperty("code_challenge")
private String codeChallenge;

@JsonProperty("code_challenge_method")
private String codeChallengeMethod;

@JsonProperty("nonce")
private String nonce;

@JsonProperty("state")
private String state;

// ===== OIDC4VCI Fields ===============================================================

@JsonProperty("authorization_details")
private List<OID4VCAuthorizationDetail> authorizationDetails;

@JsonProperty("issuer_state")
private String issuerState;

// =====================================================================================
// Serialization support
// =====================================================================================

public Map<String, List<String>> toRequestParameters() {

Map<String, List<String>> params = new LinkedHashMap<>();
BiConsumer<String, String> add = (k, v) -> {
if (!Strings.isEmpty(v)) params.put(k, List.of(v));
};

add.accept("client_id", clientId);
add.accept("redirect_uri", redirectUri);
add.accept("response_type", responseType);
add.accept("response_mode", responseMode);
add.accept("request", request);
add.accept("request_uri", requestUri);
add.accept("response_uri", responseUri);
add.accept("scope", scope);
add.accept("nonce", nonce);
add.accept("state", state);
add.accept("issuer_state", issuerState);
add.accept("code_challenge", codeChallenge);
add.accept("code_challenge_method", codeChallengeMethod);

if (authorizationDetails != null) {
add.accept("authorization_details", valueAsString(authorizationDetails));
}

return params;
}

public String toRequestUrl(String endpointUri) {
Map<String, List<String>> params = toRequestParameters();
KeycloakUriBuilder b = KeycloakUriBuilder.fromUri(endpointUri, false);
params.forEach((k, lst) -> b.queryParam(k, lst.toArray()));
return b.build().toString();
}

// Getter/Setter ---------------------------------------------------------------------------------------------------

public String getClientId() {
return clientId;
}

public AuthorizationRequest setClientId(String clientId) {
this.clientId = clientId;
return this;
}

public String getRedirectUri() {
return redirectUri;
}

public AuthorizationRequest setRedirectUri(String redirectUri) {
this.redirectUri = redirectUri;
return this;
}

public String getResponseType() {
return responseType;
}

public AuthorizationRequest setResponseType(String responseType) {
this.responseType = responseType;
return this;
}

public String getResponseMode() {
return responseMode;
}

public AuthorizationRequest setResponseMode(String responseMode) {
this.responseMode = responseMode;
return this;
}

public String getRequest() {
return request;
}

public AuthorizationRequest setRequest(String request) {
this.request = request;
return this;
}

public String getRequestUri() {
return requestUri;
}

public AuthorizationRequest setRequestUri(String requestUri) {
this.requestUri = requestUri;
return this;
}

public String getResponseUri() {
return responseUri;
}

public AuthorizationRequest setResponseUri(String responseUri) {
this.responseUri = responseUri;
return this;
}

public String getScope() {
return scope;
}

public AuthorizationRequest setScope(String scope) {
this.scope = scope;
return this;
}

public String getNonce() {
return nonce;
}

public AuthorizationRequest setNonce(String nonce) {
this.nonce = nonce;
return this;
}

public String getState() {
return state;
}

public AuthorizationRequest setState(String clientState) {
this.state = clientState;
return this;
}

public String getIssuerState() {
return issuerState;
}

public AuthorizationRequest setIssuerState(String issuerState) {
this.issuerState = issuerState;
return this;
}

public String getCodeChallenge() {
return codeChallenge;
}

public AuthorizationRequest setCodeChallenge(String codeChallenge) {
this.codeChallenge = codeChallenge;
return this;
}

public String getCodeChallengeMethod() {
return codeChallengeMethod;
}

public AuthorizationRequest setCodeChallengeMethod(String codeChallengeMethod) {
this.codeChallengeMethod = codeChallengeMethod;
return this;
}

public List<OID4VCAuthorizationDetail> getAuthorizationDetails() {
return authorizationDetails;
}

public AuthorizationRequest setAuthorizationDetails(List<OID4VCAuthorizationDetail> authorizationDetails) {
this.authorizationDetails = authorizationDetails;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.keycloak.testsuite.util.oauth;
package org.keycloak.protocol.oidc.utils;

import org.keycloak.OAuth2Constants;
import org.keycloak.protocol.oidc.utils.PkceUtils;

public class PkceGenerator {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import org.keycloak.OAuth2Constants;
import org.keycloak.protocol.oid4vc.model.OID4VCAuthorizationDetail;
import org.keycloak.protocol.oidc.utils.PkceGenerator;
import org.keycloak.util.JsonSerialization;
import org.keycloak.util.TokenUtil;

Expand Down
Loading
Loading