FEDIZ-197: Use local Port to call STS. This closes #15
STSAuthenticationProvider now handles local port (:0) on wsdlLocation. If such a port is used for wsdlLocation, STSAuthenticationProvider will use the localServer port to retrieve the wsdl. Note: org.springframework.web.filter.RequestContextFilter needs to be set for this to work. Signed-off-by: Colm O hEigeartaigh <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/36480e97 Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/36480e97 Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/36480e97 Branch: refs/heads/master Commit: 36480e97003185385e81bf5cbf8c23cee08dffef Parents: 07ce857 Author: gonzalad <[email protected]> Authored: Wed Mar 29 13:39:03 2017 +0200 Committer: Colm O hEigeartaigh <[email protected]> Committed: Wed Mar 29 16:08:18 2017 +0100 ---------------------------------------------------------------------- .../service/idp/STSAuthenticationProvider.java | 92 +++++++++--------- .../idp/STSKrbAuthenticationProvider.java | 2 +- .../idp/STSPreAuthAuthenticationProvider.java | 2 +- .../idp/STSUPAuthenticationProvider.java | 2 +- .../service/idp/beans/STSClientAction.java | 87 +++++++---------- .../service/idp/util/LocalServerResolver.java | 98 ++++++++++++++++++++ 6 files changed, 178 insertions(+), 105 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/36480e97/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSAuthenticationProvider.java ---------------------------------------------------------------------- diff --git a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSAuthenticationProvider.java b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSAuthenticationProvider.java index d42904b..9310d5c 100644 --- a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSAuthenticationProvider.java +++ b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSAuthenticationProvider.java @@ -29,9 +29,9 @@ import org.w3c.dom.Element; import org.apache.cxf.Bus; import org.apache.cxf.BusFactory; -//import org.apache.cxf.endpoint.Client; import org.apache.cxf.fediz.core.Claim; import org.apache.cxf.fediz.core.ClaimTypes; +import org.apache.cxf.fediz.service.idp.util.LocalServerResolver; import org.apache.cxf.ws.security.tokenstore.SecurityToken; import org.apache.wss4j.common.ext.WSSecurityException; import org.apache.wss4j.common.saml.SamlAssertionWrapper; @@ -41,8 +41,6 @@ import org.slf4j.LoggerFactory; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; -//import org.apache.cxf.transport.http.HTTPConduit; -//import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; /** * A base class for authenticating credentials to the STS @@ -50,45 +48,34 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; public abstract class STSAuthenticationProvider implements AuthenticationProvider { public static final String HTTP_DOCS_OASIS_OPEN_ORG_WS_SX_WS_TRUST_200512_BEARER = - "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer"; + "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer"; public static final String HTTP_DOCS_OASIS_OPEN_ORG_WS_SX_WS_TRUST_200512 = - "http://docs.oasis-open.org/ws-sx/ws-trust/200512/"; + "http://docs.oasis-open.org/ws-sx/ws-trust/200512/"; public static final String HTTP_SCHEMAS_XMLSOAP_ORG_WS_2005_02_TRUST = - "http://schemas.xmlsoap.org/ws/2005/02/trust"; + "http://schemas.xmlsoap.org/ws/2005/02/trust"; private static final Logger LOG = LoggerFactory.getLogger(STSAuthenticationProvider.class); - - protected String wsdlLocation; - protected String namespace = HTTP_DOCS_OASIS_OPEN_ORG_WS_SX_WS_TRUST_200512; - protected String wsdlService; - protected String wsdlEndpoint; - protected String appliesTo; - protected boolean use200502Namespace; - protected String tokenType; - protected Bus bus; - protected Integer lifetime; - - //Required to get IDP roles to use the IDP application, used in future release + // Required to get IDP roles to use the IDP application, used in future release protected String roleURI; - protected Map<String, Object> properties = new HashMap<>(); - + private String wsdlLocation; + private boolean isPortSet; private String customSTSParameter; protected List<GrantedAuthority> createAuthorities(SecurityToken token) throws WSSecurityException { List<GrantedAuthority> authorities = new ArrayList<>(); - //authorities.add(new SimpleGrantedAuthority("ROLE_AUTHENTICATED")); - //Not needed because AuthenticatedVoter has been added for SecurityFlowExecutionListener + // authorities.add(new SimpleGrantedAuthority("ROLE_AUTHENTICATED")); + // Not needed because AuthenticatedVoter has been added for SecurityFlowExecutionListener if (roleURI != null) { SamlAssertionWrapper assertion = new SamlAssertionWrapper(token.getToken()); @@ -98,7 +85,7 @@ public abstract class STSAuthenticationProvider implements AuthenticationProvide Object oValue = c.getValue(); if ((oValue instanceof List<?>) && !((List<?>)oValue).isEmpty()) { List<?> values = (List<?>)oValue; - for (Object role: values) { + for (Object role : values) { if (role instanceof String) { authorities.add(new SimpleGrantedAuthority((String)role)); } @@ -113,18 +100,27 @@ public abstract class STSAuthenticationProvider implements AuthenticationProvide } } - //Add IDP_LOGIN role to be able to access resource Idp, TrustedIdp, etc. + // Add IDP_LOGIN role to be able to access resource Idp, TrustedIdp, etc. authorities.add(new SimpleGrantedAuthority("ROLE_IDP_LOGIN")); return authorities; } public String getWsdlLocation() { + if (!isPortSet) { + setSTSWsdlUrl(LocalServerResolver.resolve(this.wsdlLocation)); + } return wsdlLocation; } public void setWsdlLocation(String wsdlLocation) { this.wsdlLocation = wsdlLocation; + this.isPortSet = !LocalServerResolver.isLocal(this.wsdlLocation); + } + + private synchronized void setSTSWsdlUrl(String wsdlUrl) { + this.wsdlLocation = wsdlUrl; + this.isPortSet = true; } public String getWsdlService() { @@ -159,15 +155,15 @@ public abstract class STSAuthenticationProvider implements AuthenticationProvide this.appliesTo = appliesTo; } - public void setBus(Bus bus) { - this.bus = bus; - } - public Bus getBus() { // do not store a referance to the default bus return (bus != null) ? bus : BusFactory.getDefaultBus(); } + public void setBus(Bus bus) { + this.bus = bus; + } + public String getTokenType() { return tokenType; } @@ -186,7 +182,7 @@ public abstract class STSAuthenticationProvider implements AuthenticationProvide protected List<Claim> parseClaimsInAssertion(org.opensaml.saml.saml2.core.Assertion assertion) { List<org.opensaml.saml.saml2.core.AttributeStatement> attributeStatements = assertion - .getAttributeStatements(); + .getAttributeStatements(); if (attributeStatements == null || attributeStatements.isEmpty()) { LOG.debug("No attribute statements found"); return Collections.emptyList(); @@ -197,8 +193,7 @@ public abstract class STSAuthenticationProvider implements AuthenticationProvide for (org.opensaml.saml.saml2.core.AttributeStatement statement : attributeStatements) { LOG.debug("parsing statement: {}", statement.getElementQName()); - List<org.opensaml.saml.saml2.core.Attribute> attributes = statement - .getAttributes(); + List<org.opensaml.saml.saml2.core.Attribute> attributes = statement.getAttributes(); for (org.opensaml.saml.saml2.core.Attribute attribute : attributes) { LOG.debug("parsing attribute: {}", attribute.getName()); Claim c = new Claim(); @@ -230,20 +225,19 @@ public abstract class STSAuthenticationProvider implements AuthenticationProvide } - protected void mergeClaimToMap(Map<String, Claim> claimsMap, Claim c, - List<String> valueList) { + protected void mergeClaimToMap(Map<String, Claim> claimsMap, Claim c, List<String> valueList) { Claim t = claimsMap.get(c.getClaimType().toString()); if (t != null) { - //same SAML attribute already processed. Thus Claim object already created. + // same SAML attribute already processed. Thus Claim object already created. Object oValue = t.getValue(); if (oValue instanceof String) { - //one child element AttributeValue only + // one child element AttributeValue only List<String> values = new ArrayList<>(); - values.add((String)oValue); //add existing value + values.add((String)oValue); // add existing value values.addAll(valueList); t.setValue(values); } else if (oValue instanceof List<?>) { - //more than one child element AttributeValue + // more than one child element AttributeValue @SuppressWarnings("unchecked") List<String> values = (List<String>)oValue; values.addAll(valueList); @@ -271,14 +265,14 @@ public abstract class STSAuthenticationProvider implements AuthenticationProvide this.roleURI = roleURI; } - public void setProperties(Map<String, Object> p) { - properties.putAll(p); - } - public Map<String, Object> getProperties() { return properties; } + public void setProperties(Map<String, Object> p) { + properties.putAll(p); + } + public boolean isUse200502Namespace() { return use200502Namespace; } @@ -295,13 +289,13 @@ public abstract class STSAuthenticationProvider implements AuthenticationProvide this.customSTSParameter = customSTSParameter; } -//May be uncommented for debugging -// private void setTimeout(Client client, Long timeout) { -// HTTPConduit conduit = (HTTPConduit) client.getConduit(); -// HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); -// httpClientPolicy.setConnectionTimeout(timeout); -// httpClientPolicy.setReceiveTimeout(timeout); -// conduit.setClient(httpClientPolicy); -// } + // May be uncommented for debugging + // private void setTimeout(Client client, Long timeout) { + // HTTPConduit conduit = (HTTPConduit) client.getConduit(); + // HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); + // httpClientPolicy.setConnectionTimeout(timeout); + // httpClientPolicy.setReceiveTimeout(timeout); + // conduit.setClient(httpClientPolicy); + // } } http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/36480e97/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSKrbAuthenticationProvider.java ---------------------------------------------------------------------- diff --git a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSKrbAuthenticationProvider.java b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSKrbAuthenticationProvider.java index 5e80466..3efbf08 100644 --- a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSKrbAuthenticationProvider.java +++ b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSKrbAuthenticationProvider.java @@ -80,7 +80,7 @@ public class STSKrbAuthenticationProvider extends STSAuthenticationProvider { sts.setTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE); } sts.setKeyType(HTTP_DOCS_OASIS_OPEN_ORG_WS_SX_WS_TRUST_200512_BEARER); - sts.setWsdlLocation(wsdlLocation); + sts.setWsdlLocation(getWsdlLocation()); sts.setServiceQName(new QName(namespace, wsdlService)); sts.setEndpointQName(new QName(namespace, wsdlEndpoint)); http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/36480e97/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSPreAuthAuthenticationProvider.java ---------------------------------------------------------------------- diff --git a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSPreAuthAuthenticationProvider.java b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSPreAuthAuthenticationProvider.java index e6e3629..38bfa7c 100644 --- a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSPreAuthAuthenticationProvider.java +++ b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSPreAuthAuthenticationProvider.java @@ -61,7 +61,7 @@ public class STSPreAuthAuthenticationProvider extends STSAuthenticationProvider sts.setTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE); } sts.setKeyType(HTTP_DOCS_OASIS_OPEN_ORG_WS_SX_WS_TRUST_200512_BEARER); - sts.setWsdlLocation(wsdlLocation); + sts.setWsdlLocation(getWsdlLocation()); sts.setServiceQName(new QName(namespace, wsdlService)); sts.setEndpointQName(new QName(namespace, wsdlEndpoint)); http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/36480e97/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSUPAuthenticationProvider.java ---------------------------------------------------------------------- diff --git a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSUPAuthenticationProvider.java b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSUPAuthenticationProvider.java index 7e166f3..97e96db 100644 --- a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSUPAuthenticationProvider.java +++ b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/STSUPAuthenticationProvider.java @@ -65,7 +65,7 @@ public class STSUPAuthenticationProvider extends STSAuthenticationProvider { sts.setTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE); } sts.setKeyType(HTTP_DOCS_OASIS_OPEN_ORG_WS_SX_WS_TRUST_200512_BEARER); - sts.setWsdlLocation(wsdlLocation); + sts.setWsdlLocation(getWsdlLocation()); sts.setServiceQName(new QName(namespace, wsdlService)); sts.setEndpointQName(new QName(namespace, wsdlEndpoint)); http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/36480e97/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/beans/STSClientAction.java ---------------------------------------------------------------------- diff --git a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/beans/STSClientAction.java b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/beans/STSClientAction.java index ff9f65f..3817380 100644 --- a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/beans/STSClientAction.java +++ b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/beans/STSClientAction.java @@ -20,8 +20,6 @@ package org.apache.cxf.fediz.service.idp.beans; import java.io.IOException; import java.io.StringReader; -import java.net.MalformedURLException; -import java.net.URL; import java.security.cert.X509Certificate; import java.util.List; import java.util.Map; @@ -34,6 +32,7 @@ import javax.xml.stream.XMLStreamException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; + import org.apache.cxf.Bus; import org.apache.cxf.BusFactory; import org.apache.cxf.binding.soap.SoapFault; @@ -45,6 +44,7 @@ import org.apache.cxf.fediz.service.idp.IdpSTSClient; import org.apache.cxf.fediz.service.idp.domain.Application; import org.apache.cxf.fediz.service.idp.domain.Idp; import org.apache.cxf.fediz.service.idp.domain.RequestClaim; +import org.apache.cxf.fediz.service.idp.util.LocalServerResolver; import org.apache.cxf.fediz.service.idp.util.WebUtils; import org.apache.cxf.staxutils.W3CDOMStreamWriter; import org.apache.cxf.ws.security.tokenstore.SecurityToken; @@ -76,12 +76,11 @@ public class STSClientAction { "http://docs.oasis-open.org/ws-sx/ws-trust/200512/"; private static final String HTTP_SCHEMAS_XMLSOAP_ORG_WS_2005_02_TRUST = - "http://schemas.xmlsoap.org/ws/2005/02/trust"; + "http://schemas.xmlsoap.org/ws/2005/02/trust"; private static final String SECURITY_TOKEN_SERVICE = "SecurityTokenService"; - private static final Logger LOG = LoggerFactory - .getLogger(STSClientAction.class); + private static final Logger LOG = LoggerFactory.getLogger(STSClientAction.class); protected String namespace = HTTP_DOCS_OASIS_OPEN_ORG_WS_SX_WS_TRUST_200512; @@ -107,21 +106,15 @@ public class STSClientAction { private String customSTSParameter; - public String getWsdlLocation() { return wsdlLocation; } public void setWsdlLocation(String wsdlLocation) { this.wsdlLocation = wsdlLocation; - try { - URL url = new URL(wsdlLocation); - isPortSet = url.getPort() != 0; - if (!isPortSet) { - LOG.info("Port is 0 for 'wsdlLocation'. Port evaluated when processing first request."); - } - } catch (MalformedURLException e) { - LOG.error("Invalid Url '" + wsdlLocation + "': " + e.getMessage()); + isPortSet = !LocalServerResolver.isLocal(wsdlLocation); + if (!isPortSet) { + LOG.info("Port is 0 for 'wsdlLocation'. Port evaluated when processing first request."); } } @@ -149,15 +142,15 @@ public class STSClientAction { this.namespace = namespace; } - public void setBus(Bus bus) { - this.bus = bus; - } - public Bus getBus() { // do not store a referance to the default bus return (bus != null) ? bus : BusFactory.getDefaultBus(); } + public void setBus(Bus bus) { + this.bus = bus; + } + public String getTokenType() { return tokenType; } @@ -188,13 +181,12 @@ public class STSClientAction { * @return a RP security token * @throws Exception */ - public Element submit(RequestContext context, String realm, String homeRealm) - throws Exception { + public Element submit(RequestContext context, String realm, String homeRealm) throws Exception { SecurityToken idpToken = getSecurityToken(context, homeRealm); Bus cxfBus = getBus(); - Idp idpConfig = (Idp) WebUtils.getAttributeFromFlowScope(context, "idpConfig"); + Idp idpConfig = (Idp)WebUtils.getAttributeFromFlowScope(context, "idpConfig"); IdpSTSClient sts = new IdpSTSClient(cxfBus); sts.setAddressingNamespace(HTTP_WWW_W3_ORG_2005_08_ADDRESSING); @@ -216,13 +208,13 @@ public class STSClientAction { if (wreqElement != null && "RequestSecurityToken".equals(wreqElement.getLocalName()) && (STSUtils.WST_NS_05_12.equals(wreqElement.getNamespaceURI()) || HTTP_SCHEMAS_XMLSOAP_ORG_WS_2005_02_TRUST.equals(wreqElement.getNamespaceURI()))) { - Element tokenTypeElement = - DOMUtils.getFirstChildWithName(wreqElement, wreqElement.getNamespaceURI(), "TokenType"); + Element tokenTypeElement = DOMUtils + .getFirstChildWithName(wreqElement, wreqElement.getNamespaceURI(), "TokenType"); if (tokenTypeElement != null) { stsTokenType = tokenTypeElement.getTextContent(); } - Element keyTypeElement = - DOMUtils.getFirstChildWithName(wreqElement, wreqElement.getNamespaceURI(), "KeyType"); + Element keyTypeElement = DOMUtils + .getFirstChildWithName(wreqElement, wreqElement.getNamespaceURI(), "KeyType"); if (keyTypeElement != null) { stsKeyType = keyTypeElement.getTextContent(); } @@ -251,8 +243,8 @@ public class STSClientAction { if (HTTP_DOCS_OASIS_OPEN_ORG_WS_SX_WS_TRUST_200512_PUBLICKEY.equals(stsKeyType)) { HttpServletRequest servletRequest = WebUtils.getHttpServletRequest(context); if (servletRequest != null) { - X509Certificate certs[] = - (X509Certificate[])servletRequest.getAttribute("javax.servlet.request.X509Certificate"); + X509Certificate certs[] = (X509Certificate[])servletRequest + .getAttribute("javax.servlet.request.X509Certificate"); if (certs != null && certs.length > 0) { sts.setUseCertificateForConfirmationKeyInfo(true); sts.setUseKeyCertificate(certs[0]); @@ -300,8 +292,7 @@ public class STSClientAction { rpToken = sts.requestSecurityTokenResponse(realm); } catch (SoapFault ex) { LOG.error("Error in retrieving a token", ex.getMessage()); - if (ex.getFaultCode() != null - && "RequestFailed".equals(ex.getFaultCode().getLocalPart())) { + if (ex.getFaultCode() != null && "RequestFailed".equals(ex.getFaultCode().getLocalPart())) { throw new ProcessingException(TYPE.BAD_REQUEST); } throw ex; @@ -310,8 +301,8 @@ public class STSClientAction { if (LOG.isInfoEnabled()) { String id = getIdFromToken(rpToken); - LOG.info("[RP_TOKEN={}] successfully created for realm [{}] on behalf of [IDP_TOKEN={}]", - id, realm, idpToken.getId()); + LOG.info("[RP_TOKEN={}] successfully created for realm [{}] on behalf of [IDP_TOKEN={}]", id, + realm, idpToken.getId()); } return rpToken; } @@ -327,7 +318,7 @@ public class STSClientAction { } if (nd.getLength() > 0) { - Element e = (Element) nd.item(0); + Element e = (Element)nd.item(0); if (e.hasAttributeNS(null, identifier)) { return e.getAttributeNS(null, identifier); } @@ -337,12 +328,13 @@ public class STSClientAction { return ""; } - private SecurityToken getSecurityToken(RequestContext context, String homeRealm) throws ProcessingException { + private SecurityToken getSecurityToken(RequestContext context, String homeRealm) + throws ProcessingException { - SecurityToken idpToken = (SecurityToken) WebUtils.getAttributeFromFlowScope(context, "idpToken"); + SecurityToken idpToken = (SecurityToken)WebUtils.getAttributeFromFlowScope(context, "idpToken"); if (idpToken != null) { - LOG.debug("[IDP_TOKEN={} successfully retrieved from cache for home realm [{}]", - idpToken.getId(), homeRealm); + LOG.debug("[IDP_TOKEN={} successfully retrieved from cache for home realm [{}]", idpToken.getId(), + homeRealm); } else { LOG.error("IDP_TOKEN not found"); throw new ProcessingException(TYPE.BAD_REQUEST); @@ -350,19 +342,11 @@ public class STSClientAction { return idpToken; } - private void processWsdlLocation(RequestContext context) { if (!isPortSet) { - try { - URL url = new URL(this.wsdlLocation); - URL updatedUrl = new URL(url.getProtocol(), url.getHost(), - WebUtils.getHttpServletRequest(context).getLocalPort(), url.getFile()); - - setSTSWsdlUrl(updatedUrl.toString()); - LOG.info("STS WSDL URL updated to {}", updatedUrl.toString()); - } catch (MalformedURLException e) { - LOG.error("Invalid Url '{}': {}", this.wsdlLocation, e.getMessage()); - } + String updatedUrl = LocalServerResolver.resolve(this.wsdlLocation, context); + setSTSWsdlUrl(updatedUrl); + LOG.info("STS WSDL URL updated to {}", updatedUrl.toString()); } } @@ -384,16 +368,13 @@ public class STSClientAction { W3CDOMStreamWriter writer = new W3CDOMStreamWriter(); writer.writeStartElement("wst", "Claims", STSUtils.WST_NS_05_12); writer.writeNamespace("wst", STSUtils.WST_NS_05_12); - writer.writeNamespace("ic", - HTTP_SCHEMAS_XMLSOAP_ORG_WS_2005_05_IDENTITY); - writer.writeAttribute("Dialect", - HTTP_SCHEMAS_XMLSOAP_ORG_WS_2005_05_IDENTITY); + writer.writeNamespace("ic", HTTP_SCHEMAS_XMLSOAP_ORG_WS_2005_05_IDENTITY); + writer.writeAttribute("Dialect", HTTP_SCHEMAS_XMLSOAP_ORG_WS_2005_05_IDENTITY); if (!realmClaims.isEmpty()) { for (RequestClaim item : realmClaims) { LOG.debug(" {}", item.getClaimType().toString()); - writer.writeStartElement("ic", "ClaimType", - HTTP_SCHEMAS_XMLSOAP_ORG_WS_2005_05_IDENTITY); + writer.writeStartElement("ic", "ClaimType", HTTP_SCHEMAS_XMLSOAP_ORG_WS_2005_05_IDENTITY); writer.writeAttribute("Uri", item.getClaimType().toString()); writer.writeAttribute("Optional", Boolean.toString(item.isOptional())); writer.writeEndElement(); http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/36480e97/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/util/LocalServerResolver.java ---------------------------------------------------------------------- diff --git a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/util/LocalServerResolver.java b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/util/LocalServerResolver.java new file mode 100644 index 0000000..eac1d9c --- /dev/null +++ b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/util/LocalServerResolver.java @@ -0,0 +1,98 @@ +/** + * 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.service.idp.util; + +import java.net.MalformedURLException; +import java.net.URL; + +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.webflow.execution.RequestContext; + +/** + * Detects if a given URL means the local server (useful in case IDP/STS are co-located). If port 0 is + * explicitly set, then {@link #resolve(String, RequestContext)} will replace the original URL with a url + * containing the local server port. + */ +public final class LocalServerResolver { + + private static final Logger LOG = LoggerFactory.getLogger(LocalServerResolver.class); + + private LocalServerResolver() { + } + + /** + * If url contains a 0 port, replaces it with the local server port. Otherwise returns url as-is (no + * modification). + */ + public static String resolve(String url) { + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + if (!(requestAttributes instanceof ServletRequestAttributes)) { + return url; + } + return resolve(url, ((ServletRequestAttributes)requestAttributes).getRequest()); + } + + public static String resolve(String url, RequestContext context) { + if (context == null) { + return url; + } + return resolve(url, WebUtils.getHttpServletRequest(context)); + } + + public static String resolve(String url, HttpServletRequest request) { + if (request == null) { + return url; + } + if (isLocal(url)) { + try { + URL urlValue = new URL(url); + URL updatedUrl = new URL(urlValue.getProtocol(), urlValue.getHost(), request.getLocalPort(), + urlValue.getFile()); + LOG.debug("URL updated to {}", updatedUrl.toString()); + return updatedUrl.toString(); + } catch (MalformedURLException e) { + LOG.error("Invalid Url '{}': {}", url, e.getMessage()); + } + } + return url; + } + + /** + * Returns true if the url represents a local server (that is port is explicitly set to 0) + */ + public static boolean isLocal(String url) { + boolean isLocal = false; + try { + URL urlValue = new URL(url); + isLocal = urlValue.getPort() == 0; + if (isLocal) { + LOG.info("Port is 0 used for {}. Local server port will be used.", url); + } + } catch (MalformedURLException e) { + LOG.error("Invalid Url '" + url + "': " + e.getMessage()); + } + return isLocal; + } +}
