1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
/**
* Licensed to the University Corporation for Advanced Internet
* Development, Inc. (UCAID) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*
* UCAID licenses this file to you 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.
*/
#include "binding.h"
#include <saml/saml2/core/Protocols.h>
using namespace opensaml::saml2p;
using namespace opensaml::saml2;
class SAML2RedirectTest : public CxxTest::TestSuite, public SAMLBindingBaseTestCase {
public:
void setUp() {
SAMLBindingBaseTestCase::setUp();
}
void tearDown() {
SAMLBindingBaseTestCase::tearDown();
}
void testSAML2Redirect() {
try {
xmltooling::QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);
SecurityPolicy policy(m_metadata.get(), &idprole, m_trust.get(), false);
policy.getRules().assign(m_rules.begin(), m_rules.end());
// Read message to use from file.
string path = data_path + "saml2/binding/SAML2Response.xml";
ifstream in(path.c_str());
DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);
XercesJanitor<DOMDocument> janitor(doc);
auto_ptr<Response> toSend(
dynamic_cast<Response*>(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(),true))
);
janitor.release();
CredentialCriteria cc;
cc.setUsage(Credential::SIGNING_CREDENTIAL);
Locker clocker(m_creds.get());
const Credential* cred = m_creds->resolve(&cc);
TSM_ASSERT("Retrieved credential was null", cred!=nullptr);
// Freshen timestamp and ID.
toSend->setIssueInstant(time(nullptr));
toSend->setID(nullptr);
// Encode message.
scoped_ptr<MessageEncoder> encoder(
SAMLConfig::getConfig().MessageEncoderManager.newPlugin(samlconstants::SAML20_BINDING_HTTP_REDIRECT, nullptr, false)
);
Locker locker(m_metadata.get());
encoder->encode(
*this,
toSend.get(),
"https://sp.example.org/SAML/SSO",
m_metadata->getEntityDescriptor(MetadataProvider::Criteria("https://sp.example.org/")).first,
"state",
nullptr,
cred
);
toSend.release();
// Decode message.
string relayState;
scoped_ptr<MessageDecoder> decoder(
SAMLConfig::getConfig().MessageDecoderManager.newPlugin(samlconstants::SAML20_BINDING_HTTP_REDIRECT, nullptr, false)
);
scoped_ptr<Response> response(dynamic_cast<Response*>(decoder->decode(relayState, *this, this, policy)));
// Test the results.
TSM_ASSERT_EQUALS("RelayState was not the expected result.", relayState, "state");
TSM_ASSERT("SAML Response not decoded successfully.", response.get());
TSM_ASSERT("Message was not verified.", policy.isAuthenticated());
auto_ptr_char entityID(policy.getIssuer()->getName());
TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));
TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
// Trigger a replay.
policy.reset();
TSM_ASSERT_THROWS("Did not catch the replay.", decoder->decode(relayState,*this,policy), SecurityPolicyException);
}
catch (const XMLToolingException& ex) {
TS_TRACE(ex.what());
throw;
}
}
};
|