Repository: cxf-fediz Updated Branches: refs/heads/1.2.x-fixes 6ed6ddd4e -> 74dfb98fd
Fixed logout process. Websphere session cookie is now deleted. Servlet API 3.x is required by Websphere 8.5 to support a logout. Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/7931ec1a Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/7931ec1a Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/7931ec1a Branch: refs/heads/1.2.x-fixes Commit: 7931ec1a1e3d535ce09aa9ea9ea2ed3b972751dc Parents: 6ed6ddd Author: [email protected] <[email protected]> Authored: Fri Aug 7 19:57:41 2015 +0200 Committer: Colm O hEigeartaigh <[email protected]> Committed: Thu Aug 13 10:33:48 2015 +0100 ---------------------------------------------------------------------- plugins/websphere/pom.xml | 9 +- .../org/apache/cxf/fediz/was/Constants.java | 11 ++ .../cxf/fediz/was/tai/FedizInterceptor.java | 119 ++++++++++++++----- 3 files changed, 103 insertions(+), 36 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/7931ec1a/plugins/websphere/pom.xml ---------------------------------------------------------------------- diff --git a/plugins/websphere/pom.xml b/plugins/websphere/pom.xml index b1c0747..65e26e5 100644 --- a/plugins/websphere/pom.xml +++ b/plugins/websphere/pom.xml @@ -36,10 +36,11 @@ <dependencies> <dependency> <groupId>javax.servlet</groupId> - <artifactId>servlet-api</artifactId> - <version>${servlet.version}</version> - <type>jar</type> - <scope>compile</scope> + <artifactId>javax.servlet-api</artifactId> + <!--<version>${servlet.version}</version>--> + <version>3.1.0</version> + <!--<type>jar</type>--> + <!--<scope>compile</scope>--> </dependency> <dependency> <groupId>org.apache.cxf.fediz</groupId> http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/7931ec1a/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/Constants.java ---------------------------------------------------------------------- diff --git a/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/Constants.java b/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/Constants.java index 4d3bd1f..4519c73 100644 --- a/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/Constants.java +++ b/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/Constants.java @@ -69,4 +69,15 @@ public interface Constants { * default value is set to 'false', thus the UserRegistry will be invoked. */ String PROPERTY_KEY_DIRECT_GROUP_MAPPING = "directGroupMapping"; + + /** + * The session cookie name can be renamed in WebSphere. If it is renames, it is required to change it in the + * interceptor configuration too. A missconfiguration would lead to performance loss. + */ + String PROPERTY_SESSION_COOKIE_NAME = "sessionCookieName"; + + /** + * Default name of the session cookie in wbesphere + */ + String SESSION_COOKIE_DEFAULT_NAME = "LtpaToken2"; } http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/7931ec1a/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/FedizInterceptor.java ---------------------------------------------------------------------- diff --git a/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/FedizInterceptor.java b/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/FedizInterceptor.java index fd76e61..b6f6551 100644 --- a/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/FedizInterceptor.java +++ b/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/FedizInterceptor.java @@ -31,6 +31,7 @@ import java.util.Properties; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.security.auth.Subject; +import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -64,6 +65,8 @@ import org.apache.cxf.fediz.was.tai.exception.TAIConfigurationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + + /** * A Trust Authentication Interceptor (TAI) that trusts a Sign-In-Response provided from a configured IP/STS * and instantiates the corresponding WAS Subject @@ -74,6 +77,7 @@ public class FedizInterceptor implements TrustAssociationInterceptor { private String configFile; private FedizConfigurator configurator; private RoleToGroupMapper mapper; + private String cookieName; /** * @see org.apache.cxf.fediz.was.Constants#PROPERTY_KEY_DIRECT_GROUP_MAPPING @@ -140,24 +144,26 @@ public class FedizInterceptor implements TrustAssociationInterceptor { /* * (non-Javadoc) - * @see com.ibm.wsspi.security.tai.TrustAssociationInterceptor#initialize(java.util.Properties) + * @see com.ibm.wsspi.security.tai.TrustAssociationInterceptor#initialize(java .util.Properties) */ @Override public int initialize(Properties props) throws WebTrustAssociationFailedException { if (props != null) { try { @SuppressWarnings("deprecation") - String roleGroupMapper = props.containsKey(Constants.PROPERTY_KEY_ROLE_MAPPER) - ? props.getProperty(Constants.PROPERTY_KEY_ROLE_MAPPER) - : props.getProperty(Constants.ROLE_GROUP_MAPPER); + String roleGroupMapper = props.containsKey(Constants.PROPERTY_KEY_ROLE_MAPPER) ? props + .getProperty(Constants.PROPERTY_KEY_ROLE_MAPPER) : props + .getProperty(Constants.ROLE_GROUP_MAPPER); if (roleGroupMapper != null && !roleGroupMapper.isEmpty()) { try { mapper = (RoleToGroupMapper)Class.forName(roleGroupMapper).newInstance(); LOG.debug("Using the {} mapper class", roleGroupMapper); mapper.initialize(props); } catch (Exception e) { - throw new TAIConfigurationException("Invalid TAI configuration for idpRoleToGroupMapper: " - + e.getClass().getName() + " " + e.getMessage()); + throw new TAIConfigurationException( + "Invalid TAI configuration for idpRoleToGroupMapper: " + + e.getClass().getName() + " " + + e.getMessage()); } } else { mapper = new DefaultRoleToGroupMapper(); @@ -165,9 +171,9 @@ public class FedizInterceptor implements TrustAssociationInterceptor { } @SuppressWarnings("deprecation") - String configFileLocation = props.containsKey(Constants.PROPERTY_KEY_CONFIG_LOCATION) - ? props.getProperty(Constants.PROPERTY_KEY_CONFIG_LOCATION) - : props.getProperty(Constants.CONFIGURATION_FILE_PARAMETER); + String configFileLocation = props.containsKey(Constants.PROPERTY_KEY_CONFIG_LOCATION) ? props + .getProperty(Constants.PROPERTY_KEY_CONFIG_LOCATION) : props + .getProperty(Constants.CONFIGURATION_FILE_PARAMETER); if (configFileLocation != null) { LOG.debug("Configuration file location set to {}", configFileLocation); File f = new File(configFileLocation); @@ -181,7 +187,13 @@ public class FedizInterceptor implements TrustAssociationInterceptor { + Constants.PROPERTY_KEY_CONFIG_LOCATION); } - directGroupMapping = Boolean.valueOf(props.getProperty(Constants.PROPERTY_KEY_DIRECT_GROUP_MAPPING)); + directGroupMapping = Boolean.valueOf(props + .getProperty(Constants.PROPERTY_KEY_DIRECT_GROUP_MAPPING)); + + cookieName = props.getProperty(Constants.PROPERTY_SESSION_COOKIE_NAME); + if (cookieName == null) { + cookieName = Constants.SESSION_COOKIE_DEFAULT_NAME; + } } catch (Throwable t) { LOG.warn("Failed initializing TAI", t); return 1; @@ -226,7 +238,7 @@ public class FedizInterceptor implements TrustAssociationInterceptor { } // Handle Logout requests - LogoutHandler logoutHandler = new LogoutHandler(fedCtx); + LogoutHandler logoutHandler = new LogoutHandler(fedCtx, req.getContextPath()); if (logoutHandler.canHandleRequest(req)) { LOG.debug("Logout URL request detected"); return true; @@ -252,7 +264,7 @@ public class FedizInterceptor implements TrustAssociationInterceptor { } } } - // Check if token is already in session + // Check if token is already in session Object token = session.getAttribute(Constants.SECURITY_TOKEN_SESSION_ATTRIBUTE_KEY); if (token != null) { LOG.debug("SAML Token found in session"); @@ -272,9 +284,9 @@ public class FedizInterceptor implements TrustAssociationInterceptor { /* * (non-Javadoc) - * @see - * com.ibm.wsspi.security.tai.TrustAssociationInterceptor#negotiateValidateandEstablishTrust(javax.servlet - * .http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + * @see com.ibm.wsspi.security.tai.TrustAssociationInterceptor# + * negotiateValidateandEstablishTrust(javax.servlet .http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) */ @Override public TAIResult negotiateValidateandEstablishTrust(HttpServletRequest req, HttpServletResponse resp) @@ -293,16 +305,49 @@ public class FedizInterceptor implements TrustAssociationInterceptor { MetadataDocumentHandler mddHandler = new MetadataDocumentHandler(fedCtx); if (mddHandler.canHandleRequest(req)) { return TAIResult.create(mddHandler.handleRequest(req, resp) - ? HttpServletResponse.SC_OK - : HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + ? HttpServletResponse.SC_OK : HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } // Handle Logout requests - LogoutHandler logoutHandler = new LogoutHandler(fedCtx); + LogoutHandler logoutHandler = new LogoutHandler(fedCtx, req.getContextPath()) { + + @Override + protected boolean signoutCleanup(HttpServletRequest request, HttpServletResponse response) { + HttpSession session = request.getSession(); + session.removeAttribute(Constants.SECURITY_TOKEN_SESSION_ATTRIBUTE_KEY); + session.removeAttribute(Constants.SUBJECT_TOKEN_KEY); + session.invalidate(); + Cookie cookie = new Cookie(Constants.PROPERTY_SESSION_COOKIE_NAME, ""); + cookie.setMaxAge(0); + response.addCookie(cookie); + try { + request.logout(); + } catch (ServletException e) { + LOG.error("Could not logout users"); + e.printStackTrace(); + } + // WSSecurityHelper.revokeSSOCookies(request, response); + return super.signoutCleanup(request, response); + } + + @Override + protected boolean signout(HttpServletRequest request, HttpServletResponse response) { + HttpSession session = request.getSession(); + session.removeAttribute(Constants.SECURITY_TOKEN_SESSION_ATTRIBUTE_KEY); + session.removeAttribute(Constants.SUBJECT_TOKEN_KEY); + session.invalidate(); + try { + request.logout(); + } catch (ServletException e) { + LOG.error("Could not logout users"); + e.printStackTrace(); + } + return super.signout(request, response); + } + }; if (logoutHandler.canHandleRequest(req)) { return TAIResult.create(logoutHandler.handleRequest(req, resp) - ? HttpServletResponse.SC_OK - : HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + ? HttpServletResponse.SC_OK : HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } // Handle Signin requests @@ -310,16 +355,20 @@ public class FedizInterceptor implements TrustAssociationInterceptor { @Override protected TAIResult createPrincipal(HttpServletRequest request, HttpServletResponse response, - FedizResponse federationResponse) { + FedizResponse federationResponse) { // proceed creating the JAAS Subject HttpSession session = request.getSession(true); session.setAttribute(Constants.SECURITY_TOKEN_SESSION_ATTRIBUTE_KEY, federationResponse); String username = federationResponse.getUsername(); - // List<String> groupsIds = groupIdsFromTokenRoles(federationResponse); - // Subject subject = createSubject(federationResponse, groupsIds, session.getId()); - // LOG.info("UserPrincipal was created successfully for {}", username); + // List<String> groupsIds = + // groupIdsFromTokenRoles(federationResponse); + // Subject subject = createSubject(federationResponse, + // groupsIds, session.getId()); + // LOG.info("UserPrincipal was created successfully for {}", + // username); try { - // return TAIResult.create(HttpServletResponse.SC_FOUND, username, subject); + // return TAIResult.create(HttpServletResponse.SC_FOUND, + // username, subject); return TAIResult.create(HttpServletResponse.SC_FOUND); } catch (WebTrustAssociationFailedException e) { LOG.error("TAIResult for user '" + username + "' could not be created", e); @@ -335,7 +384,8 @@ public class FedizInterceptor implements TrustAssociationInterceptor { return taiResult; } - // Check if user was authenticated previously and token is still valid + // Check if user was authenticated previously and token is still + // valid TAIResult taiResult = checkUserAuthentication(req, fedCtx); if (taiResult != null) { return taiResult; @@ -365,7 +415,7 @@ public class FedizInterceptor implements TrustAssociationInterceptor { session.removeAttribute(wctx); } } - + private TAIResult checkUserAuthentication(HttpServletRequest req, FedizContext fedCtx) throws WebTrustAssociationFailedException { TAIResult result = null; @@ -379,13 +429,15 @@ public class FedizInterceptor implements TrustAssociationInterceptor { // validate Security Token and create User Principal if (checkSecurityToken(federationResponse)) { - // TODO check if there is a better way to avoid recreation of subject each validated call + // TODO check if there is a better way to avoid recreation + // of subject each validated call // proceed creating the JAAS Subject List<String> groupsIds = groupIdsFromTokenRoles(federationResponse); LOG.debug("Mapped group IDs: {}", groupsIds); Subject subject = createSubject(federationResponse, groupsIds, session.getId()); - result = TAIResult.create(HttpServletResponse.SC_OK, federationResponse.getUsername(), subject); + result = TAIResult.create(HttpServletResponse.SC_OK, federationResponse.getUsername(), + subject); } if (!fedCtx.isDetectExpiredTokens()) { // token is not required for TTL validation @@ -420,7 +472,8 @@ public class FedizInterceptor implements TrustAssociationInterceptor { response.sendRedirect(redirectURL); } else { LOG.error("RedirectUrl is null. Failed to create SignInRequest."); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to create SignInRequest."); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "Failed to create SignInRequest."); } } catch (ProcessingException ex) { LOG.error("Failed to create SignInRequest", ex); @@ -512,7 +565,8 @@ public class FedizInterceptor implements TrustAssociationInterceptor { + ",o=defaultWIMFileBasedRealm"; String completeCacheKey = uniqueId + ':' + cacheKey; - // creating the JAAS Subject so that WAS won't do a lookup in the registry + // creating the JAAS Subject so that WAS won't do a lookup in the + // registry Subject subject = new Subject(); Map<String, Object> map = new Hashtable<String, Object>(); @@ -520,7 +574,8 @@ public class FedizInterceptor implements TrustAssociationInterceptor { map.put(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME, federationResponse.getUsername()); map.put(AttributeNameConstants.WSCREDENTIAL_GROUPS, groups); map.put(AttributeNameConstants.WSCREDENTIAL_CACHE_KEY, completeCacheKey); - // caching the WS-Federation security token for further reuse by the application + // caching the WS-Federation security token for further reuse by the + // application map.put(Constants.SUBJECT_TOKEN_KEY, federationResponse); subject.getPublicCredentials().add(map);
