Handle encrypted PGTs (#260)
* Handle encrypted PGTs * add tests * stick to Java 6 and use commons-codec for Base64 * Remove the encrypted PGT after a PGT has been retrieved * use Bouncycastle to load PEM files * update to latest BC dependency
This commit is contained in:
parent
96f51465a8
commit
abacb75df2
|
|
@ -371,6 +371,8 @@ Validates the tickets using the CAS 2.0 protocol. If you provide either the `acc
|
|||
| `millisBetweenCleanUps` | Startup delay for the cleanup task to remove expired tickets from the storage. Defaults to `60000 msec` | No
|
||||
| `ticketValidatorClass` | Ticket validator class to use/create | No
|
||||
| `hostnameVerifier` | Hostname verifier class name, used when making back-channel calls | No
|
||||
| `privateKeyPath` | The path to a private key to decrypt PGTs directly sent encrypted as an attribute | No
|
||||
| `privateKeyAlgorithm` | The algorithm of the private key. Defaults to `RSA` | No
|
||||
|
||||
#### org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter
|
||||
Validates the tickets using the CAS 3.0 protocol. If you provide either the `acceptAnyProxy` or the `allowedProxyChains` parameters,
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ public interface ConfigurationKeys {
|
|||
ConfigurationKey<String> CAS_SERVER_URL_PREFIX = new ConfigurationKey<String>("casServerUrlPrefix", null);
|
||||
ConfigurationKey<String> ENCODING = new ConfigurationKey<String>("encoding", null);
|
||||
ConfigurationKey<Long> TOLERANCE = new ConfigurationKey<Long>("tolerance", 1000L);
|
||||
ConfigurationKey<String> PRIVATE_KEY_PATH = new ConfigurationKey<String>("privateKeyPath", null);
|
||||
ConfigurationKey<String> PRIVATE_KEY_ALGORITHM = new ConfigurationKey<String>("privateKeyAlgorithm", "RSA");
|
||||
|
||||
/**
|
||||
* @deprecated As of 3.4. This constant is not used by the client and will
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
package org.jasig.cas.client.util;
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.openssl.PEMKeyPair;
|
||||
import org.bouncycastle.openssl.PEMParser;
|
||||
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Security;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
|
||||
/**
|
||||
* Utility class to parse private keys.
|
||||
*
|
||||
* @author Jerome LELEU
|
||||
* @since 3.6.0
|
||||
*/
|
||||
public class PrivateKeyUtils {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(PrivateKeyUtils.class);
|
||||
|
||||
static {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
|
||||
public static PrivateKey createKey(final String path, final String algorithm) {
|
||||
PrivateKey key = readPemPrivateKey(path);
|
||||
if (key == null) {
|
||||
return readDERPrivateKey(path, algorithm);
|
||||
} else {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
private static PrivateKey readPemPrivateKey(final String path) {
|
||||
LOGGER.debug("Attempting to read as PEM [{}]", path);
|
||||
final File file = new File(path);
|
||||
InputStreamReader isr = null;
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
isr = new FileReader(file);
|
||||
br = new BufferedReader(isr);
|
||||
final PEMParser pp = new PEMParser(br);
|
||||
final PEMKeyPair pemKeyPair = (PEMKeyPair) pp.readObject();
|
||||
final KeyPair kp = new JcaPEMKeyConverter().getKeyPair(pemKeyPair);
|
||||
return kp.getPrivate();
|
||||
} catch (final Exception e) {
|
||||
LOGGER.error("Unable to read key", e);
|
||||
return null;
|
||||
} finally {
|
||||
try {
|
||||
if (br != null) {
|
||||
br.close();
|
||||
}
|
||||
if (isr != null) {
|
||||
isr.close();
|
||||
}
|
||||
} catch (final IOException e) {}
|
||||
}
|
||||
}
|
||||
|
||||
private static PrivateKey readDERPrivateKey(final String path, final String algorithm) {
|
||||
LOGGER.debug("Attempting to read key as DER [{}]", path);
|
||||
final File file = new File(path);
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
long byteLength = file.length();
|
||||
byte[] bytes = new byte[(int) byteLength];
|
||||
fis.read(bytes, 0, (int) byteLength);
|
||||
final PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(bytes);
|
||||
final KeyFactory factory = KeyFactory.getInstance(algorithm);
|
||||
return factory.generatePrivate(privSpec);
|
||||
} catch (final Exception e) {
|
||||
LOGGER.error("Unable to read key", e);
|
||||
return null;
|
||||
} finally {
|
||||
try {
|
||||
if (fis != null) {
|
||||
fis.close();
|
||||
}
|
||||
} catch (final IOException e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
package org.jasig.cas.client.validation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.PrivateKey;
|
||||
import java.util.*;
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
|
@ -30,6 +31,7 @@ import org.jasig.cas.client.proxy.*;
|
|||
import org.jasig.cas.client.ssl.HttpURLConnectionFactory;
|
||||
import org.jasig.cas.client.ssl.HttpsURLConnectionFactory;
|
||||
import org.jasig.cas.client.util.CommonUtils;
|
||||
import org.jasig.cas.client.util.PrivateKeyUtils;
|
||||
import org.jasig.cas.client.util.ReflectUtils;
|
||||
|
||||
import static org.jasig.cas.client.configuration.ConfigurationKeys.*;
|
||||
|
|
@ -54,7 +56,7 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
|
|||
TOLERANCE.getName(), IGNORE_PATTERN.getName(), IGNORE_URL_PATTERN_TYPE.getName(), HOSTNAME_VERIFIER.getName(), HOSTNAME_VERIFIER_CONFIG.getName(),
|
||||
EXCEPTION_ON_VALIDATION_FAILURE.getName(), REDIRECT_AFTER_VALIDATION.getName(), USE_SESSION.getName(), SECRET_KEY.getName(), CIPHER_ALGORITHM.getName(), PROXY_RECEPTOR_URL.getName(),
|
||||
PROXY_GRANTING_TICKET_STORAGE_CLASS.getName(), MILLIS_BETWEEN_CLEAN_UPS.getName(), ACCEPT_ANY_PROXY.getName(), ALLOWED_PROXY_CHAINS.getName(), TICKET_VALIDATOR_CLASS.getName(),
|
||||
PROXY_CALLBACK_URL.getName(), RELAY_STATE_PARAMETER_NAME.getName()
|
||||
PROXY_CALLBACK_URL.getName(), RELAY_STATE_PARAMETER_NAME.getName(), METHOD.getName(), PRIVATE_KEY_PATH.getName(), PRIVATE_KEY_ALGORITHM.getName()
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -72,6 +74,8 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
|
|||
|
||||
protected Class<? extends Cas20ProxyTicketValidator> defaultProxyTicketValidatorClass;
|
||||
|
||||
private PrivateKey privateKey;
|
||||
|
||||
/**
|
||||
* Storage location of ProxyGrantingTickets and Proxy Ticket IOUs.
|
||||
*/
|
||||
|
|
@ -113,6 +117,8 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
|
|||
}
|
||||
|
||||
this.millisBetweenCleanUps = getInt(ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS);
|
||||
|
||||
this.privateKey = buildPrivateKey(getString(PRIVATE_KEY_PATH), getString(PRIVATE_KEY_ALGORITHM));
|
||||
super.initInternal(filterConfig);
|
||||
}
|
||||
|
||||
|
|
@ -139,6 +145,13 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
|
|||
return (T) ReflectUtils.newInstance(ticketValidatorClass, casServerUrlPrefix);
|
||||
}
|
||||
|
||||
public static PrivateKey buildPrivateKey(final String keyPath, final String keyAlgorithm) {
|
||||
if (keyPath != null) {
|
||||
return PrivateKeyUtils.createKey(keyPath, keyAlgorithm);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a Cas20ServiceTicketValidator or a Cas20ProxyTicketValidator based on supplied parameters.
|
||||
*
|
||||
|
|
@ -184,6 +197,8 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
|
|||
}
|
||||
}
|
||||
|
||||
validator.setPrivateKey(this.privateKey);
|
||||
|
||||
validator.setCustomParameters(additionalParameters);
|
||||
return validator;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,9 +19,13 @@
|
|||
package org.jasig.cas.client.validation;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.security.PrivateKey;
|
||||
import java.util.*;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.jasig.cas.client.authentication.AttributePrincipal;
|
||||
import org.jasig.cas.client.authentication.AttributePrincipalImpl;
|
||||
import org.jasig.cas.client.proxy.Cas20ProxyRetriever;
|
||||
|
|
@ -43,6 +47,9 @@ import org.xml.sax.helpers.DefaultHandler;
|
|||
*/
|
||||
public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTicketValidator {
|
||||
|
||||
public static final String PGT_ATTRIBUTE = "proxyGrantingTicket";
|
||||
private static final String PGTIOU_PREFIX = "PGTIOU-";
|
||||
|
||||
/** The CAS 2.0 protocol proxy callback url. */
|
||||
private String proxyCallbackUrl;
|
||||
|
||||
|
|
@ -52,12 +59,14 @@ public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTick
|
|||
/** Implementation of the proxy retriever. */
|
||||
private ProxyRetriever proxyRetriever;
|
||||
|
||||
/** Private key for decryption */
|
||||
private PrivateKey privateKey;
|
||||
|
||||
/**
|
||||
* Constructs an instance of the CAS 2.0 Service Ticket Validator with the supplied
|
||||
* CAS server url prefix.
|
||||
*
|
||||
* @param casServerUrlPrefix the CAS Server URL prefix.
|
||||
* @param urlFactory URL connection factory to use when communicating with the server
|
||||
*/
|
||||
public Cas20ServiceTicketValidator(final String casServerUrlPrefix) {
|
||||
super(casServerUrlPrefix);
|
||||
|
|
@ -85,14 +94,7 @@ public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTick
|
|||
}
|
||||
|
||||
final String principal = parsePrincipalFromResponse(response);
|
||||
final String proxyGrantingTicketIou = parseProxyGrantingTicketFromResponse(response);
|
||||
|
||||
final String proxyGrantingTicket;
|
||||
if (CommonUtils.isBlank(proxyGrantingTicketIou) || this.proxyGrantingTicketStorage == null) {
|
||||
proxyGrantingTicket = null;
|
||||
} else {
|
||||
proxyGrantingTicket = this.proxyGrantingTicketStorage.retrieve(proxyGrantingTicketIou);
|
||||
}
|
||||
final String proxyGrantingTicket = retrieveProxyGrantingTicket(response);
|
||||
|
||||
if (CommonUtils.isEmpty(principal)) {
|
||||
throw new TicketValidationException("No principal was found in the response from the CAS server.");
|
||||
|
|
@ -101,6 +103,7 @@ public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTick
|
|||
final Assertion assertion;
|
||||
final Map<String, Object> attributes = extractCustomAttributes(response);
|
||||
if (CommonUtils.isNotBlank(proxyGrantingTicket)) {
|
||||
attributes.remove(PGT_ATTRIBUTE);
|
||||
final AttributePrincipal attributePrincipal = new AttributePrincipalImpl(principal, attributes,
|
||||
proxyGrantingTicket, this.proxyRetriever);
|
||||
assertion = new AssertionImpl(attributePrincipal);
|
||||
|
|
@ -113,8 +116,42 @@ public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTick
|
|||
return assertion;
|
||||
}
|
||||
|
||||
protected String parseProxyGrantingTicketFromResponse(final String response) {
|
||||
return XmlUtils.getTextForElement(response, "proxyGrantingTicket");
|
||||
protected String retrieveProxyGrantingTicket(final String response) {
|
||||
final List<String> values = XmlUtils.getTextForElements(response, PGT_ATTRIBUTE);
|
||||
for (final String value : values) {
|
||||
if (value != null) {
|
||||
if (value.startsWith(PGTIOU_PREFIX)) {
|
||||
return retrieveProxyGrantingTicketFromStorage(value);
|
||||
} else {
|
||||
return retrieveProxyGrantingTicketViaEncryption(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String retrieveProxyGrantingTicketFromStorage(final String pgtIou) {
|
||||
if (this.proxyGrantingTicketStorage != null) {
|
||||
return this.proxyGrantingTicketStorage.retrieve(pgtIou);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String retrieveProxyGrantingTicketViaEncryption(final String encryptedPgt) {
|
||||
if (this.privateKey != null) {
|
||||
try {
|
||||
final Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
|
||||
final byte[] cred64 = new Base64().decode(encryptedPgt);
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
final byte[] cipherData = cipher.doFinal(cred64);
|
||||
final String pgt = new String(cipherData);
|
||||
logger.debug("Decrypted PGT: {}", pgt);
|
||||
return pgt;
|
||||
} catch (final Exception e) {
|
||||
logger.error("Unable to decrypt PGT", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String parsePrincipalFromResponse(final String response) {
|
||||
|
|
@ -258,4 +295,12 @@ public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTick
|
|||
return this.attributes;
|
||||
}
|
||||
}
|
||||
|
||||
public PrivateKey getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
public void setPrivateKey(final PrivateKey privateKey) {
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,10 @@ package org.jasig.cas.client.validation;
|
|||
|
||||
import static org.junit.Assert.*;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import org.jasig.cas.client.PublicTestHttpServer;
|
||||
import org.jasig.cas.client.authentication.AttributePrincipalImpl;
|
||||
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
|
||||
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl;
|
||||
import org.jasig.cas.client.proxy.ProxyRetriever;
|
||||
|
|
@ -37,32 +39,33 @@ import org.junit.Test;
|
|||
public final class Cas20ServiceTicketValidatorTests extends AbstractTicketValidatorTests {
|
||||
|
||||
private static final PublicTestHttpServer server = PublicTestHttpServer.instance(8088);
|
||||
private static final String USERNAME = "username";
|
||||
private static final String PGTIOU = "PGTIOU-1-test";
|
||||
private static final String PGT = "PGT-1-ixcY6jtRXZ4OrJ39SadtLEcTLsGNhE8-NYtvDTK3kk5iAEdatRcnGrGjLckOwK8xU6ocastest";
|
||||
private static final String ENCRYPTED_PGT = "H3wqFQLBlvhbrPVo4yrwIF9p8yJhCfzHnLHgTWTYVw42sLDJj7c3PBFHKgZfaY9l57qDbKA0fZY979GGFFgnSz1VOOlTgVRi/nmbpwlScRLHP8qUf2JGUyhu0+nTRp6TcQiEqpf5iquXNyQ9UXPyWPdTM/YtgtYtcIOzMovjN5c=";
|
||||
|
||||
private Cas20ServiceTicketValidator ticketValidator;
|
||||
|
||||
private ProxyGrantingTicketStorage proxyGrantingTicketStorage;
|
||||
|
||||
private Field proxyGrantingTicketField;
|
||||
|
||||
public Cas20ServiceTicketValidatorTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
/*@AfterClass
|
||||
public static void classCleanUp() {
|
||||
server.shutdown();
|
||||
} */
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
this.proxyGrantingTicketStorage = getProxyGrantingTicketStorage();
|
||||
this.proxyGrantingTicketStorage = new ProxyGrantingTicketStorageImpl();
|
||||
this.proxyGrantingTicketStorage.save(PGTIOU, PGT);
|
||||
this.ticketValidator = new Cas20ServiceTicketValidator(CONST_CAS_SERVER_URL_PREFIX + "8088");
|
||||
this.ticketValidator.setProxyCallbackUrl("test");
|
||||
this.ticketValidator.setProxyGrantingTicketStorage(getProxyGrantingTicketStorage());
|
||||
this.ticketValidator.setProxyGrantingTicketStorage(this.proxyGrantingTicketStorage);
|
||||
this.ticketValidator.setProxyRetriever(getProxyRetriever());
|
||||
this.ticketValidator.setPrivateKey(Cas20ProxyReceivingTicketValidationFilter.buildPrivateKey("src/test/resources/private.pem", "RSA"));
|
||||
this.ticketValidator.setRenew(true);
|
||||
}
|
||||
|
||||
private ProxyGrantingTicketStorage getProxyGrantingTicketStorage() {
|
||||
return new ProxyGrantingTicketStorageImpl();
|
||||
proxyGrantingTicketField = AttributePrincipalImpl.class.getDeclaredField("proxyGrantingTicket");
|
||||
proxyGrantingTicketField.setAccessible(true);
|
||||
}
|
||||
|
||||
private ProxyRetriever getProxyRetriever() {
|
||||
|
|
@ -90,8 +93,7 @@ public final class Cas20ServiceTicketValidatorTests extends AbstractTicketValida
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testYesResponseButNoPgt() throws TicketValidationException, UnsupportedEncodingException {
|
||||
final String USERNAME = "username";
|
||||
public void testYesResponseButNoPgtiou() throws TicketValidationException, UnsupportedEncodingException {
|
||||
final String RESPONSE = "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'><cas:authenticationSuccess><cas:user>"
|
||||
+ USERNAME + "</cas:user></cas:authenticationSuccess></cas:serviceResponse>";
|
||||
server.content = RESPONSE.getBytes(server.encoding);
|
||||
|
|
@ -102,10 +104,7 @@ public final class Cas20ServiceTicketValidatorTests extends AbstractTicketValida
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testYesResponseWithPgt() throws TicketValidationException, UnsupportedEncodingException {
|
||||
final String USERNAME = "username";
|
||||
final String PGTIOU = "testPgtIou";
|
||||
final String PGT = "test";
|
||||
public void testYesResponseWithPgtiou() throws TicketValidationException, UnsupportedEncodingException, IllegalAccessException {
|
||||
final String RESPONSE = "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'><cas:authenticationSuccess><cas:user>"
|
||||
+ USERNAME
|
||||
+ "</cas:user><cas:proxyGrantingTicket>"
|
||||
|
|
@ -113,17 +112,15 @@ public final class Cas20ServiceTicketValidatorTests extends AbstractTicketValida
|
|||
+ "</cas:proxyGrantingTicket></cas:authenticationSuccess></cas:serviceResponse>";
|
||||
|
||||
server.content = RESPONSE.getBytes(server.encoding);
|
||||
this.proxyGrantingTicketStorage.save(PGTIOU, PGT);
|
||||
|
||||
final Assertion assertion = this.ticketValidator.validate("test", "test");
|
||||
assertEquals(USERNAME, assertion.getPrincipal().getName());
|
||||
// assertEquals(PGT, assertion.getProxyGrantingTicketId());
|
||||
final AttributePrincipalImpl principal = (AttributePrincipalImpl) assertion.getPrincipal();
|
||||
assertEquals(USERNAME, principal.getName());
|
||||
assertEquals(PGT, proxyGrantingTicketField.get(principal));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAttributes() throws TicketValidationException, UnsupportedEncodingException {
|
||||
final String USERNAME = "username";
|
||||
final String PGTIOU = "testPgtIou";
|
||||
public void testGetAttributes() throws TicketValidationException, UnsupportedEncodingException, IllegalAccessException {
|
||||
final String RESPONSE = "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'><cas:authenticationSuccess><cas:user>"
|
||||
+ USERNAME
|
||||
+ "</cas:user><cas:proxyGrantingTicket>"
|
||||
|
|
@ -132,20 +129,53 @@ public final class Cas20ServiceTicketValidatorTests extends AbstractTicketValida
|
|||
|
||||
server.content = RESPONSE.getBytes(server.encoding);
|
||||
final Assertion assertion = this.ticketValidator.validate("test", "test");
|
||||
assertEquals(USERNAME, assertion.getPrincipal().getName());
|
||||
assertEquals("test", assertion.getPrincipal().getAttributes().get("password"));
|
||||
assertEquals("id", assertion.getPrincipal().getAttributes().get("eduPersonId"));
|
||||
assertEquals("test1\n\ntest", assertion.getPrincipal().getAttributes().get("longAttribute"));
|
||||
final AttributePrincipalImpl principal = (AttributePrincipalImpl) assertion.getPrincipal();
|
||||
assertEquals(USERNAME, principal.getName());
|
||||
assertEquals("test", principal.getAttributes().get("password"));
|
||||
assertEquals("id", principal.getAttributes().get("eduPersonId"));
|
||||
assertEquals("test1\n\ntest", principal.getAttributes().get("longAttribute"));
|
||||
try {
|
||||
List<?> multivalued = (List<?>) assertion.getPrincipal().getAttributes().get("multivaluedAttribute");
|
||||
List<?> multivalued = (List<?>) principal.getAttributes().get("multivaluedAttribute");
|
||||
assertArrayEquals(new String[] { "value1", "value2" }, multivalued.toArray());
|
||||
} catch (Exception e) {
|
||||
fail("'multivaluedAttribute' attribute expected as List<Object> object.");
|
||||
}
|
||||
//assertEquals(PGT, assertion.getProxyGrantingTicketId());
|
||||
assertEquals(PGT, proxyGrantingTicketField.get(principal));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testYesResponseWithEncryptedPgt() throws TicketValidationException, UnsupportedEncodingException, IllegalAccessException {
|
||||
final String RESPONSE = "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'><cas:authenticationSuccess><cas:user>"
|
||||
+ USERNAME
|
||||
+ "</cas:user><cas:attributes><cas:proxyGrantingTicket>"
|
||||
+ ENCRYPTED_PGT
|
||||
+ "</cas:proxyGrantingTicket></cas:attributes></cas:authenticationSuccess></cas:serviceResponse>";
|
||||
|
||||
server.content = RESPONSE.getBytes(server.encoding);
|
||||
|
||||
final Assertion assertion = this.ticketValidator.validate("test", "test");
|
||||
final AttributePrincipalImpl principal = (AttributePrincipalImpl) assertion.getPrincipal();
|
||||
assertEquals(USERNAME, principal.getName());
|
||||
assertEquals(PGT, proxyGrantingTicketField.get(principal));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testYesResponseWithPgtiouAndEncryptedPgt() throws TicketValidationException, UnsupportedEncodingException, IllegalAccessException {
|
||||
final String RESPONSE = "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'><cas:authenticationSuccess><cas:user>"
|
||||
+ USERNAME
|
||||
+ "</cas:user><cas:proxyGrantingTicket>"
|
||||
+ PGTIOU
|
||||
+ "</cas:proxyGrantingTicket><cas:attributes><cas:proxyGrantingTicket>"
|
||||
+ ENCRYPTED_PGT
|
||||
+ "</cas:proxyGrantingTicket></cas:attributes></cas:authenticationSuccess></cas:serviceResponse>";
|
||||
|
||||
server.content = RESPONSE.getBytes(server.encoding);
|
||||
|
||||
final Assertion assertion = this.ticketValidator.validate("test", "test");
|
||||
final AttributePrincipalImpl principal = (AttributePrincipalImpl) assertion.getPrincipal();
|
||||
assertEquals(USERNAME, principal.getName());
|
||||
assertEquals(PGT, proxyGrantingTicketField.get(principal));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidResponse() throws Exception {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXgIBAAKBgQDcup6Yn4+K33A7jydo5YWuDYboBla65o4bikkSMxCvXWAvDwL/
|
||||
Qy69i4q7z/nZo/O2XgVQlfKFciXSSl4qfWj0R5XILCz/g8bjwG3r9tMJUFGhGlsm
|
||||
SCTbZ4+GcjnxREE8tu3x7LBhmIHZ9/FuStwnuGIBXj4iNs9K/mmYPPNAfwIDAQAB
|
||||
AoGBALs2xgGphDRDo4vAtapw0lt4Oa5egf1wQ6P0PFnlWgeDaWtAjkg3kVNPIdJ+
|
||||
aepA9xr80AEzzUmGMbIVRZ1AVV0YB2MBNl1FmFwjJLsZ7E9JbD84QQWUAZfmdp4h
|
||||
desvzPJA+FrVNuYxVJ8sO8pmOv2toueqeJYMOlSjFsQfR80RAkEA+bWxETU8RR2y
|
||||
bBW4sIJjRXb/SrztpRqjSCnqcFYa38QraYcWfk/TGU/u8U5j39xI2UM8pNSr8j+l
|
||||
i5ZC+SYzkwJBAOJKCgEuGInS8B5DVhuDswf0aRsn7P3mi68kAZqUaI/7Z55aopek
|
||||
usg02qK9Wn0aESRdjbNu0gOta9rpetYLKuUCQQDIE/O3RP9wpbXTcqgUDbU68Hjn
|
||||
Sm/jjW9tH+Cvd956krTyDgJQ3ObY7joW8OeHc/qO0pfhvmGzbZnYOWKaPSivAkA+
|
||||
sX6WFxxLSvqll8hKdTFrucZI9MXPDkmS62naVtWlVmS91aSIWOY6w5HzVny0fj1T
|
||||
kuvIU6KxzCE+lEMo/A0VAkEAtonSABWxd4CA/QOWbi9ZKpPUM1T5o/yATheS8DTk
|
||||
ZKFA2XDXB5Aj1lCjY/5QaOhfyE2AnvlukCRPzO5FWHabKQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
12
pom.xml
12
pom.xml
|
|
@ -238,6 +238,18 @@
|
|||
<version>${slf4j.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.11</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
<version>1.61</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
|
|
|
|||
Loading…
Reference in New Issue