[java-oidc-common] branch main updated: JCOMOIDC-175 - Add Generalised POST Request Encoder

Codeberg noreply at shibboleth.net
Fri Jul 3 10:18:03 UTC 2026


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch main
in repository java-oidc-common.

View the commit online:
https://codeberg.org/Shibboleth/java-oidc-common/commit/c85f447ad4c5fc3ac4edf9562a1874a319a17b82

The following commit(s) were added to refs/heads/main by this push:
     new c85f447a JCOMOIDC-175 - Add Generalised POST Request Encoder
c85f447a is described below

commit c85f447ad4c5fc3ac4edf9562a1874a319a17b82
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Fri Jul 3 11:17:52 2026 +0100

    JCOMOIDC-175 - Add Generalised POST Request Encoder
    
     - Added generalised POST encoder
     - Deprecated existing authentication specific encoder
     - Add logout request params to the test POST template
    
    https://shibboleth.atlassian.net/browse/JCOMOIDC-175
---
 .../encoding/impl/AbstractOIDCMessageEncoder.java  |   2 +-
 .../encoding/impl/HTTPPostAuthnRequestEncoder.java |   4 +
 ...estEncoder.java => HTTPPostRequestEncoder.java} |  70 +++++++---
 .../impl/HTTPRedirectAuthnRequestEncoder.java      |   3 +-
 ...erTest.java => HTTPPostRequestEncoderTest.java} | 141 ++++++++++++++-------
 .../impl/HTTPRedirectRequestEncoderTest.java       |  15 ++-
 .../resources/templates/oidc-request-form-post.vm  |   9 +-
 7 files changed, 179 insertions(+), 65 deletions(-)

diff --git a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/AbstractOIDCMessageEncoder.java b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/AbstractOIDCMessageEncoder.java
index 810dafb1..fc46b040 100644
--- a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/AbstractOIDCMessageEncoder.java
+++ b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/AbstractOIDCMessageEncoder.java
@@ -63,7 +63,7 @@ public abstract class AbstractOIDCMessageEncoder extends AbstractHttpServletResp
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(AbstractOIDCMessageEncoder.class);
     
-    /** A hook to allow additional checking of the authorization parameters after it is built.*/
+    /** A hook to allow additional checking of the authorization parameters after they are built.*/
     @Nonnull private Predicate<List<Pair<String, String>>> authorizationParamsAreValidPredicate;
     
     /** Constructor. */
diff --git a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/HTTPPostAuthnRequestEncoder.java b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/HTTPPostAuthnRequestEncoder.java
index cd1bd4d1..3b485c0e 100644
--- a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/HTTPPostAuthnRequestEncoder.java
+++ b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/HTTPPostAuthnRequestEncoder.java
@@ -45,7 +45,10 @@ import net.shibboleth.shared.servlet.HttpServletSupport;
 /**
  * A {@link MessageEncoder message encoder} that encodes an OpenID authentication request by
  * HTTP Form POST Serialization.
+ * 
+ * @deprecated Use {@link HTTPPostRequestEncoder}, which now handles both authentication and logout requests.
  */
