[java-identity-provider] branch main updated: IDP-2028 Track pgtUrl with proxy-granting ticket.

Marvin S. Addison marvin.addison at gmail.com
Fri Oct 28 18:45:15 UTC 2022


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

serac pushed a commit to branch main
in repository java-identity-provider.

View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=061180243b247966db5b72f0aee7f60899028e83

The following commit(s) were added to refs/heads/main by this push:
     new 061180243 IDP-2028 Track pgtUrl with proxy-granting ticket.
061180243 is described below

commit 061180243b247966db5b72f0aee7f60899028e83
Author: Marvin S. Addison <serac at vt.edu>
AuthorDate: Wed Oct 26 07:21:50 2022 -0400

    IDP-2028 Track pgtUrl with proxy-granting ticket.
    
    Tracking the proxy callback URL with the PGT is needed in order to emit the
    proxy callback URL in the <proxies> element of the /proxyValidate
    response message, which brings the CAS protocol into compliance with
    section 2.6.2 of the CAS protocol v2 spec.
    
    See https://shibboleth.atlassian.net/browse/IDP-2028.
---
 .../idp/cas/ticket/ProxyGrantingTicket.java        | 14 ++++++++++++-
 .../shibboleth/idp/cas/ticket/TicketService.java   |  8 ++++++--
 .../idp/cas/flow/impl/BuildProxyChainAction.java   |  2 +-
 .../cas/flow/impl/ValidateProxyCallbackAction.java |  6 ++++--
 .../idp/cas/ticket/impl/AbstractTicketService.java |  8 ++++++--
 .../idp/cas/ticket/impl/EncodingTicketService.java |  4 +++-
 .../impl/ProxyGrantingTicketSerializer.java        |  7 ++++++-
 .../idp/cas/flow/impl/AbstractFlowActionTest.java  |  8 ++++----
 .../cas/flow/impl/BuildProxyChainActionTest.java   | 23 +++++++++++++---------
 .../cas/flow/impl/GrantProxyTicketActionTest.java  |  3 ++-
 .../idp/cas/flow/impl/ValidateRenewActionTest.java |  4 ++--
 .../cas/flow/impl/ValidateTicketActionTest.java    |  2 +-
 .../cas/ticket/impl/EncodingTicketServiceTest.java | 13 +++++++++---
 .../cas/ticket/impl/SimpleTicketServiceTest.java   |  6 +++++-
 .../impl/ProxyGrantingTicketSerializerTest.java    |  6 ++++++
 .../idp/test/flows/cas/ProxyFlowTest.java          |  3 ++-
 .../idp/test/flows/cas/ProxyValidateFlowTest.java  | 19 ++++++++++--------
 .../idp/test/flows/cas/ThrowingTicketService.java  |  6 ++++--
 18 files changed, 100 insertions(+), 42 deletions(-)

