2 * Licensed to the University Corporation for Advanced Internet
3 * Development, Inc. (UCAID) under one or more contributor license
4 * agreements. See the NOTICE file distributed with this work for
5 * additional information regarding copyright ownership.
7 * UCAID licenses this file to you under the Apache License,
8 * Version 2.0 (the "License"); you may not use this file except
9 * in compliance with the License. You may obtain a copy of the
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17 * either express or implied. See the License for the specific
18 * language governing permissions and limitations under the License.
24 * Handler for dumping information about an active session.
28 #include "Application.h"
29 #include "exceptions.h"
30 #include "ServiceProvider.h"
31 #include "SessionCache.h"
32 #include "SPRequest.h"
33 #include "attribute/Attribute.h"
34 #include "handler/SecuredHandler.h"
38 using namespace shibsp;
39 using namespace xmltooling;
44 #if defined (_MSC_VER)
45 #pragma warning( push )
46 #pragma warning( disable : 4250 )
49 class SHIBSP_API SessionHandler : public SecuredHandler
52 SessionHandler(const DOMElement* e, const char* appId);
53 virtual ~SessionHandler() {}
55 pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
61 #if defined (_MSC_VER)
62 #pragma warning( pop )
65 Handler* SHIBSP_DLLLOCAL SessionHandlerFactory(const pair<const DOMElement*,const char*>& p)
67 return new SessionHandler(p.first, p.second);
72 SessionHandler::SessionHandler(const DOMElement* e, const char* appId)
73 : SecuredHandler(e, Category::getInstance(SHIBSP_LOGCAT".SessionHandler")), m_values(false)
75 pair<bool,bool> flag = getBool("showAttributeValues");
77 m_values = flag.second;
80 pair<bool,long> SessionHandler::run(SPRequest& request, bool isHandler) const
82 // Check ACL in base class.
83 pair<bool,long> ret = SecuredHandler::run(request, isHandler);
88 s << "<html><head><title>Session Summary</title></head><body><pre>" << endl;
90 Session* session = nullptr;
92 session = request.getSession(); // caches the locked session in the request so it's unlocked automatically
94 s << "A valid session was not found.</pre></body></html>" << endl;
95 request.setContentType("text/html");
96 request.setResponseHeader("Expires","Wed, 01 Jan 1997 12:00:00 GMT");
97 request.setResponseHeader("Cache-Control","private,no-store,no-cache,max-age=0");
98 return make_pair(true, request.sendResponse(s));
101 catch (std::exception& ex) {
102 s << "Exception while retrieving active session:" << endl
103 << '\t' << ex.what() << "</pre></body></html>" << endl;
104 request.setContentType("text/html");
105 request.setResponseHeader("Expires","Wed, 01 Jan 1997 12:00:00 GMT");
106 request.setResponseHeader("Cache-Control","private,no-store,no-cache,max-age=0");
107 return make_pair(true, request.sendResponse(s));
110 s << "<u>Miscellaneous</u>" << endl;
112 s << "<strong>Client Address:</strong> " << (session->getClientAddress() ? session->getClientAddress() : "(none)") << endl;
113 s << "<strong>Identity Provider:</strong> " << (session->getEntityID() ? session->getEntityID() : "(none)") << endl;
114 s << "<strong>SSO Protocol:</strong> " << (session->getProtocol() ? session->getProtocol() : "(none)") << endl;
115 s << "<strong>Authentication Time:</strong> " << (session->getAuthnInstant() ? session->getAuthnInstant() : "(none)") << endl;
116 s << "<strong>Authentication Context Class:</strong> " << (session->getAuthnContextClassRef() ? session->getAuthnContextClassRef() : "(none)") << endl;
117 s << "<strong>Authentication Context Decl:</strong> " << (session->getAuthnContextDeclRef() ? session->getAuthnContextDeclRef() : "(none)") << endl;
118 s << "<strong>Session Expiration (barring inactivity):</strong> ";
119 if (session->getExpiration())
120 s << ((session->getExpiration() - time(nullptr)) / 60) << " minute(s)" << endl;
122 s << "Infinite" << endl;
124 s << endl << "<u>Attributes</u>" << endl;
127 vector<string>::size_type count=0;
128 const multimap<string,const Attribute*>& attributes = session->getIndexedAttributes();
129 for (multimap<string,const Attribute*>::const_iterator a = attributes.begin(); a != attributes.end(); ++a) {
130 if (a->first != key) {
131 if (a != attributes.begin()) {
135 s << count << " value(s)" << endl;
139 s << "<strong>" << a->first << "</strong>: ";
143 const vector<string>& vals = a->second->getSerializedValues();
144 for (vector<string>::const_iterator v = vals.begin(); v!=vals.end(); ++v) {
145 if (v != vals.begin() || a->first == key)
147 string::size_type pos = v->find_first_of(';',string::size_type(0));
148 if (pos!=string::npos) {
150 for (; pos != string::npos; pos = value.find_first_of(';',pos)) {
151 value.insert(pos, "\\");
162 count += a->second->getSerializedValues().size();
166 if (!m_values && !attributes.empty())
167 s << count << " value(s)" << endl;
169 s << "</pre></body></html>";
170 request.setContentType("text/html; charset=UTF-8");
171 request.setResponseHeader("Expires","Wed, 01 Jan 1997 12:00:00 GMT");
172 request.setResponseHeader("Cache-Control","private,no-store,no-cache,max-age=0");
173 return make_pair(true, request.sendResponse(s));