/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at opensso/legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id: CDCServlet.java,v 1.13 2009/11/13 23:43:17 dknab Exp $
*
* Portions Copyrighted 2010-2016 ForgeRock AS.
*/
/**
* The <code>CDCServlet</code> is the heart of the Cross Domain Single
* Signon mechanism of OpenAM.
* <p>
* The following is the algorithm used by the program.
* <ol>
* <li> If request does not contain SSO related cookie redirect request to
* the auth service</li>
* <li> if request contains SSO related cookie
* <ul>
* <li>Retrieve the cookie related to SSO namely
* <code>iPlanetDirectoryPro</code> from request.</li>
* <li> Create Liberty <code>AuthnResponse</code> with the SSO cookie as
* the Name Identifier.</li>
* <li>Send the Response as Form POST to the original request
* requested using the goto parameter in the query string.</li>
* </ul>
* </li>
* </ol>
*/
"sunIdentityServerAuthNServer";
"X-DSAME-Assertion-Form";
"true";
static {
initConfig();
}
private boolean uniqueCookieEnabled;
/**
* Initiates the servlet.
*
* @param config Servlet Configuration object that contains configutation
* information for this servlet.
* @throws ServletException if servlet failed to initialize.
*/
try {
spValidator = new LdapSPValidator();
// Check if CDC needs to generate restricted SSO Tokens
if (debug.messageEnabled()) {
" Restricted Token Enabled = " + uniqueCookieEnabled +
" Auth URL Cookie Name = " + authURLCookieName +
" Auth URL Cookie Domain = " + authURLCookieDomain +
" Deployment Descriptor: " + deployDescriptor);
}
} catch (SSOException e) {
throw new ServletException(e.getMessage());
} catch(UnknownHostException e) {
throw new ServletException(e.getMessage());
}
}
/**
* Handles the HTTP GET request.
*
* @param request HTTP Servlet Request object that contains the request
* the client has made of the servlet.
* @param response an HTTP Servlet Response object that contains the
* response the servlet sends to the client.
* @throws ServletException if an input or output error is detected when
* the servlet handles the GET request
* @throws IOException if the request for the GET could not be handled.
*/
throws ServletException, IOException {
}
/**
* Handles the HTTP POST request.
*
* @param request HTTP Servlet Request object that contains the request
* the client has made of the servlet.
* @param response an HTTP Servlet Response object that contains the
* response the servlet sends to the client.
* @throws ServletException if an input or output error is detected when
* the servlet handles the GET request.
* @throws IOException if the request for the GET could not be handled.
*/
throws ServletException, IOException {
}
/**
* Redirects the user to the authentication module if he is not
* authenticated; otherwise redirects him back to the original referrer.
*
* @param request HTTP Servlet Request object that contains the request
* the client has made of the servlet.
* @param response an HTTP Servlet Response object that contains the
* response the servlet sends to the client.
* @throws ServletException if an input or output error is detected when
* the servlet handles the GET request
* @throws IOException if the request for the GET could not be handled.
*/
private void doGetPost(
) throws ServletException, IOException {
if (debug.messageEnabled()) {
}
if (targetParameter == null) {
}
// if check if goto ot target have invalid strings, to avoid
// accepting invalid injected javascript.
return;
}
return;
}
}
}
/* Steps
* 1. If no SSOToken, forward to authentication
* 2. If SSOToken is valid construct AuthN response and return
*/
/*
* Check for a valid SSOToken in the request. If it is not found or
* it is invalid, redirect the user for authentication URL.
* Also re-direct if there are policy advices in the query string
*/
} else {
//ok, the token is valid check if cookie is already set for this platform server
//if the CDCServlet was accessed with valid token, but the cookie is not set
//then set it to browser before redirecting
try {
}
} else {
}
}
} catch (Exception e) {
if (debug.messageEnabled()) {
}
}
}
}
}
/**
* Constructs the Liberty AuthNResponse with Restricted SSOToken
* and redirects the user to the requested resouce
*/
private void redirectWithAuthNResponse(
) throws ServletException, IOException {
if (debug.messageEnabled()) {
}
if (debug.messageEnabled()) {
}
try {
/**
* validateAndGetRestriction throws an exception if an agent
* profile with provider id and goto url is not present
*/
gotoURL);
if (uniqueCookieEnabled) {
} else {
}
} catch(SAMLException se) {
} catch(FSMsgException fe){
} catch(FSException fse){
} catch (SessionException e) {
} catch (SSOException ssoe) {
} catch (Exception e) {
spValidator = new LdapSPValidator();
}
}
}
) {
}
// this is unlikely to happen in a normal execution.
return null;
} else {
if (debug.messageEnabled()) {
}
return gotoURL;
}
}
/**
* Returns the parameters in the request as a HTTP URL string.
* It returns all the parameters from the original request except
* the original goto url.
* Note: All the paramters will be url decoded by default., we should
* make sure that these values are encoded again.
**
* @param request an HttpServletRequest object that contains the request
* the client has made of the servlet.
* @return The parameters of the request as String.
*/
) {
}
}
}
}
}
/**
* Returns policy advices
*/
) {
// this is to workaround cross domain SSO scenario where user
// has logged in against openAM server, but not with PA in different domain
// we will assume we don't need to re-authenticate user if it's not session
// upgrade
try {
tokenRealm = "/";
} else {
}
//if realm for user session is the same as the one from request,
//then it's not session upgrade and therefore no re-auth necessary
return null;
}
}
} catch (SSOException ssoe) {
}
}
}
if (adviceList == null) {
adviceList = new StringBuilder();
} else {
}
}
}
}
}
if (debug.messageEnabled()) {
+ adviceList);
}
}
/**
* Redirects the HTTP request to the Authentication module.
* It gets the authentication URL from <code>SystemProperties</code>.
*
* @param request HTTP Servlet Request object that contains the request
* the client has made of the servlet.
* @param response an HTTP Servlet Response object that contains the
* response the servlet sends to the client.
* @exception IOException if an input or output exception occurred.
*/
private void redirectForAuthentication(
) throws IOException {
// Check if user has authenticated to another OpenAM
// instance
if (authCookie != null) {
if (debug.messageEnabled()) {
"got an authenticated URL: " + authURL);
}
}
try {
(policyAdviceList != null) ||
) {
// Construct the login URL
if (debug.messageEnabled()) {
}
} else {
}
if (debug.messageEnabled()) {
}
} else {
}
// check if this is resource based auth case
if ((resourceAuth != null) &&
// this is the resource based authentication case,
// append resourceURL since original goto is modified
// check if resourceURL is present : J2EE agent case
if (resourceUrl == null) {
} else {
// resourceURL present in request
}
}
if (policyAdviceList != null) {
}
if (debug.messageEnabled()) {
}
}
} else {
// Redirect the user to the OpenAM host that they originally authenticated against. The authURL is
// set by AuthClientUtils#setHostUrlCookie when in restricted cookie mode. It's not entirely clear
// exactly what this use-case is for, but we should validate the cookie against the known server list
// to prevent an unvalidated redirect.
boolean valid = false;
valid = true;
break;
}
}
if (!valid) {
return;
}
/*
* Reset the cookie value to null, to avoid continous loop
* when a load balancer is used.
*/
}
if (debug.messageEnabled()) {
}
} catch (Exception e) {
}
}
}
try {
} catch (IOException e) {
"Could not show error message to the user", e);
} finally {
try {
}
} catch (IOException ex) {
//ignored
}
}
}
/**
* Returns the SSOToken of the user. If user has not authenticated
* re-directs the user to login page
*/
) throws IOException {
try {
/* SSOTokenManager.createSSOToken() throws an SSOException if the
* token is not valid, so for a invalid token manager.isValidToken()
* will never get executed for an invalid token.
*/
if (debug.messageEnabled()) {
"SSOToken is either null or not valid: " + token +
"\nRedirecting for authentication");
}
}
} catch (SSOException e) {
if (debug.messageEnabled()) {
}
}
return token;
}
) throws SAMLException, FSMsgException{
return response;
}
) throws FSException, SAMLException {
}
if (debug.messageEnabled()) {
"Creating Authentication Assertion for user with opaqueHandle ="
}
//setReauthenticateOnOrAfter date
// get this period from the config
}
if (debug.messageEnabled()) {
}
}
if (debug.messageEnabled()) {
}
if (debug.messageEnabled()) {
}
return assertion;
}
if (strAuthInst != null){
try {
} catch (ParseException ex) {
if (debug.messageEnabled()) {
"cannot convert " + strAuthInst);
}
}
}
}
if (debug.messageEnabled()) {
}
try{
if (debug.messageEnabled()) {
"AuthnResponse: " + respStr);
}
if (debug.messageEnabled()) {
+ "AuthnResponse sent successfully to: " + destURL);
}
} catch (FSMsgException fme) {
} catch (IOException ioe) {
} catch (ServletException se) {
}
}
/**
* Return <code>true</code> if the passed URI is valid compared to the valid set loaded during initialization.
*
* @param cdcUri The URI to test.
* @return <code>true</code> if the URI is considered valid, <code>false</code> otherwise.
*/
// We are only interested in the URI part up to any parameters that may be included.
if (questionMark != -1) {
}
// If there is not an exact match for the passed value then it cannot be considered valid
if (debug.messageEnabled()) {
}
return result;
}
private static void initConfig() {
if (INVALID_SET.isEmpty()) {
if (invalidStrings == null) {
} else {
while (st.hasMoreTokens()) {
}
}
}
if (validLoginURIStrings == null) {
} else {
if (debug.messageEnabled()) {
}
while (st.hasMoreTokens()) {
}
}
}
}