diff --git a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/ticket/ProxyGrantingTicket.java b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/ticket/ProxyGrantingTicket.java
index c7e06448d..dbf236af8 100644
--- a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/ticket/ProxyGrantingTicket.java
+++ b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/ticket/ProxyGrantingTicket.java
@@ -31,6 +31,9 @@ import net.shibboleth.shared.primitive.StringSupport;
  */
 public class ProxyGrantingTicket extends Ticket {
 
+    /** Proxy callback URL that uniquely identifies the proxying party to which the PGT was issued. */
+    private String proxyCallbackUrl;
+
     /** The ID of the parent proxy-granting ticket. */
     @Nullable
     private String parentPgTicketId;
@@ -41,17 +44,25 @@ public class ProxyGrantingTicket extends Ticket {
      * @param id Ticket ID.
      * @param service Service that requested the ticket.
      * @param expiration Expiration instant.
+     * @param pgtUrl Proxy callback URL that uniquely identifies the proxying party to which the PGT was issued.
      * @param parentId ID of parent proxy-granting ticket or null if this is first proxy in chain.
      */
     public ProxyGrantingTicket(
             @Nonnull final String id,
             @Nonnull final String service,
             @Nonnull final Instant expiration,
+            @Nonnull final String pgtUrl,
             @Nullable final String parentId) {
         super(id, service, expiration);
+        proxyCallbackUrl = pgtUrl;
         parentPgTicketId = StringSupport.trimOrNull(parentId);
     }
 
+    /** @return Proxy callback URL that uniquely identifies the proxying party to which the PGT was issued. */
+    @Nonnull public String getProxyCallbackUrl() {
+        return proxyCallbackUrl;
+    }
+
     /**
      * Get ID of parent proxy-granting ticket.
      * 
@@ -72,7 +83,8 @@ public class ProxyGrantingTicket extends Ticket {
 
     @Override
     protected Ticket newInstance(final String newId) {
-        return new ProxyGrantingTicket(newId, getService(), getExpirationInstant(), parentPgTicketId);
+        return new ProxyGrantingTicket(
+            newId, getService(), getExpirationInstant(), getProxyCallbackUrl(), parentPgTicketId);
     }
 
 }
\ No newline at end of file
diff --git a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/ticket/TicketService.java b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/ticket/TicketService.java
index a0b8b5ced..36f90d024 100644
--- a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/ticket/TicketService.java
+++ b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/ticket/TicketService.java
@@ -63,6 +63,7 @@ public interface TicketService {
      * @param id ID of proxy-granting ticket to create.
      * @param expiry Expiration date of proxy-granting ticket.
      * @param serviceTicket Successfully-validated service ticket.
+     * @param pgtUrl Proxy callback URL used to authenticate and identify the proxying service.
      *
      * @return Created proxy-granting ticket.
      */
@@ -70,7 +71,8 @@ public interface TicketService {
     ProxyGrantingTicket createProxyGrantingTicket(
             @Nonnull String id,
             @Nonnull Instant expiry,
-            @Nonnull ServiceTicket serviceTicket);
+            @Nonnull ServiceTicket serviceTicket,
+            @Nonnull String pgtUrl);
 
     /**
      * Creates a chained proxy-granting ticket from a proxy ticket. The value of {@link ProxyTicket#getPgtId()}
@@ -79,6 +81,7 @@ public interface TicketService {
      * @param id ID of proxy-granting ticket to create.
      * @param expiry Expiration date of proxy-granting ticket.
      * @param proxyTicket Successfully-validated proxy ticket.
+     * @param pgtUrl Proxy callback URL used to authenticate and identify the proxying service.
      *
      * @return Created proxy-granting ticket.
      */
@@ -86,7 +89,8 @@ public interface TicketService {
     ProxyGrantingTicket createProxyGrantingTicket(
             @Nonnull String id,
             @Nonnull Instant expiry,
-            @Nonnull ProxyTicket proxyTicket);
+            @Nonnull ProxyTicket proxyTicket,
+            @Nonnull String pgtUrl);
 
     /**
      * Retrieves a proxy-granting ticket by its ID.
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildProxyChainAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildProxyChainAction.java
index fb1e16147..c6da7be7b 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildProxyChainAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildProxyChainAction.java
@@ -105,7 +105,7 @@ public class BuildProxyChainAction
                 ActionSupport.buildEvent(profileRequestContext, ProtocolError.BrokenProxyChain.event(this));
                 return;
             }
-            response.addProxy(pgt.getService());
+            response.addProxy(pgt.getProxyCallbackUrl());
             pgtId = pgt.getParentId();
         } while (pgtId != null);
     }
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateProxyCallbackAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateProxyCallbackAction.java
index d7525f2d2..5ea83ced0 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateProxyCallbackAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateProxyCallbackAction.java
@@ -145,9 +145,11 @@ public class ValidateProxyCallbackAction
         final String pgtId = pgtGenerator.generateIdentifier();
         final ProxyGrantingTicket pgt;
         if (ticket instanceof ServiceTicket) {
-            pgt = casTicketService.createProxyGrantingTicket(pgtId, expiration, (ServiceTicket) ticket);
+            pgt = casTicketService.createProxyGrantingTicket(
+                pgtId, expiration, (ServiceTicket) ticket, request.getPgtUrl());
         } else {
-            pgt = casTicketService.createProxyGrantingTicket(pgtId, expiration, (ProxyTicket) ticket);
+            pgt = casTicketService.createProxyGrantingTicket(
+                pgtId, expiration, (ProxyTicket) ticket, request.getPgtUrl());
         }
         // The ID of the proxy-granting ticket MAY be different from the generated value above.
         // ALWAYS use the value from the ticket object.
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/ticket/impl/AbstractTicketService.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/ticket/impl/AbstractTicketService.java
index 1327bc230..334c93be9 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/ticket/impl/AbstractTicketService.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/ticket/impl/AbstractTicketService.java
@@ -99,12 +99,14 @@ public abstract class AbstractTicketService implements TicketService {
     public ProxyGrantingTicket createProxyGrantingTicket(
             @Nonnull final String id,
             @Nonnull final Instant expiry,
-            @Nonnull final ServiceTicket serviceTicket) {
+            @Nonnull final ServiceTicket serviceTicket,
+            @Nonnull final String pgtUrl) {
         Constraint.isNotNull(serviceTicket, "ServiceTicket cannot be null");
         final ProxyGrantingTicket pgt = new ProxyGrantingTicket(
                 Constraint.isNotNull(id, "ID cannot be null"),
                 serviceTicket.getService(),
                 Constraint.isNotNull(expiry, "Expiry cannot be null"),
+                Constraint.isNotNull(pgtUrl, "pgtURL cannot be null"),
                 null);
         pgt.setTicketState(serviceTicket.getTicketState());
         store(pgt);
@@ -116,12 +118,14 @@ public abstract class AbstractTicketService implements TicketService {
     public ProxyGrantingTicket createProxyGrantingTicket(
             @Nonnull final String id,
             @Nonnull final Instant expiry,
-            @Nonnull final ProxyTicket proxyTicket) {
+            @Nonnull final ProxyTicket proxyTicket,
+            @Nonnull final String pgtUrl) {
         Constraint.isNotNull(proxyTicket, "ProxyTicket cannot be null");
         final ProxyGrantingTicket pgt = new ProxyGrantingTicket(
                 Constraint.isNotNull(id, "ID cannot be null"),
                 proxyTicket.getService(),
                 Constraint.isNotNull(expiry, "Expiry cannot be null"),
+            Constraint.isNotNull(pgtUrl, "pgtURL cannot be null"),
                 proxyTicket.getPgtId());
         pgt.setTicketState(proxyTicket.getTicketState());
         store(pgt);
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/ticket/impl/EncodingTicketService.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/ticket/impl/EncodingTicketService.java
index 21076bc28..877b5502f 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/ticket/impl/EncodingTicketService.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/ticket/impl/EncodingTicketService.java
@@ -186,12 +186,14 @@ public class EncodingTicketService extends AbstractTicketService {
     public ProxyGrantingTicket createProxyGrantingTicket(
             @Nonnull final String id,
             @Nonnull final Instant expiry,
-            @Nonnull final ServiceTicket serviceTicket) {
+            @Nonnull final ServiceTicket serviceTicket,
+            @Nonnull final String pgtUrl) {
         Constraint.isNotNull(serviceTicket, "ServiceTicket cannot be null");
         final ProxyGrantingTicket pgt = new ProxyGrantingTicket(
                 NOT_USED,
                 serviceTicket.getService(),
                 Constraint.isNotNull(expiry, "Expiry cannot be null"),
+                Constraint.isNotNull(pgtUrl, "pgtUrl cannot be null"),
                 null);
         pgt.setTicketState(serviceTicket.getTicketState());
         return encode(ProxyGrantingTicket.class, pgt, proxyGrantingTicketPrefix);
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/ticket/serialization/impl/ProxyGrantingTicketSerializer.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/ticket/serialization/impl/ProxyGrantingTicketSerializer.java
index 74d81a1eb..bde509080 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/ticket/serialization/impl/ProxyGrantingTicketSerializer.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/ticket/serialization/impl/ProxyGrantingTicketSerializer.java
@@ -35,10 +35,15 @@ public class ProxyGrantingTicketSerializer extends AbstractTicketSerializer<Prox
     /** Parent PGT ID field name. */
     private static final String PARENT_FIELD = "parent";
 
+    /** PGT URL field name. */
+    private static final String PGTURL_FIELD = "pgtUrl";
+
+
 
     @Override
     protected void serializeInternal(@Nonnull final JsonGenerator generator,
             @Nonnull final ProxyGrantingTicket ticket) {
+        generator.write(PGTURL_FIELD, ticket.getProxyCallbackUrl());
         if (ticket.getParentId() != null) {
             generator.write(PARENT_FIELD, ticket.getParentId());
         }
@@ -50,6 +55,6 @@ public class ProxyGrantingTicketSerializer extends AbstractTicketSerializer<Prox
             @Nonnull final String id,
             @Nonnull final String service,
             @Nonnull final Instant expiry) {
-        return new ProxyGrantingTicket(id, service, expiry, o.getString(PARENT_FIELD, null));
+        return new ProxyGrantingTicket(id, service, expiry, o.getString(PGTURL_FIELD), o.getString(PARENT_FIELD, null));
     }
 }
diff --git a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/AbstractFlowActionTest.java b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/AbstractFlowActionTest.java
index dc2e756cc..3dc573f6f 100644
--- a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/AbstractFlowActionTest.java
+++ b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/AbstractFlowActionTest.java
@@ -128,12 +128,12 @@ public abstract class AbstractFlowActionTest extends AbstractTestNGSpringContext
         return ticketService.createProxyTicket(generateProxyTicketId(), expiry(), pgt, service);
     }
 
