projects
/
shibboleth
/
cpp-sp.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
109ccda
)
Add return parameter and relay state support to logout processing in lieu of templates.
author
Scott Cantor
<cantor.2@osu.edu>
Wed, 19 Dec 2007 23:18:32 +0000
(23:18 +0000)
committer
Scott Cantor
<cantor.2@osu.edu>
Wed, 19 Dec 2007 23:18:32 +0000
(23:18 +0000)
configs/shibboleth2.xml.in
patch
|
blob
|
history
schemas/shibboleth-2.0-native-sp-config.xsd
patch
|
blob
|
history
shibsp/handler/impl/LocalLogoutInitiator.cpp
patch
|
blob
|
history
shibsp/handler/impl/LogoutHandler.cpp
patch
|
blob
|
history
shibsp/handler/impl/SAML2Logout.cpp
patch
|
blob
|
history
shibsp/handler/impl/SAML2LogoutInitiator.cpp
patch
|
blob
|
history
diff --git
a/configs/shibboleth2.xml.in
b/configs/shibboleth2.xml.in
index
c7ac88a
..
bd35126
100644
(file)
--- a/
configs/shibboleth2.xml.in
+++ b/
configs/shibboleth2.xml.in
@@
-143,7
+143,7
@@
Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01"/>
<!-- LogoutInitiators enable SP-initiated local or global/single logout of sessions. -->
Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01"/>
<!-- LogoutInitiators enable SP-initiated local or global/single logout of sessions. -->
- <LogoutInitiator type="Chaining" Location="/Logout">
+ <LogoutInitiator type="Chaining" Location="/Logout"
relayState="cookie"
>
<LogoutInitiator type="SAML2" template="@-PKGSYSCONFDIR-@/bindingTemplate.html"/>
<LogoutInitiator type="Local"/>
</LogoutInitiator>
<LogoutInitiator type="SAML2" template="@-PKGSYSCONFDIR-@/bindingTemplate.html"/>
<LogoutInitiator type="Local"/>
</LogoutInitiator>
diff --git
a/schemas/shibboleth-2.0-native-sp-config.xsd
b/schemas/shibboleth-2.0-native-sp-config.xsd
index
c08d2b4
..
fb2d538
100644
(file)
--- a/
schemas/shibboleth-2.0-native-sp-config.xsd
+++ b/
schemas/shibboleth-2.0-native-sp-config.xsd
@@
-569,6
+569,7
@@
<any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
\r
</sequence>
\r
<attribute name="Location" type="anyURI"/>
\r
<any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
\r
</sequence>
\r
<attribute name="Location" type="anyURI"/>
\r
+ <attribute name="relayState" type="conf:string"/>
\r
<attribute name="outgoingBindings" type="conf:listOfURIs"/>
\r
<attribute name="template" type="anyURI"/>
\r
<attribute name="postArtifact" type="boolean"/>
\r
<attribute name="outgoingBindings" type="conf:listOfURIs"/>
\r
<attribute name="template" type="anyURI"/>
\r
<attribute name="postArtifact" type="boolean"/>
\r
diff --git
a/shibsp/handler/impl/LocalLogoutInitiator.cpp
b/shibsp/handler/impl/LocalLogoutInitiator.cpp
index
832e640
..
6850bec
100644
(file)
--- a/
shibsp/handler/impl/LocalLogoutInitiator.cpp
+++ b/
shibsp/handler/impl/LocalLogoutInitiator.cpp
@@
-109,5
+109,9
@@
pair<bool,long> LocalLogoutInitiator::run(SPRequest& request, bool isHandler) co
request.getServiceProvider().getSessionCache()->remove(app, request, &request);
}
request.getServiceProvider().getSessionCache()->remove(app, request, &request);
}
+ // Route back to return location specified, or use the local template.
+ const char* dest = request.getParameter("return");
+ if (dest)
+ return make_pair(true, request.sendRedirect(dest));
return sendLogoutPage(app, request, request, true, "Logout was successful.");
}
return sendLogoutPage(app, request, request, true, "Logout was successful.");
}
diff --git
a/shibsp/handler/impl/LogoutHandler.cpp
b/shibsp/handler/impl/LogoutHandler.cpp
index
c86b412
..
5342397
100644
(file)
--- a/
shibsp/handler/impl/LogoutHandler.cpp
+++ b/
shibsp/handler/impl/LogoutHandler.cpp
@@
-119,6
+119,9
@@
pair<bool,long> LogoutHandler::notifyFrontChannel(
if (param)
index = atoi(param);
if (param)
index = atoi(param);
+ // "return" is a backwards-compatible "eventual destination" to go back to after logout completes.
+ param = request.getParameter("return");
+
// Fetch the next front notification URL and bump the index for the next round trip.
string loc = application.getNotificationURL(request.getRequestURL(), true, index++);
if (loc.empty())
// Fetch the next front notification URL and bump the index for the next round trip.
string loc = application.getNotificationURL(request.getRequestURL(), true, index++);
if (loc.empty())
@@
-138,6
+141,10
@@
pair<bool,long> LogoutHandler::notifyFrontChannel(
// Add a signal that we're coming back from notification and the next index.
locstr << "?notifying=1&index=" << index;
// Add a signal that we're coming back from notification and the next index.
locstr << "?notifying=1&index=" << index;
+ // Add return if set.
+ if (param)
+ locstr << "&return=" << encoder->encode(param);
+
// We preserve anything we're instructed to directly.
if (params) {
for (map<string,string>::const_iterator p = params->begin(); p!=params->end(); ++p)
// We preserve anything we're instructed to directly.
if (params) {
for (map<string,string>::const_iterator p = params->begin(); p!=params->end(); ++p)
@@
-151,7
+158,8
@@
pair<bool,long> LogoutHandler::notifyFrontChannel(
}
}
}
}
- // Add the return parameter to the destination location and redirect.
+ // Add the notifier's return parameter to the destination location and redirect.
+ // This is NOT the same as the return parameter that might be embedded inside it ;-)
loc = loc + "&return=" + encoder->encode(locstr.str().c_str());
return make_pair(true,response.sendRedirect(loc.c_str()));
}
loc = loc + "&return=" + encoder->encode(locstr.str().c_str());
return make_pair(true,response.sendRedirect(loc.c_str()));
}
diff --git
a/shibsp/handler/impl/SAML2Logout.cpp
b/shibsp/handler/impl/SAML2Logout.cpp
index
ade83f0
..
7dd1d78
100644
(file)
--- a/
shibsp/handler/impl/SAML2Logout.cpp
+++ b/
shibsp/handler/impl/SAML2Logout.cpp
@@
-514,6
+514,12
@@
pair<bool,long> SAML2Logout::doRequest(const Application& application, const HTT
}
checkError(logoutResponse, policy.getIssuerMetadata()); // throws if Status doesn't look good...
}
checkError(logoutResponse, policy.getIssuerMetadata()); // throws if Status doesn't look good...
+ // If relay state is set, recover the original return URL.
+ if (!relayState.empty())
+ recoverRelayState(application, request, response, relayState);
+ if (!relayState.empty())
+ return make_pair(true, response.sendRedirect(relayState.c_str()));
+
// Return template for completion of global logout, or redirect to homeURL.
return sendLogoutPage(application, request, response, false, "Global logout completed.");
}
// Return template for completion of global logout, or redirect to homeURL.
return sendLogoutPage(application, request, response, false, "Global logout completed.");
}
diff --git
a/shibsp/handler/impl/SAML2LogoutInitiator.cpp
b/shibsp/handler/impl/SAML2LogoutInitiator.cpp
index
00a1a66
..
ff813d3
100644
(file)
--- a/
shibsp/handler/impl/SAML2LogoutInitiator.cpp
+++ b/
shibsp/handler/impl/SAML2LogoutInitiator.cpp
@@
-348,6
+348,11
@@
pair<bool,long> SAML2LogoutInitiator::doRequest(
}
else {
delete logoutResponse;
}
else {
delete logoutResponse;
+ const char* returnloc = httpRequest.getParameter("return");
+ if (returnloc) {
+ ret.second = httpResponse.sendRedirect(returnloc);
+ ret.first = true;
+ }
ret = sendLogoutPage(application, httpRequest, httpResponse, false, "Logout completed successfully.");
}
ret = sendLogoutPage(application, httpRequest, httpResponse, false, "Logout completed successfully.");
}
@@
-359,11
+364,19
@@
pair<bool,long> SAML2LogoutInitiator::doRequest(
return ret;
}
return ret;
}
+ // Save off return location as RelayState.
+ string relayState;
+ const char* returnloc = httpRequest.getParameter("return");
+ if (returnloc) {
+ relayState = returnloc;
+ preserveRelayState(application, httpResponse, relayState);
+ }
+
auto_ptr<LogoutRequest> msg(buildRequest(application, *session, *role, encoder));
msg->setDestination(ep->getLocation());
auto_ptr_char dest(ep->getLocation());
auto_ptr<LogoutRequest> msg(buildRequest(application, *session, *role, encoder));
msg->setDestination(ep->getLocation());
auto_ptr_char dest(ep->getLocation());
- ret.second = sendMessage(*encoder, msg.get(),
NULL
, dest.get(), role, application, httpResponse);
+ ret.second = sendMessage(*encoder, msg.get(),
relayState.c_str()
, dest.get(), role, application, httpResponse);
ret.first = true;
msg.release(); // freed by encoder
}
ret.first = true;
msg.release(); // freed by encoder
}