+ at Deprecated(since="3.4.0", forRemoval=true)
 public class HTTPPostAuthnRequestEncoder extends AbstractOIDCMessageEncoder {
     
     /** Default template ID for using FORM POST request type. */
@@ -116,6 +119,7 @@ public class HTTPPostAuthnRequestEncoder extends AbstractOIDCMessageEncoder {
     }
 
     /** {@inheritDoc} */
+    @Override
     public boolean test(@Nullable final HttpRequestMethod requestMethod) {
        return HttpRequestMethod.POST.equals(requestMethod);
     }   
diff --git a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/HTTPPostAuthnRequestEncoder.java b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/HTTPPostRequestEncoder.java
similarity index 74%
copy from oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/HTTPPostAuthnRequestEncoder.java
copy to oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/HTTPPostRequestEncoder.java
index cd1bd4d1..8b8bb33f 100644
--- a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/HTTPPostAuthnRequestEncoder.java
+++ b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/HTTPPostRequestEncoder.java
@@ -32,6 +32,7 @@ import org.slf4j.Logger;
 
 import jakarta.servlet.http.HttpServletResponse;
 import net.shibboleth.oidc.profile.core.OIDCAuthenticationRequest;
+import net.shibboleth.oidc.profile.core.OIDCLogoutRequest;
 import net.shibboleth.oidc.profile.oauth2.config.OAuth2AuthorizationProfileConfiguration.HttpRequestMethod;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.codec.HTMLEncoder;
@@ -43,16 +44,16 @@ import net.shibboleth.shared.security.IdentifierGenerationStrategy;
 import net.shibboleth.shared.servlet.HttpServletSupport;
 
 /**
- * A {@link MessageEncoder message encoder} that encodes an OpenID authentication request by
+ * A {@link MessageEncoder message encoder} that encodes an OpenID authentication or logout request by
  * HTTP Form POST Serialization.
  */
-public class HTTPPostAuthnRequestEncoder extends AbstractOIDCMessageEncoder {
+public class HTTPPostRequestEncoder extends AbstractOIDCMessageEncoder {
     
-    /** Default template ID for using FORM POST request type. */
+    /** Default template ID for using FORM POST request type for authentication or logout. */
     @Nonnull @NotEmpty public static final String DEFAULT_TEMPLATE_ID = "/templates/oidc-request-form-post.vm";
     
     /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(HTTPPostAuthnRequestEncoder.class);
+    @Nonnull private final Logger log = LoggerFactory.getLogger(HTTPPostRequestEncoder.class);
     
     /** Velocity engine used to evaluate the template when using FORM POST response mode. */
     @Nullable private VelocityEngine velocityEngine;
@@ -116,12 +117,13 @@ public class HTTPPostAuthnRequestEncoder extends AbstractOIDCMessageEncoder {
     }
 
     /** {@inheritDoc} */
+    @Override
     public boolean test(@Nullable final HttpRequestMethod requestMethod) {
        return HttpRequestMethod.POST.equals(requestMethod);
     }   
     
     /**
-     * Construct form POST.
+     * Construct form POST for an authentication request.
      * 
      * @param request the authentication request.
      * @param httpResponse the httpResponse.
@@ -132,13 +134,46 @@ public class HTTPPostAuthnRequestEncoder extends AbstractOIDCMessageEncoder {
     private VelocityContext doPostEncode(@Nonnull final OIDCAuthenticationRequest request, 
             @Nonnull final HttpServletResponse httpResponse) throws MessageEncodingException {
         
-        final VelocityContext context = new VelocityContext();
-        final List<Pair<String, String>> params = createParametersFromRequest(request);
-        params.forEach(param -> context.put(param.getFirst(),HTMLEncoder.encodeForHTML(param.getSecond())));
+        final List<Pair<String, String>> params = createParametersFromRequest(request);        
         final URI endpoint = request.getEndpointURI();
         if (endpoint == null) {
             throw new MessageEncodingException("Endpoint URI for form action is null.");
         }
+        return createContext(endpoint, params, httpResponse);
+    }
+    
+    /**
+     * Construct form POST for a logout request.
+     * 
+     * @param request the logout request.
+     * @param httpResponse the httpResponse.
+     * @return response message as velocity context.
+     * 
+     * @throws MessageEncodingException on error building the parameters
+     */
+    private VelocityContext doPostEncode(@Nonnull final OIDCLogoutRequest request, 
+            @Nonnull final HttpServletResponse httpResponse) throws MessageEncodingException {        
+        
+        final List<Pair<String, String>> params = createParametersFromRequest(request);        
+        final URI endpoint = request.getLogoutEndpoint();
+        return createContext(endpoint, params, httpResponse);
+    } 
+    
+    /**
+     * Create a Velocity context and encode the response parameters into the context. 
+     * 
+     * @param endpoint the URL to add to the form action
+     * @param params the parameters to encode in the context
+     * @param httpResponse the HTTP response to use
+     * 
+     * @return the populated Velocity context
+     */
+    private VelocityContext createContext(@Nonnull final URI endpoint, @Nonnull final List<Pair<String, String>> params, 
+            @Nonnull final HttpServletResponse httpResponse) {
+        
+        final VelocityContext context = new VelocityContext();
+        params.forEach(param -> context.put(param.getFirst(),HTMLEncoder.encodeForHTML(param.getSecond())));        
+        
         context.put("response", httpResponse);
         if (cspDigester != null) {
             context.put("cspDigester", cspDigester);
@@ -149,7 +184,7 @@ public class HTTPPostAuthnRequestEncoder extends AbstractOIDCMessageEncoder {
         context.put("action", HTMLEncoder.encodeForHTMLAttribute(endpoint.toString()));
         log.trace("Velocity context OIDC parameters: {}", params);
         return context;
-    }    
+    }
 
     /** {@inheritDoc} */
     @Override
@@ -161,11 +196,7 @@ public class HTTPPostAuthnRequestEncoder extends AbstractOIDCMessageEncoder {
         
         log.debug("Encoding OIDC authentication request using HTTP Form Post Serialization");
         final MessageContext messageContext = getMessageContext();
-        final Object outboundMessage = messageContext.getMessage();
-        if (!(outboundMessage instanceof OIDCAuthenticationRequest)) {
-            throw new MessageEncodingException("No outbound OIDC authentication request message "
-                    + "contained in message context.");
-        }
+        final Object outboundMessage = messageContext.getMessage();        
         
         final HttpServletResponse response = getHttpServletResponse();
         if (response == null) {
@@ -176,7 +207,16 @@ public class HTTPPostAuthnRequestEncoder extends AbstractOIDCMessageEncoder {
             HttpServletSupport.addNoCacheHeaders(response);
             HttpServletSupport.setUTF8Encoding(response);
             HttpServletSupport.setContentType(response, "text/html");
-            final VelocityContext context = doPostEncode((OIDCAuthenticationRequest) outboundMessage, response);
+            
+            VelocityContext context;
+            if (outboundMessage instanceof final OIDCAuthenticationRequest authnRequest) {                
+                context = doPostEncode(authnRequest, response);
+            } else if (outboundMessage instanceof final OIDCLogoutRequest logoutRequest) {
+                context = doPostEncode(logoutRequest, response);
+            } else {
+                throw new MessageEncodingException("Unsupported OIDC authentication request message "
+                        + "contained in message context.");
+            }
             try (final Writer out = new OutputStreamWriter(response.getOutputStream(), StandardCharsets.UTF_8)) {
                 assert velocityEngine != null;
                 velocityEngine.mergeTemplate(velocityTemplateId, "UTF-8", context, out);
diff --git a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/HTTPRedirectAuthnRequestEncoder.java b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/HTTPRedirectAuthnRequestEncoder.java
index df58759d..fa7bdb6c 100644
--- a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/HTTPRedirectAuthnRequestEncoder.java
+++ b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/encoding/impl/HTTPRedirectAuthnRequestEncoder.java
@@ -37,8 +37,7 @@ import net.shibboleth.shared.servlet.HttpServletSupport;
  * A {@link MessageEncoder message encoder} that encodes an OpenID authentication request by 
  * Query String Serialization and sends a HTTP redirect response.
  * 
- * @deprecated The redirect encoder has been combined for both authentication and logout request in the 
- *              {@link HTTPRedirectRequestEncoder}.
+ * @deprecated Use {@link HTTPRedirectRequestEncoder}, which now handles both authentication and logout requests.
  */
 //TODO maybe this could encode authz responses as well? to replace the NimbusResponseEncoder
 @Deprecated(since="3.4.0", forRemoval=true)
diff --git a/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/encoding/impl/HTTPRedirectRequestEncoderTest.java b/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/encoding/impl/HTTPPostRequestEncoderTest.java
similarity index 68%
copy from oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/encoding/impl/HTTPRedirectRequestEncoderTest.java
copy to oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/encoding/impl/HTTPPostRequestEncoderTest.java
index 0d0f1e8f..66599ace 100644
--- a/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/encoding/impl/HTTPRedirectRequestEncoderTest.java
+++ b/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/encoding/impl/HTTPPostRequestEncoderTest.java
@@ -14,11 +14,10 @@
 
 package net.shibboleth.oidc.profile.encoding.impl;
 
+import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
 import java.net.URI;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
 import java.time.Instant;
 import java.util.Date;
 import java.util.List;
@@ -45,43 +44,50 @@ import com.nimbusds.oauth2.sdk.ResponseType;
 import com.nimbusds.oauth2.sdk.id.ClientID;
 import com.nimbusds.oauth2.sdk.id.State;
 import com.nimbusds.openid.connect.sdk.OIDCClaimsRequest;
-import com.nimbusds.openid.connect.sdk.assurance.claims.VerifiedClaimsSetRequest;
+import com.nimbusds.openid.connect.sdk.assurance.request.VerifiedClaimsSetRequest;
 
 import net.shibboleth.oidc.profile.core.OIDCAuthenticationRequest;
 import net.shibboleth.oidc.profile.core.OIDCLogoutRequest;
+import net.shibboleth.shared.codec.HTMLEncoder;
+import net.shibboleth.shared.codec.StringDigester;
+import net.shibboleth.shared.codec.StringDigester.OutputFormat;
 import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.UninitializedComponentException;
 import net.shibboleth.shared.servlet.impl.HttpServletRequestResponseContext;
 import net.shibboleth.shared.servlet.impl.ThreadLocalHttpServletResponseSupplier;
+import net.shibboleth.shared.testing.VelocityEngine;
 
-/** Test for the HTTPRedirectRequestEncoder.*/
+
+/** Test for the HTTPPostRequestEncoder.*/
 @SuppressWarnings("javadoc")
-public class HTTPRedirectRequestEncoderTest {
+public class HTTPPostRequestEncoderTest {
     
+    /** A client secret.*/
     private static final String CLIENT_SECRET = "Xp2s5v8y/B?E(H+MbQeThWmYq3t6w9z$";
     
-    /** The encoder to test.*/
-    private HTTPRedirectRequestEncoder encoder;
-    
     /** Mock servlet response.*/
     private MockHttpServletResponse mockResponse;
     
-    /** The OAuth authentication request.*/
+    /** The encoder to test.*/
+    private HTTPPostRequestEncoder encoder;
+    
+    /** The OAuth 2.0 authentication request.*/
     private OIDCAuthenticationRequest request;
     
     /** The OIDC logout request.*/
     private OIDCLogoutRequest logoutRequest;
     
-    /** The Message context.*/
+    /** The message context.*/
     private MessageContext context;
     
     
     @SuppressWarnings("null")
     @BeforeMethod public void setUp() throws Exception {    
-        encoder = new HTTPRedirectRequestEncoder();      
+        encoder = new HTTPPostRequestEncoder();      
         context = new MessageContext();
-        request = new OIDCAuthenticationRequest(new ClientID("clientID"));
-        // Create an authentication request: This needs to be dynamic
+        
+        // Create an authentication request
+        request = new OIDCAuthenticationRequest(new ClientID("clientID"));        
         request.setResponseType(ResponseType.CODE);
         request.setEndpointURI(new URI("https://somewhere.com/oauth2/authz"));
         request.setRedirectURI(new URI("https://localhost:8080/callback"));
@@ -91,6 +97,7 @@ public class HTTPRedirectRequestEncoderTest {
         logoutRequest.setClientID(new ClientID("clientID"));
         
         encoder.setMessageContext(context);
+        encoder.setVelocityEngine(VelocityEngine.newVelocityEngine());
         mockResponse = new MockHttpServletResponse();
         encoder.setHttpServletResponseSupplier(new ThreadLocalHttpServletResponseSupplier());
 
@@ -98,6 +105,11 @@ public class HTTPRedirectRequestEncoderTest {
     	HttpServletRequestResponseContext.loadCurrent(new MockHttpServletRequest(), mockResponse);
     }
     
+    /**
+     * Create a set of claims suitable for an ID Token.
+     * 
+     * @return the claims
+     */
     private JWTClaimsSet createClaims() {
         return new JWTClaimsSet.Builder()
                 .issuer("https://localhost:9918")
@@ -110,6 +122,13 @@ public class HTTPRedirectRequestEncoderTest {
                 .build();
     }
     
+    /** 
+     * Create a signed JWT.
+     * 
+     * @return a signed JWT
+     * @throws KeyLengthException on error
+     * @throws JOSEException on error
+     */
     private SignedJWT createdSignedJWT() throws KeyLengthException, JOSEException {        
         final var header = new JWSHeader.Builder(JWSAlgorithm.HS256)
                 .type(JOSEObjectType.JWT)
@@ -121,17 +140,37 @@ public class HTTPRedirectRequestEncoderTest {
     }
     
     @Test
-    public void testSuccesfullEncoding() throws Exception {
+    public void testSuccesfullEncoding_WithClaims() throws Exception {
         context.setMessage(request);
+        
+        final OIDCClaimsRequest requestedClaims =  new OIDCClaimsRequest()
+                .withIDTokenClaimsRequest(new VerifiedClaimsSetRequest().add("given_name"))
+                .withUserInfoClaimsRequest(new VerifiedClaimsSetRequest().add("family_name"));
+        request.setRequestedClaims(requestedClaims);
+        request.setProviderSupportsClaimsParameter(true);
+        
         encoder.initialize();
         encoder.encode();
-        final String response = mockResponse.getRedirectedUrl();
-        assert response != null;
+        final String response = mockResponse.getContentAsString();
+        assertNotNull(response);
         // These are all required
         assertTrue(response.contains("client_id"));
         assertTrue(response.contains("response_type"));
         assertTrue(response.contains("client_id"));
         assertTrue(response.contains("scope"));
+        assertTrue(response.contains("claims"));
+       
+    }
+    
+    @Test
+    public void testSuccesfullLogoutEncoding() throws Exception {
+        context.setMessage(logoutRequest);
+        encoder.initialize();
+        encoder.encode();
+        final String response = mockResponse.getContentAsString();
+        assertNotNull(response);
+        assertTrue(response.contains(HTMLEncoder.encodeForHTML("https://somewhere.com/end-session")));
+        assertTrue(response.contains("client_id"));
        
     }
     
@@ -141,12 +180,11 @@ public class HTTPRedirectRequestEncoderTest {
         context.setMessage(logoutRequest);
         encoder.initialize();
         encoder.encode();
-        final String response = mockResponse.getRedirectedUrl();
+        final String response = mockResponse.getContentAsString();
         assert response != null;
-        assertTrue(response.contains("https://somewhere.com/end-session"));
+        assertTrue(response.contains(HTMLEncoder.encodeForHTML("https://somewhere.com/end-session")));
         assertTrue(response.contains("client_id"));
-        assertTrue(response.contains(URLEncoder.encode("https://localhost:8080/end-session-callback",
-                StandardCharsets.UTF_8)));   
+        assertTrue(response.contains(HTMLEncoder.encodeForHTML("https://localhost:8080/end-session-callback")));   
     }
     
     @Test
@@ -156,9 +194,9 @@ public class HTTPRedirectRequestEncoderTest {
         context.setMessage(logoutRequest);
         encoder.initialize();
         encoder.encode();
-        final String response = mockResponse.getRedirectedUrl();
+        final String response = mockResponse.getContentAsString();
         assert response != null;
-        assertTrue(response.contains("https://somewhere.com/end-session"));
+        assertTrue(response.contains(HTMLEncoder.encodeForHTML("https://somewhere.com/end-session")));
         assertTrue(response.contains("client_id"));
         assertTrue(response.contains(idToken.serialize()));   
     }
@@ -169,9 +207,9 @@ public class HTTPRedirectRequestEncoderTest {
         context.setMessage(logoutRequest);
         encoder.initialize();
         encoder.encode();
-        final String response = mockResponse.getRedirectedUrl();
+        final String response = mockResponse.getContentAsString();
         assert response != null;
-        assertTrue(response.contains("https://somewhere.com/end-session"));
+        assertTrue(response.contains(HTMLEncoder.encodeForHTML("https://somewhere.com/end-session")));
         assertTrue(response.contains("client_id"));
         assertTrue(response.contains("hint"));   
     }
@@ -182,11 +220,11 @@ public class HTTPRedirectRequestEncoderTest {
         context.setMessage(logoutRequest);
         encoder.initialize();
         encoder.encode();
-        final String response = mockResponse.getRedirectedUrl();
+        final String response = mockResponse.getContentAsString();
         assert response != null;
-        assertTrue(response.contains("https://somewhere.com/end-session"));
+        assertTrue(response.contains(HTMLEncoder.encodeForHTML("https://somewhere.com/end-session")));
         assertTrue(response.contains("client_id"));
-        //assertTrue(response.contains("hint"));   
+        assertTrue(response.contains("ui_locales"));   
     }
     
     @Test
@@ -195,37 +233,35 @@ public class HTTPRedirectRequestEncoderTest {
         context.setMessage(logoutRequest);
         encoder.initialize();
         encoder.encode();
-        final String response = mockResponse.getRedirectedUrl();
+        final String response = mockResponse.getContentAsString();
         assert response != null;
-        assertTrue(response.contains("https://somewhere.com/end-session"));
+        assertTrue(response.contains(HTMLEncoder.encodeForHTML("https://somewhere.com/end-session")));
         assertTrue(response.contains("client_id"));
         assertTrue(response.contains("state"));   
     }
     
     @Test
-    public void testSuccesfullLogoutRequestEncoding() throws Exception {
-        context.setMessage(logoutRequest);
-        encoder.initialize();
-        encoder.encode();
-        final String response = mockResponse.getRedirectedUrl();
-        assert response != null;
-        assertTrue(response.contains("https://somewhere.com/end-session"));
-        assertTrue(response.contains("client_id"));       
-    }
-    
-    @Test
-    public void testSuccesfullEncoding_WithClaims() throws Exception {
+    public void testSuccesfullEncoding_WithClaims_And_CspComputed() throws Exception {
         context.setMessage(request);
+        
         final OIDCClaimsRequest requestedClaims =  new OIDCClaimsRequest()
                 .withIDTokenClaimsRequest(new VerifiedClaimsSetRequest().add("given_name"))
                 .withUserInfoClaimsRequest(new VerifiedClaimsSetRequest().add("family_name"));
         request.setRequestedClaims(requestedClaims);
         request.setProviderSupportsClaimsParameter(true);
         
+        encoder.setCSPDigester(new StringDigester("SHA-256", OutputFormat.HEX_LOWER));
+        
         encoder.initialize();
         encoder.encode();
-        final String response = mockResponse.getRedirectedUrl();
-        assert response != null;
+        final String response = mockResponse.getContentAsString();
+        assertNotNull(response);
+        
+        final String csp = mockResponse.getHeader("Content-Security-Policy");
+        assertNotNull(csp);
+        assertTrue(csp != null && 
+                csp.contains("script-src-attr 'unsafe-hashes' 'sha256-78f9e25449128af5ff73b5d604669faa1f2d4a9891aca8aa61ea9b1bb3754ce1"));
+        
         // These are all required
         assertTrue(response.contains("client_id"));
         assertTrue(response.contains("response_type"));
@@ -238,6 +274,7 @@ public class HTTPRedirectRequestEncoderTest {
     @Test
     public void testSuccesfullEncoding_WithRequestObject() throws Exception {
         context.setMessage(request);
+
     	request.setRequestObject(new PlainJWT(new JWTClaimsSet.Builder()
     			.claim("response_type", "code")
     			.claim("redirect_uri","https://localhost:8080/callback")
@@ -247,8 +284,8 @@ public class HTTPRedirectRequestEncoderTest {
         
         encoder.initialize();
         encoder.encode();
-        final String response = mockResponse.getRedirectedUrl();
-        assert response != null;
+        final String response = mockResponse.getContentAsString();
+        assertNotNull(response);
         // These are all required
         assertTrue(response.contains("client_id"));
         assertTrue(response.contains("response_type"));
@@ -256,6 +293,20 @@ public class HTTPRedirectRequestEncoderTest {
         assertTrue(response.contains("scope"));       
     }
     
+    @Test
+    public void testSuccesfullEncoding() throws Exception {
+        context.setMessage(request);
+        encoder.initialize();
+        encoder.encode();
+        final String response = mockResponse.getContentAsString();
+        assertNotNull(response);
+        // These are all required
+        assertTrue(response.contains("client_id"));
+        assertTrue(response.contains("response_type"));
+        assertTrue(response.contains("client_id"));
+        assertTrue(response.contains("scope"));
+    }
+    
     @Test(expectedExceptions = UninitializedComponentException.class)
     public void testUninitialized() throws MessageEncodingException {
         context.setMessage(request);
diff --git a/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/encoding/impl/HTTPRedirectRequestEncoderTest.java b/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/encoding/impl/HTTPRedirectRequestEncoderTest.java
index 0d0f1e8f..604a8f3b 100644
--- a/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/encoding/impl/HTTPRedirectRequestEncoderTest.java
+++ b/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/encoding/impl/HTTPRedirectRequestEncoderTest.java
@@ -58,6 +58,7 @@ import net.shibboleth.shared.servlet.impl.ThreadLocalHttpServletResponseSupplier
 @SuppressWarnings("javadoc")
 public class HTTPRedirectRequestEncoderTest {
     
+    /** A client secret.*/
     private static final String CLIENT_SECRET = "Xp2s5v8y/B?E(H+MbQeThWmYq3t6w9z$";
     
     /** The encoder to test.*/
@@ -98,6 +99,11 @@ public class HTTPRedirectRequestEncoderTest {
     	HttpServletRequestResponseContext.loadCurrent(new MockHttpServletRequest(), mockResponse);
     }
     
+    /**
+     * Create a set of claims suitable for an ID Token.
+     * 
+     * @return the claims
+     */
     private JWTClaimsSet createClaims() {
         return new JWTClaimsSet.Builder()
                 .issuer("https://localhost:9918")
@@ -110,6 +116,13 @@ public class HTTPRedirectRequestEncoderTest {
                 .build();
     }
     
+    /** 
+     * Create a signed JWT.
+     * 
+     * @return a signed JWT
+     * @throws KeyLengthException on error
+     * @throws JOSEException on error
+     */
     private SignedJWT createdSignedJWT() throws KeyLengthException, JOSEException {        
         final var header = new JWSHeader.Builder(JWSAlgorithm.HS256)
                 .type(JOSEObjectType.JWT)
@@ -186,7 +199,7 @@ public class HTTPRedirectRequestEncoderTest {
         assert response != null;
         assertTrue(response.contains("https://somewhere.com/end-session"));
         assertTrue(response.contains("client_id"));
-        //assertTrue(response.contains("hint"));   
+        assertTrue(response.contains("ui_locales"));   
     }
     
     @Test
diff --git a/oidc-common-profile-impl/src/test/resources/templates/oidc-request-form-post.vm b/oidc-common-profile-impl/src/test/resources/templates/oidc-request-form-post.vm
index eb445e61..6ee1e877 100644
--- a/oidc-common-profile-impl/src/test/resources/templates/oidc-request-form-post.vm
+++ b/oidc-common-profile-impl/src/test/resources/templates/oidc-request-form-post.vm
@@ -24,7 +24,14 @@
 
     <form action="${action}" method="post">
          <div>
-            #if($client_id)
+            #if($id_token_hint) <input type="hidden" name="id_token_hint" value="${id_token_hint}" />#end #if($ui_locales)
+            
+            <input type="hidden" name="ui_locales" value="${ui_locales}" />#end #if($post_logout_redirect_uri)
+            
+            <input type="hidden" name="post_logout_redirect_uri" value="${post_logout_redirect_uri}" />#end #if($logout_hint)
+            
+            <input type="hidden" name="logout_hint" value="${logout_hint}" />#end #if($client_id)
+
             <input type="hidden" name="client_id" value="${client_id}" />#end #if($scope)
 
             <input type="hidden" name="scope" value="${scope}" />#end #if($response_type)

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list