-    protected ProxyGrantingTicket createProxyGrantingTicket(final ServiceTicket st) {
-        return ticketService.createProxyGrantingTicket(generateProxyGrantingTicketId(), expiry(), st);
+    protected ProxyGrantingTicket createProxyGrantingTicket(final ServiceTicket st, final String pgtUrl) {
+        return ticketService.createProxyGrantingTicket(generateProxyGrantingTicketId(), expiry(), st, pgtUrl);
     }
 
-    protected ProxyGrantingTicket createProxyGrantingTicket(final ProxyTicket pt) {
-        return ticketService.createProxyGrantingTicket(generateProxyGrantingTicketId(), expiry(), pt);
+    protected ProxyGrantingTicket createProxyGrantingTicket(final ProxyTicket pt, final String pgtUrl) {
+        return ticketService.createProxyGrantingTicket(generateProxyGrantingTicketId(), expiry(), pt, pgtUrl);
     }
 
     /**
diff --git a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/BuildProxyChainActionTest.java b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/BuildProxyChainActionTest.java
index da03ba1d6..9cb671910 100644
--- a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/BuildProxyChainActionTest.java
+++ b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/BuildProxyChainActionTest.java
@@ -41,10 +41,12 @@ public class BuildProxyChainActionTest extends AbstractFlowActionTest {
 
     @Test
     public void testBuildChainLength2() throws Exception {
-        final ServiceTicket st = createServiceTicket("proxyA", true);
-        final ProxyGrantingTicket pgtA = createProxyGrantingTicket(st);
+        final ServiceTicket st = createServiceTicket("alpha", true);
+        final String pgtUrlA = "https://proxya.example.com/";
+        final ProxyGrantingTicket pgtA = createProxyGrantingTicket(st, pgtUrlA);
         final ProxyTicket ptA = createProxyTicket(pgtA, "proxiedByA");
-        final ProxyGrantingTicket pgtB = createProxyGrantingTicket(ptA);
+        final String pgtUrlB = "https://proxyb.example.com/";
+        final ProxyGrantingTicket pgtB = createProxyGrantingTicket(ptA, pgtUrlB);
         final ProxyTicket ptB = createProxyTicket(pgtB, "proxiedByB");
         final TicketValidationRequest request = new TicketValidationRequest("proxiedByB", ptB.getId());
         final TicketValidationResponse response = new TicketValidationResponse();
@@ -54,19 +56,22 @@ public class BuildProxyChainActionTest extends AbstractFlowActionTest {
                 .build();
         assertNull(action.execute(context));
         assertEquals(response.getProxies().size(), 2);
-        assertEquals(response.getProxies().get(0), "proxiedByA");
-        assertEquals(response.getProxies().get(1), "proxyA");
+        assertEquals(response.getProxies().get(0), pgtUrlB);
+        assertEquals(response.getProxies().get(1), pgtUrlA);
     }
 
 
     @Test
     public void testBrokenProxyChain() throws Exception {
-        final ServiceTicket st = createServiceTicket("proxyA", true);
-        final ProxyGrantingTicket pgtA = createProxyGrantingTicket(st);
+        final ServiceTicket st = createServiceTicket("beta", true);
+        final String pgtUrlA = "https://proxya.example.com/";
+        final ProxyGrantingTicket pgtA = createProxyGrantingTicket(st, pgtUrlA);
         final ProxyTicket ptA = createProxyTicket(pgtA, "proxiedByA");
-        final ProxyGrantingTicket pgtB = createProxyGrantingTicket(ptA);
+        final String pgtUrlB = "https://proxyb.example.com/";
+        final ProxyGrantingTicket pgtB = createProxyGrantingTicket(ptA, pgtUrlB);
         final ProxyTicket ptB = createProxyTicket(pgtB, "proxiedByB");
-        final ProxyGrantingTicket pgtC = createProxyGrantingTicket(ptB);
+        final String pgtUrlC = "https://proxyc.example.com/";
+        final ProxyGrantingTicket pgtC = createProxyGrantingTicket(ptB, pgtUrlC);
         final ProxyTicket ptC = createProxyTicket(pgtC, "proxiedByC");
         final TicketValidationRequest request = new TicketValidationRequest("proxiedByC", ptC.getId());
         final TicketValidationResponse response = new TicketValidationResponse();
diff --git a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/GrantProxyTicketActionTest.java b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/GrantProxyTicketActionTest.java
index 9be13bc8a..9eae9c8ef 100644
--- a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/GrantProxyTicketActionTest.java
+++ b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/GrantProxyTicketActionTest.java
@@ -41,7 +41,8 @@ public class GrantProxyTicketActionTest extends AbstractFlowActionTest {
     @Test
     public void testGrantProxyTicketSuccess() throws Exception {
         final String service = "https://s.example.org/";
-        final ProxyGrantingTicket pgt = createProxyGrantingTicket(createServiceTicket(service, false));
+        final ProxyGrantingTicket pgt = createProxyGrantingTicket(
+            createServiceTicket(service, false), service + "proxy");
         final RequestContext context = new TestContextBuilder(ProxyConfiguration.PROFILE_ID)
                 .addProtocolContext(new ProxyTicketRequest(pgt.getId(), service), null)
                 .addTicketContext(pgt)
diff --git a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/ValidateRenewActionTest.java b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/ValidateRenewActionTest.java
index 953f226eb..a1b0ace52 100644
--- a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/ValidateRenewActionTest.java
+++ b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/ValidateRenewActionTest.java
@@ -54,7 +54,7 @@ public class ValidateRenewActionTest extends AbstractFlowActionTest {
     @Test
     public void testRenewIncompatibleWithProxy() throws Exception {
         final ServiceTicket st = createServiceTicket(TEST_SERVICE, false);
-        final ProxyGrantingTicket pgt = createProxyGrantingTicket(st);
+        final ProxyGrantingTicket pgt = createProxyGrantingTicket(st, TEST_SERVICE + "/proxy");
         final ProxyTicket pt = createProxyTicket(pgt, "https://foo.example.org");
         final TicketValidationRequest request = new TicketValidationRequest(TEST_SERVICE, pt.getId());
         request.setRenew(true);
@@ -80,7 +80,7 @@ public class ValidateRenewActionTest extends AbstractFlowActionTest {
     @Test
     public void testSuccessWithoutRenewAndProxyTicket() throws Exception {
         final ServiceTicket st = createServiceTicket(TEST_SERVICE, false);
-        final ProxyGrantingTicket pgt = createProxyGrantingTicket(st);
+        final ProxyGrantingTicket pgt = createProxyGrantingTicket(st, TEST_SERVICE + "/proxy");
         final ProxyTicket pt = createProxyTicket(pgt, "https://foo.example.org");
         final RequestContext context = new TestContextBuilder(LoginConfiguration.PROFILE_ID)
                 .addProtocolContext(new TicketValidationRequest(TEST_SERVICE, pt.getId()), null)
diff --git a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/ValidateTicketActionTest.java b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/ValidateTicketActionTest.java
index d640c29d7..068d67c6d 100644
--- a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/ValidateTicketActionTest.java
+++ b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/ValidateTicketActionTest.java
@@ -121,7 +121,7 @@ public class ValidateTicketActionTest extends AbstractFlowActionTest {
     @Test
     public void testProxyTicketValidateSuccess() throws Exception {
         final ServiceTicket st = createServiceTicket(TEST_SERVICE, false);
-        final ProxyGrantingTicket pgt = createProxyGrantingTicket(st);
+        final ProxyGrantingTicket pgt = createProxyGrantingTicket(st, TEST_SERVICE + "/proxy");
         final ProxyTicket pt = createProxyTicket(pgt, "proxyA");
         final RequestContext context = new TestContextBuilder(ValidateConfiguration.PROFILE_ID)
                 .addProtocolContext(new TicketValidationRequest("proxyA", pt.getId()), null)
diff --git a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/impl/EncodingTicketServiceTest.java b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/impl/EncodingTicketServiceTest.java
index 06875ef89..f3f192cf2 100644
--- a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/impl/EncodingTicketServiceTest.java
+++ b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/impl/EncodingTicketServiceTest.java
@@ -160,7 +160,8 @@ public class EncodingTicketServiceTest {
     @Test
     public void testCreateFetchRemoveEncodedProxyGrantingTicket() {
         final String principal = "aleph";
-        final String serviceUrl = "https://www.example.com/pgt1/";
+        final String serviceUrl = "https://www.example.com/service1";
+        final String pgtUrl = "https://www.example.com/pgt1";
         final ServiceTicket st = ticketService.createServiceTicket(
             String.valueOf(System.currentTimeMillis()),
             Instant.now().plusSeconds(5),
@@ -168,15 +169,17 @@ public class EncodingTicketServiceTest {
             newState(principal),
             true);
         final Instant expiry = Instant.now().plusSeconds(3600);
-        final ProxyGrantingTicket pgt = ticketService.createProxyGrantingTicket("notused", expiry, st);
+        final ProxyGrantingTicket pgt = ticketService.createProxyGrantingTicket("notused", expiry, st, pgtUrl);
         assertTrue(pgt.getId().startsWith("PGT-E-"));
         final ProxyGrantingTicket pgt2 = ticketService.fetchProxyGrantingTicket(pgt.getId());
         assertNotNull(pgt2);
         assertEquals(pgt2.getService(), serviceUrl);
+        assertEquals(pgt2.getProxyCallbackUrl(), pgtUrl);
         assertEquals(pgt2.getTicketState().getPrincipalName(), principal);
         final ProxyGrantingTicket pgt3 = ticketService.removeProxyGrantingTicket(pgt.getId());
         assertNotNull(pgt3);
         assertEquals(pgt3.getService(), serviceUrl);
+        assertEquals(pgt2.getProxyCallbackUrl(), pgtUrl);
         assertEquals(pgt3.getTicketState().getPrincipalName(), principal);
         // Removing encoded tickets is the same as fetching so they are still available (no backing storage)
         assertNotNull(ticketService.fetchProxyGrantingTicket(pgt.getId()));
@@ -189,7 +192,11 @@ public class EncodingTicketServiceTest {
 
     private ProxyGrantingTicket newPGT(final TicketState state, final String service) {
         final ProxyGrantingTicket pgt = new ProxyGrantingTicket(
-                pgtIdGenerator.generateIdentifier(), service, Instant.now().plusSeconds(300), "PGT-12345");
+            pgtIdGenerator.generateIdentifier(),
+            service,
+            Instant.now().plusSeconds(300),
+            service + "/proxy",
+            "PGT-12345");
         pgt.setTicketState(state);
         return pgt;
     }
diff --git a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/impl/SimpleTicketServiceTest.java b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/impl/SimpleTicketServiceTest.java
index 47bc187ed..4f9ed6ac9 100644
--- a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/impl/SimpleTicketServiceTest.java
+++ b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/impl/SimpleTicketServiceTest.java
@@ -42,6 +42,8 @@ public class SimpleTicketServiceTest {
 
     private static final String TEST_SERVICE = "https://example.com/widget";
 
+    private static final String TEST_PGTURL = "https://proxy.example.com/";
+
     private SimpleTicketService ticketService;
 
     @BeforeClass
@@ -77,6 +79,7 @@ public class SimpleTicketServiceTest {
         assertEquals(pgt, pgt2);
         assertEquals(pgt.getExpirationInstant(), pgt2.getExpirationInstant());
         assertEquals(pgt.getService(), pgt2.getService());
+        assertEquals(pgt.getProxyCallbackUrl(), pgt2.getProxyCallbackUrl());
         assertEquals(pgt.getTicketState(), pgt2.getTicketState());
         assertEquals(ticketService.removeProxyGrantingTicket(pgt.getId()), pgt);
         assertNull(ticketService.removeProxyGrantingTicket(pgt.getId()));
@@ -113,7 +116,8 @@ public class SimpleTicketServiceTest {
         return ticketService.createProxyGrantingTicket(
                 new TicketIdentifierGenerationStrategy("PGT", 50).generateIdentifier(),
                 expiry(),
-                createServiceTicket());
+                createServiceTicket(),
+                TEST_PGTURL);
     }
 
     private static Instant expiry() {
diff --git a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/serialization/impl/ProxyGrantingTicketSerializerTest.java b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/serialization/impl/ProxyGrantingTicketSerializerTest.java
index d41a706c9..363285e0d 100644
--- a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/serialization/impl/ProxyGrantingTicketSerializerTest.java
+++ b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/serialization/impl/ProxyGrantingTicketSerializerTest.java
@@ -39,12 +39,14 @@ public class ProxyGrantingTicketSerializerTest {
                 "ST-0123456789-9d22c36953a31fd12f12d30d76b344d3",
                 "https://nobody.example.org",
                 Instant.now().truncatedTo(ChronoUnit.MILLIS),
+                "https://proxy1.example.org",
                 null);
         final String serialized = serializer.serialize(pgt1);
         final ProxyGrantingTicket pgt2 = serializer.deserialize(1, "notused", pgt1.getId(), serialized, null);
         assertEquals(pgt2.getId(), pgt1.getId());
         assertEquals(pgt2.getService(), pgt1.getService());
         assertEquals(pgt2.getExpirationInstant(), pgt1.getExpirationInstant());
+        assertEquals(pgt2.getProxyCallbackUrl(), pgt1.getProxyCallbackUrl());
         assertEquals(pgt2.getParentId(), pgt1.getParentId());
         assertEquals(pgt2.getTicketState(), pgt1.getTicketState());
     }
@@ -55,6 +57,7 @@ public class ProxyGrantingTicketSerializerTest {
                 "ST-0123456789-fbca86ba09d1be7ec3ac17e6f372be87",
                 "https://nobody.example.org",
                 Instant.now().truncatedTo(ChronoUnit.MILLIS),
+                "https://proxy2.example.org",
                 null);
         pgt1.setTicketState(new TicketState("idpsess-1e663b80e6c6b2b7ae778cb3ea265", "bob",
                 Instant.now().truncatedTo(ChronoUnit.MILLIS), "Password"));
@@ -63,6 +66,7 @@ public class ProxyGrantingTicketSerializerTest {
         assertEquals(pgt2.getId(), pgt1.getId());
         assertEquals(pgt2.getService(), pgt1.getService());
         assertEquals(pgt2.getExpirationInstant(), pgt1.getExpirationInstant());
+        assertEquals(pgt2.getProxyCallbackUrl(), pgt1.getProxyCallbackUrl());
         assertEquals(pgt2.getParentId(), pgt1.getParentId());
         assertEquals(pgt2.getTicketState(), pgt1.getTicketState());
     }
@@ -73,6 +77,7 @@ public class ProxyGrantingTicketSerializerTest {
                 "ST-0123456789-fbca86ba09d1be7ec3ac17e6f372be87",
                 "https://nobody.example.org",
                 Instant.now().truncatedTo(ChronoUnit.MILLIS),
+                "https://proxy3.example.org",
                 "PGT-0987654321-0040c390cf67e571c7e12fcc78fc0cb3");
         pgt1.setTicketState(new TicketState("idpsess-6d986af1280b7f52f9e7da434cfd0", "bob",
                 Instant.now().truncatedTo(ChronoUnit.MILLIS), "Password"));
@@ -81,6 +86,7 @@ public class ProxyGrantingTicketSerializerTest {
         assertEquals(pgt2.getId(), pgt1.getId());
         assertEquals(pgt2.getService(), pgt1.getService());
         assertEquals(pgt2.getExpirationInstant(), pgt1.getExpirationInstant());
+        assertEquals(pgt2.getProxyCallbackUrl(), pgt1.getProxyCallbackUrl());
         assertEquals(pgt2.getParentId(), pgt1.getParentId());
         assertEquals(pgt2.getTicketState(), pgt1.getTicketState());
     }
diff --git a/idp-conf/src/test/java/net/shibboleth/idp/test/flows/cas/ProxyFlowTest.java b/idp-conf/src/test/java/net/shibboleth/idp/test/flows/cas/ProxyFlowTest.java
index 226f775ab..fe7a20890 100644
--- a/idp-conf/src/test/java/net/shibboleth/idp/test/flows/cas/ProxyFlowTest.java
+++ b/idp-conf/src/test/java/net/shibboleth/idp/test/flows/cas/ProxyFlowTest.java
@@ -173,6 +173,7 @@ public class ProxyFlowTest extends AbstractFlowTest {
         return ticketService.createProxyGrantingTicket(
                 new TicketIdentifierGenerationStrategy("PGT", 50).generateIdentifier(),
                 Instant.now().plus(1, ChronoUnit.HOURS),
-                st);
+                st,
+                "https://service.example.org/proxy");
     }
 }
diff --git a/idp-conf/src/test/java/net/shibboleth/idp/test/flows/cas/ProxyValidateFlowTest.java b/idp-conf/src/test/java/net/shibboleth/idp/test/flows/cas/ProxyValidateFlowTest.java
index ebc52c707..cab196c0c 100644
--- a/idp-conf/src/test/java/net/shibboleth/idp/test/flows/cas/ProxyValidateFlowTest.java
+++ b/idp-conf/src/test/java/net/shibboleth/idp/test/flows/cas/ProxyValidateFlowTest.java
@@ -81,7 +81,7 @@ public class ProxyValidateFlowTest extends AbstractFlowTest {
         assertTrue(responseBody.contains("<cas:authenticationSuccess>"));
         assertTrue(responseBody.contains("<cas:user>john</cas:user>"));
         assertFalse(responseBody.contains("<cas:proxyGrantingTicket>"));
-        assertTrue(responseBody.contains("<cas:proxy>https://service.example.org/</cas:proxy>"));
+        assertTrue(responseBody.contains("<cas:proxy>https://service.example.org/proxy</cas:proxy>"));
     }
 
     @Test
@@ -116,7 +116,7 @@ public class ProxyValidateFlowTest extends AbstractFlowTest {
         assertTrue(responseBody.contains("<cas:authenticationSuccess>"));
         assertTrue(responseBody.contains("<cas:user>john</cas:user>"));
         assertTrue(responseBody.contains("<cas:proxyGrantingTicket>"));
-        assertTrue(responseBody.contains("<cas:proxy>https://service.example.org/</cas:proxy>"));
+        assertTrue(responseBody.contains("<cas:proxy>https://service.example.org/proxy</cas:proxy>"));
     }
 
     // This test must execute after testSuccessWithProxy to prevent concurrency problems
@@ -155,21 +155,23 @@ public class ProxyValidateFlowTest extends AbstractFlowTest {
         final ProxyGrantingTicket pgt1 = ticketService.createProxyGrantingTicket(
             new TicketIdentifierGenerationStrategy("PGT", 50).generateIdentifier(),
             Instant.now().plusMillis(pgtTTLMillis),
-            st);
+            st,
+            "https://proxy1.example.org/");
         final ProxyTicket pt1 = ticketService.createProxyTicket(
             new TicketIdentifierGenerationStrategy("PT", 25).generateIdentifier(),
             Instant.now().plusSeconds(5),
             pgt1,
-            "https://proxy1.example.org/");
+            "https://proxied1.example.org/");
         final ProxyGrantingTicket pgt2 = ticketService.createProxyGrantingTicket(
             new TicketIdentifierGenerationStrategy("PGT", 50).generateIdentifier(),
             Instant.now().plusSeconds(3600),
-            pt1);
+            pt1,
+            "https://proxy2.example.org/");
         final ProxyTicket pt2 = ticketService.createProxyTicket(
             new TicketIdentifierGenerationStrategy("PT", 25).generateIdentifier(),
             Instant.now().plusSeconds(5),
             pgt2,
-            "https://proxy2.example.org/");
+            "https://proxied2.example.org/");
 
         externalContext.getMockRequestParameterMap().put("service", pt2.getService());
         externalContext.getMockRequestParameterMap().put("ticket", pt2.getId());
@@ -195,11 +197,12 @@ public class ProxyValidateFlowTest extends AbstractFlowTest {
         final ProxyGrantingTicket pgt = ticketService.createProxyGrantingTicket(
                 new TicketIdentifierGenerationStrategy("PGT", 50).generateIdentifier(),
                 Instant.now().plusSeconds(10),
-                st);
+                st,
+                "https://service.example.org/proxy");
         return ticketService.createProxyTicket(
                 new TicketIdentifierGenerationStrategy("PT", 25).generateIdentifier(),
                 Instant.now().plusSeconds(5),
                 pgt,
-                "https://proxyA.example.org/");
+                "https://proxiedA.example.org/");
     }
 }
diff --git a/idp-conf/src/test/java/net/shibboleth/idp/test/flows/cas/ThrowingTicketService.java b/idp-conf/src/test/java/net/shibboleth/idp/test/flows/cas/ThrowingTicketService.java
index 3add5ce41..6758bb137 100644
--- a/idp-conf/src/test/java/net/shibboleth/idp/test/flows/cas/ThrowingTicketService.java
+++ b/idp-conf/src/test/java/net/shibboleth/idp/test/flows/cas/ThrowingTicketService.java
@@ -46,12 +46,14 @@ public class ThrowingTicketService implements TicketService {
     }
 
     @Nonnull
-    public ProxyGrantingTicket createProxyGrantingTicket(@Nonnull String id, @Nonnull Instant expiry, @Nonnull ServiceTicket serviceTicket) {
+    public ProxyGrantingTicket createProxyGrantingTicket(
+        @Nonnull String id, @Nonnull Instant expiry, @Nonnull ServiceTicket serviceTicket, @Nonnull String pgtUrl) {
         throw new RuntimeException("createProxyGrantingTicket failed for ticket " + id);
     }
 
     @Nonnull
-    public ProxyGrantingTicket createProxyGrantingTicket(@Nonnull String id, @Nonnull Instant expiry, @Nonnull ProxyTicket proxyTicket) {
+    public ProxyGrantingTicket createProxyGrantingTicket(
+        @Nonnull String id, @Nonnull Instant expiry, @Nonnull ProxyTicket proxyTicket, @Nonnull String pgtUrl) {
         throw new RuntimeException("createProxyGrantingTicket failed for ticket " + id);
     }
 

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


More information about the commits mailing list