Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 68C611159F for ; Fri, 1 Aug 2014 10:55:39 +0000 (UTC) Received: (qmail 12731 invoked by uid 500); 1 Aug 2014 10:55:39 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 12670 invoked by uid 500); 1 Aug 2014 10:55:39 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 12661 invoked by uid 99); 1 Aug 2014 10:55:39 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 01 Aug 2014 10:55:39 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 0CE059BCE15; Fri, 1 Aug 2014 10:55:39 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: coheigea@apache.org To: commits@cxf.apache.org Message-Id: <9aac28be5ddc4bef990970df13fac001@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: git commit: Some refactoring of the CXF plugin Date: Fri, 1 Aug 2014 10:55:39 +0000 (UTC) Repository: cxf-fediz Updated Branches: refs/heads/master aadf0319a -> 863f99bd0 Some refactoring of the CXF plugin Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/863f99bd Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/863f99bd Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/863f99bd Branch: refs/heads/master Commit: 863f99bd0a59a44571e626f5c4519ac0cc3f0817 Parents: aadf031 Author: Colm O hEigeartaigh Authored: Fri Aug 1 11:55:24 2014 +0100 Committer: Colm O hEigeartaigh Committed: Fri Aug 1 11:55:24 2014 +0100 ---------------------------------------------------------------------- .../fediz/core/processor/SAMLProcessorImpl.java | 62 +--------- .../apache/cxf/fediz/core/util/CookieUtils.java | 89 ++++++++++++++ .../plugin/AbstractServiceProviderFilter.java | 115 +++++++------------ .../cxf/fediz/cxf/plugin/CXFFedizPrincipal.java | 2 +- .../cxf/plugin/SamlRedirectBindingFilter.java | 9 +- 5 files changed, 141 insertions(+), 136 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/863f99bd/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java ---------------------------------------------------------------------- diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java index 1679da2..0272a10 100644 --- a/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java +++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java @@ -24,11 +24,8 @@ import java.io.InputStream; import java.net.URLEncoder; import java.security.PrivateKey; import java.security.Signature; -import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; -import java.util.Locale; -import java.util.TimeZone; import java.util.UUID; import java.util.zip.DataFormatException; @@ -53,6 +50,7 @@ import org.apache.cxf.fediz.core.samlsso.RequestState; import org.apache.cxf.fediz.core.samlsso.SAMLProtocolResponseValidator; import org.apache.cxf.fediz.core.samlsso.SAMLSSOResponseValidator; import org.apache.cxf.fediz.core.samlsso.SSOValidatorResponse; +import org.apache.cxf.fediz.core.util.CookieUtils; import org.apache.cxf.fediz.core.util.DOMUtils; import org.apache.wss4j.common.crypto.Crypto; import org.apache.wss4j.common.ext.WSSecurityException; @@ -116,26 +114,14 @@ public class SAMLProcessorImpl extends AbstractFedizProcessor { LOG.error("Missing Request State"); throw new ProcessingException(TYPE.INVALID_REQUEST); } - if (isStateExpired(requestState.getCreatedAt(), 0, samlProtocol.getStateTimeToLive())) { + if (CookieUtils.isStateExpired(requestState.getCreatedAt(), 0, + samlProtocol.getStateTimeToLive())) { LOG.error("EXPIRED_REQUEST_STATE"); throw new ProcessingException(TYPE.INVALID_REQUEST); } return requestState; } - private boolean isStateExpired(long stateCreatedAt, long expiresAt, long stateTTL) { - Date currentTime = new Date(); - if (currentTime.after(new Date(stateCreatedAt + stateTTL))) { - return true; - } - - if (expiresAt > 0 && currentTime.after(new Date(expiresAt))) { - return true; - } - - return false; - } - protected FedizResponse processSignInRequest( FedizRequest request, FedizContext config) throws ProcessingException { @@ -342,7 +328,7 @@ public class SAMLProcessorImpl extends AbstractFedizProcessor { sb.append("&" + SAMLSSOConstants.SIGNATURE).append('=').append(signature); } - String contextCookie = createCookie(SAMLSSOConstants.RELAY_STATE, + String contextCookie = CookieUtils.createCookie(SAMLSSOConstants.RELAY_STATE, relayState, request.getRequestURI(), webAppDomain, @@ -417,46 +403,6 @@ public class SAMLProcessorImpl extends AbstractFedizProcessor { return URLEncoder.encode(encodedSignature, "UTF-8"); } - protected String createCookie(String name, - String value, - String path, - String domain, - long stateTimeToLive) { - - String contextCookie = name + "=" + value; - // Setting a specific path restricts the browsers - // to return a cookie only to the web applications - // listening on that specific context path - if (path != null) { - contextCookie += ";Path=" + path; - } - - // Setting a specific domain further restricts the browsers - // to return a cookie only to the web applications - // listening on the specific context path within a particular domain - if (domain != null) { - contextCookie += ";Domain=" + domain; - } - - // Keep the cookie across the browser restarts until it actually expires. - // Note that the Expires property has been deprecated but apparently is - // supported better than 'max-age' property by different browsers - // (Firefox, IE, etc) - Date expiresDate = new Date(System.currentTimeMillis() + stateTimeToLive); - String cookieExpires = getHttpDateFormat().format(expiresDate); - contextCookie += ";Expires=" + cookieExpires; - - return contextCookie; - } - - protected static SimpleDateFormat getHttpDateFormat() { - SimpleDateFormat dateFormat = - new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US); - TimeZone tZone = TimeZone.getTimeZone("GMT"); - dateFormat.setTimeZone(tZone); - return dateFormat; - } - protected String encodeAuthnRequest(Element authnRequest) throws IOException { String requestMessage = DOM2Writer.nodeToString(authnRequest); http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/863f99bd/plugins/core/src/main/java/org/apache/cxf/fediz/core/util/CookieUtils.java ---------------------------------------------------------------------- diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/util/CookieUtils.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/util/CookieUtils.java new file mode 100644 index 0000000..f1ac431 --- /dev/null +++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/util/CookieUtils.java @@ -0,0 +1,89 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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. + */ + +package org.apache.cxf.fediz.core.util; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +/** + * Some Utility methods for manipulating cookies + */ +public final class CookieUtils { + + private CookieUtils() { + // complete + } + + public static String createCookie(String name, + String value, + String path, + String domain, + long stateTimeToLive) { + + String contextCookie = name + "=" + value; + // Setting a specific path restricts the browsers + // to return a cookie only to the web applications + // listening on that specific context path + if (path != null) { + contextCookie += ";Path=" + path; + } + + // Setting a specific domain further restricts the browsers + // to return a cookie only to the web applications + // listening on the specific context path within a particular domain + if (domain != null) { + contextCookie += ";Domain=" + domain; + } + + // Keep the cookie across the browser restarts until it actually expires. + // Note that the Expires property has been deprecated but apparently is + // supported better than 'max-age' property by different browsers + // (Firefox, IE, etc) + Date expiresDate = new Date(System.currentTimeMillis() + stateTimeToLive); + String cookieExpires = getHttpDateFormat().format(expiresDate); + contextCookie += ";Expires=" + cookieExpires; + + return contextCookie; + } + + public static SimpleDateFormat getHttpDateFormat() { + SimpleDateFormat dateFormat = + new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US); + TimeZone tZone = TimeZone.getTimeZone("GMT"); + dateFormat.setTimeZone(tZone); + return dateFormat; + } + + public static boolean isStateExpired(long stateCreatedAt, long expiresAt, long stateTTL) { + Date currentTime = new Date(); + if (currentTime.after(new Date(stateCreatedAt + stateTTL))) { + return true; + } + + if (expiresAt > 0 && currentTime.after(new Date(expiresAt))) { + return true; + } + + return false; + } + +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/863f99bd/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/AbstractServiceProviderFilter.java ---------------------------------------------------------------------- diff --git a/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/AbstractServiceProviderFilter.java b/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/AbstractServiceProviderFilter.java index 8b90f7d..853f916 100644 --- a/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/AbstractServiceProviderFilter.java +++ b/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/AbstractServiceProviderFilter.java @@ -19,22 +19,24 @@ package org.apache.cxf.fediz.cxf.plugin; import java.io.File; +import java.io.IOException; import java.io.StringReader; import java.net.MalformedURLException; +import java.net.URI; import java.net.URL; -import java.util.Date; +import java.util.List; import java.util.Map; import java.util.ResourceBundle; import javax.annotation.PostConstruct; -import javax.annotation.Priority; -import javax.ws.rs.Priorities; +import javax.annotation.PreDestroy; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.PreMatching; import javax.ws.rs.core.Cookie; import javax.ws.rs.core.HttpHeaders; import javax.xml.bind.JAXBException; +import org.w3c.dom.Element; import org.apache.cxf.common.classloader.ClassLoaderUtils; import org.apache.cxf.common.i18n.BundleUtils; import org.apache.cxf.fediz.core.SAMLSSOConstants; @@ -43,20 +45,17 @@ import org.apache.cxf.fediz.core.config.FedizConfigurator; import org.apache.cxf.fediz.core.config.FedizContext; import org.apache.cxf.fediz.core.config.SAMLProtocol; import org.apache.cxf.fediz.core.samlsso.ResponseState; -import org.apache.cxf.fediz.core.util.DOMUtils; +import org.apache.cxf.fediz.core.util.CookieUtils; import org.apache.cxf.jaxrs.impl.HttpHeadersImpl; import org.apache.cxf.jaxrs.impl.UriInfoImpl; -import org.apache.cxf.jaxrs.utils.HttpUtils; import org.apache.cxf.message.Message; import org.apache.cxf.security.SecurityContext; import org.apache.cxf.staxutils.StaxUtils; import org.apache.wss4j.common.ext.WSSecurityException; -import org.apache.wss4j.common.saml.SamlAssertionWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @PreMatching -@Priority(Priorities.AUTHENTICATION + 1) public abstract class AbstractServiceProviderFilter implements ContainerRequestFilter { public static final String SECURITY_CONTEXT_TOKEN = @@ -66,8 +65,8 @@ public abstract class AbstractServiceProviderFilter implements ContainerRequestF private static final Logger LOG = LoggerFactory.getLogger(AbstractServiceProviderFilter.class); private String webAppDomain; - // private boolean addWebAppContext = true; - // private boolean addEndpointAddressToContext; + private boolean addWebAppContext = true; + private boolean addEndpointAddressToContext; private FedizConfigurator configurator; private String configFile; @@ -108,6 +107,22 @@ public abstract class AbstractServiceProviderFilter implements ContainerRequestF } } + @PreDestroy + public synchronized void cleanup() { + if (configurator != null) { + List fedContextList = configurator.getFedizContextList(); + if (fedContextList != null) { + for (FedizContext fedContext : fedContextList) { + try { + fedContext.close(); + } catch (IOException ex) { + // + } + } + } + } + } + protected boolean checkSecurityContext(Message m) { HttpHeaders headers = new HttpHeadersImpl(m); Map cookies = headers.getCookies(); @@ -133,10 +148,9 @@ public abstract class AbstractServiceProviderFilter implements ContainerRequestF // Create SecurityContext try { - SamlAssertionWrapper assertionWrapper = - new SamlAssertionWrapper( - StaxUtils.read(new StringReader(responseState.getAssertion())).getDocumentElement()); - setSecurityContext(responseState, m, assertionWrapper); + Element token = + StaxUtils.read(new StringReader(responseState.getAssertion())).getDocumentElement(); + setSecurityContext(responseState, m, token); } catch (Exception ex) { reportError("INVALID_RESPONSE_STATE"); return false; @@ -146,11 +160,10 @@ public abstract class AbstractServiceProviderFilter implements ContainerRequestF } protected void setSecurityContext( - ResponseState responseState, Message m, SamlAssertionWrapper assertionWrapper + ResponseState responseState, Message m, Element token ) throws WSSecurityException { CXFFedizPrincipal principal = - new CXFFedizPrincipal(responseState.getSubject(), responseState.getClaims(), - assertionWrapper.toDOM(DOMUtils.createDocument())); + new CXFFedizPrincipal(responseState.getSubject(), responseState.getClaims(), token); SecurityTokenThreadLocal.setToken(principal.getLoginToken()); FedizSecurityContext context = @@ -171,6 +184,7 @@ public abstract class AbstractServiceProviderFilter implements ContainerRequestF String contextKey = securityContextCookie.getValue(); FedizContext fedizConfig = getFedizContext(m); + SAMLProtocol protocol = (SAMLProtocol)fedizConfig.getProtocol(); ResponseState responseState = protocol.getStateManager().getResponseState(contextKey); @@ -178,11 +192,14 @@ public abstract class AbstractServiceProviderFilter implements ContainerRequestF reportError("MISSING_RESPONSE_STATE"); return null; } - if (isStateExpired(responseState.getCreatedAt(), responseState.getExpiresAt(), fedizConfig)) { + + if (CookieUtils.isStateExpired(responseState.getCreatedAt(), responseState.getExpiresAt(), + protocol.getStateTimeToLive())) { reportError("EXPIRED_RESPONSE_STATE"); protocol.getStateManager().removeResponseState(contextKey); return null; } + // TODO String webAppContext = getWebAppContext(m); if (webAppDomain != null && (responseState.getWebAppDomain() == null @@ -200,53 +217,6 @@ public abstract class AbstractServiceProviderFilter implements ContainerRequestF return responseState; } - protected String createCookie(String name, - String value, - String path, - String domain, - long stateTimeToLive) { - - String contextCookie = name + "=" + value; - // Setting a specific path restricts the browsers - // to return a cookie only to the web applications - // listening on that specific context path - if (path != null) { - contextCookie += ";Path=" + path; - } - - // Setting a specific domain further restricts the browsers - // to return a cookie only to the web applications - // listening on the specific context path within a particular domain - if (domain != null) { - contextCookie += ";Domain=" + domain; - } - - // Keep the cookie across the browser restarts until it actually expires. - // Note that the Expires property has been deprecated but apparently is - // supported better than 'max-age' property by different browsers - // (Firefox, IE, etc) - Date expiresDate = new Date(System.currentTimeMillis() + stateTimeToLive); - String cookieExpires = HttpUtils.getHttpDateFormat().format(expiresDate); - contextCookie += ";Expires=" + cookieExpires; - //TODO: Consider adding an 'HttpOnly' attribute - - return contextCookie; - } - - protected boolean isStateExpired(long stateCreatedAt, long expiresAt, FedizContext fedizConfig) { - Date currentTime = new Date(); - long stateTimeToLive = ((SAMLProtocol)fedizConfig.getProtocol()).getStateTimeToLive(); - if (currentTime.after(new Date(stateCreatedAt + stateTimeToLive))) { - return true; - } - - if (expiresAt > 0 && currentTime.after(new Date(expiresAt))) { - return true; - } - - return false; - } - protected FedizContext getFedizContext(Message message) { String contextName = new UriInfoImpl(message).getRequestUri().getPath(); if (contextName == null || contextName.isEmpty()) { @@ -265,12 +235,9 @@ public abstract class AbstractServiceProviderFilter implements ContainerRequestF } FedizContext config = configurator.getFedizContext(contextName); if (config == null) { - throw new IllegalStateException("No Fediz configuration for context :" + contextName); - } - String catalinaBase = System.getProperty("catalina.base"); - if (catalinaBase != null && catalinaBase.length() > 0) { - config.setRelativePath(catalinaBase); + throw new IllegalStateException("No Fediz configuration for context: " + contextName); } + return config; } @@ -287,9 +254,8 @@ public abstract class AbstractServiceProviderFilter implements ContainerRequestF LOG.debug(errorMsg.toString()); } } -/* - * TODO - private String getWebAppContext(Message m) { + + protected String getWebAppContext(Message m) { if (addWebAppContext) { if (addEndpointAddressToContext) { return new UriInfoImpl(m).getBaseUri().getRawPath(); @@ -301,7 +267,7 @@ public abstract class AbstractServiceProviderFilter implements ContainerRequestF return "/"; } } - */ + public String getWebAppDomain() { return webAppDomain; } @@ -309,10 +275,9 @@ public abstract class AbstractServiceProviderFilter implements ContainerRequestF public void setWebAppDomain(String webAppDomain) { this.webAppDomain = webAppDomain; } -/* + public void setAddWebAppContext(boolean addWebAppContext) { this.addWebAppContext = addWebAppContext; } - */ } http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/863f99bd/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/CXFFedizPrincipal.java ---------------------------------------------------------------------- diff --git a/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/CXFFedizPrincipal.java b/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/CXFFedizPrincipal.java index 787883f..3fde312 100644 --- a/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/CXFFedizPrincipal.java +++ b/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/CXFFedizPrincipal.java @@ -29,7 +29,7 @@ public class CXFFedizPrincipal implements FedizPrincipal { private final String subject; private final List claims; - private final Element token; + private Element token; public CXFFedizPrincipal(String subject, List claims, Element token) { this.subject = subject; http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/863f99bd/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/SamlRedirectBindingFilter.java ---------------------------------------------------------------------- diff --git a/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/SamlRedirectBindingFilter.java b/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/SamlRedirectBindingFilter.java index a456f21..a31e0e2 100644 --- a/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/SamlRedirectBindingFilter.java +++ b/plugins/cxf/src/main/java/org/apache/cxf/fediz/cxf/plugin/SamlRedirectBindingFilter.java @@ -45,6 +45,7 @@ import org.apache.cxf.fediz.core.processor.FedizRequest; import org.apache.cxf.fediz.core.processor.FedizResponse; import org.apache.cxf.fediz.core.processor.RedirectionResponse; import org.apache.cxf.fediz.core.samlsso.ResponseState; +import org.apache.cxf.fediz.core.util.CookieUtils; import org.apache.cxf.jaxrs.ext.MessageContext; import org.apache.cxf.jaxrs.impl.UriInfoImpl; import org.apache.cxf.jaxrs.utils.ExceptionUtils; @@ -63,6 +64,10 @@ public class SamlRedirectBindingFilter extends AbstractServiceProviderFilter { public void filter(ContainerRequestContext context) { Message m = JAXRSUtils.getCurrentMessage(); + + String webAppContext = getWebAppContext(m); + System.out.println("WEB APP CTX: " + webAppContext); + if (checkSecurityContext(m)) { return; } else { @@ -154,7 +159,7 @@ public class SamlRedirectBindingFilter extends AbstractServiceProviderFilter { } ResponseState responseState = - new ResponseState(token, // TODO + new ResponseState(token, params.getFirst("RelayState"), null, // TODO webAppDomain, @@ -167,7 +172,7 @@ public class SamlRedirectBindingFilter extends AbstractServiceProviderFilter { protocol.getStateManager().setResponseState(securityContextKey, responseState); long stateTimeToLive = protocol.getStateTimeToLive(); - String contextCookie = createCookie(SECURITY_CONTEXT_TOKEN, + String contextCookie = CookieUtils.createCookie(SECURITY_CONTEXT_TOKEN, securityContextKey, null, // TODO webAppDomain,