Added: cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/client/SamlRoleCallbackHandler.java URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/client/SamlRoleCallbackHandler.java?rev=1414652&view=auto ============================================================================== --- cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/client/SamlRoleCallbackHandler.java (added) +++ cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/client/SamlRoleCallbackHandler.java Wed Nov 28 12:47:26 2012 @@ -0,0 +1,155 @@ +/** + * 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.systest.ws.saml.client; + +import java.io.IOException; +import java.security.cert.X509Certificate; +import java.util.Collections; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.UnsupportedCallbackException; + +import org.apache.ws.security.components.crypto.Crypto; +import org.apache.ws.security.components.crypto.CryptoFactory; +import org.apache.ws.security.components.crypto.CryptoType; +import org.apache.ws.security.saml.ext.SAMLCallback; +import org.apache.ws.security.saml.ext.bean.AttributeBean; +import org.apache.ws.security.saml.ext.bean.AttributeStatementBean; +import org.apache.ws.security.saml.ext.bean.KeyInfoBean; +import org.apache.ws.security.saml.ext.bean.KeyInfoBean.CERT_IDENTIFIER; +import org.apache.ws.security.saml.ext.bean.SubjectBean; +import org.apache.ws.security.saml.ext.builder.SAML1Constants; +import org.apache.ws.security.saml.ext.builder.SAML2Constants; +import org.opensaml.common.SAMLVersion; + +/** + * A CallbackHandler instance that is used by the STS to mock up a SAML Attribute Assertion. + */ +public class SamlRoleCallbackHandler implements CallbackHandler { + private static final String ROLE_URI = + "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"; + private boolean saml2 = true; + private String confirmationMethod = SAML2Constants.CONF_SENDER_VOUCHES; + private CERT_IDENTIFIER keyInfoIdentifier = CERT_IDENTIFIER.X509_CERT; + private String roleName; + + public SamlRoleCallbackHandler() { + // + } + + public SamlRoleCallbackHandler(boolean saml2) { + this.saml2 = saml2; + } + + public void setConfirmationMethod(String confirmationMethod) { + this.confirmationMethod = confirmationMethod; + } + + public void setKeyInfoIdentifier(CERT_IDENTIFIER keyInfoIdentifier) { + this.keyInfoIdentifier = keyInfoIdentifier; + } + + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + for (int i = 0; i < callbacks.length; i++) { + if (callbacks[i] instanceof SAMLCallback) { + SAMLCallback callback = (SAMLCallback) callbacks[i]; + if (saml2) { + callback.setSamlVersion(SAMLVersion.VERSION_20); + } else { + callback.setSamlVersion(SAMLVersion.VERSION_11); + } + callback.setIssuer("sts"); + String subjectName = "uid=sts-client,o=mock-sts.com"; + String subjectQualifier = "www.mock-sts.com"; + if (!saml2 && SAML2Constants.CONF_SENDER_VOUCHES.equals(confirmationMethod)) { + confirmationMethod = SAML1Constants.CONF_SENDER_VOUCHES; + } + SubjectBean subjectBean = + new SubjectBean( + subjectName, subjectQualifier, confirmationMethod + ); + if (SAML2Constants.CONF_HOLDER_KEY.equals(confirmationMethod) + || SAML1Constants.CONF_HOLDER_KEY.equals(confirmationMethod)) { + try { + KeyInfoBean keyInfo = createKeyInfo(); + subjectBean.setKeyInfo(keyInfo); + } catch (Exception ex) { + throw new IOException("Problem creating KeyInfo: " + ex.getMessage()); + } + } + callback.setSubject(subjectBean); + + AttributeStatementBean attrBean = new AttributeStatementBean(); + attrBean.setSubject(subjectBean); + + AttributeBean attributeBean = new AttributeBean(); + attributeBean.setNameFormat(SAML2Constants.ATTRNAME_FORMAT_UNSPECIFIED); + if (saml2) { + attributeBean.setQualifiedName(ROLE_URI); + attributeBean.setNameFormat(SAML2Constants.ATTRNAME_FORMAT_UNSPECIFIED); + } else { + String uri = ROLE_URI.toString(); + int lastSlash = uri.lastIndexOf("/"); + if (lastSlash == (uri.length() - 1)) { + uri = uri.substring(0, lastSlash); + lastSlash = uri.lastIndexOf("/"); + } + + String namespace = uri.substring(0, lastSlash); + String name = uri.substring(lastSlash + 1, uri.length()); + + attributeBean.setSimpleName(name); + attributeBean.setQualifiedName(namespace); + } + attributeBean.setAttributeValues(Collections.singletonList(roleName)); + attrBean.setSamlAttributes(Collections.singletonList(attributeBean)); + callback.setAttributeStatementData(Collections.singletonList(attrBean)); + } + } + } + + protected KeyInfoBean createKeyInfo() throws Exception { + Crypto crypto = + CryptoFactory.getInstance("org/apache/cxf/systest/ws/wssec10/client/alice.properties"); + CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS); + cryptoType.setAlias("alice"); + X509Certificate[] certs = crypto.getX509Certificates(cryptoType); + + KeyInfoBean keyInfo = new KeyInfoBean(); + keyInfo.setCertIdentifer(keyInfoIdentifier); + if (keyInfoIdentifier == CERT_IDENTIFIER.X509_CERT) { + keyInfo.setCertificate(certs[0]); + } else if (keyInfoIdentifier == CERT_IDENTIFIER.KEY_VALUE) { + keyInfo.setPublicKey(certs[0].getPublicKey()); + } + + return keyInfo; + } + + public String getRoleName() { + return roleName; + } + + public void setRoleName(String roleName) { + this.roleName = roleName; + } + +}
Added: cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/server/XACMLAuthorizingInterceptor.java URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/server/XACMLAuthorizingInterceptor.java?rev=1414652&view=auto ============================================================================== --- cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/server/XACMLAuthorizingInterceptor.java (added) +++ cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/server/XACMLAuthorizingInterceptor.java Wed Nov 28 12:47:26 2012 @@ -0,0 +1,118 @@ +/** + * 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.systest.ws.saml.server; + +import java.util.List; + +import org.apache.cxf.message.Message; +import org.apache.cxf.rt.security.xacml.AbstractXACMLAuthorizingInterceptor; +import org.apache.cxf.rt.security.xacml.XACMLConstants; +import org.opensaml.Configuration; +import org.opensaml.xacml.XACMLObjectBuilder; +import org.opensaml.xacml.ctx.AttributeType; +import org.opensaml.xacml.ctx.DecisionType; +import org.opensaml.xacml.ctx.RequestType; +import org.opensaml.xacml.ctx.ResponseType; +import org.opensaml.xacml.ctx.ResultType; +import org.opensaml.xacml.ctx.StatusCodeType; +import org.opensaml.xacml.ctx.StatusType; +import org.opensaml.xacml.ctx.SubjectType; +import org.opensaml.xml.XMLObjectBuilderFactory; + + +/** + * A test implementation of AbstractXACMLAuthorizingInterceptor. It just mocks up a Response + * object based on the role of the Subject. If the role is "manager" then it permits the + * request, otherwise it denies it. + */ +public class XACMLAuthorizingInterceptor extends AbstractXACMLAuthorizingInterceptor { + + public ResponseType performRequest(RequestType request, Message message) throws Exception { + + XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory(); + + @SuppressWarnings("unchecked") + XACMLObjectBuilder<ResponseType> responseTypeBuilder = + (XACMLObjectBuilder<ResponseType>) + builderFactory.getBuilder(ResponseType.DEFAULT_ELEMENT_NAME); + + @SuppressWarnings("unchecked") + XACMLObjectBuilder<ResultType> resultTypeBuilder = + (XACMLObjectBuilder<ResultType>) + builderFactory.getBuilder(ResultType.DEFAULT_ELEMENT_NAME); + + @SuppressWarnings("unchecked") + XACMLObjectBuilder<DecisionType> decisionTypeBuilder = + (XACMLObjectBuilder<DecisionType>) + builderFactory.getBuilder(DecisionType.DEFAULT_ELEMENT_NAME); + + @SuppressWarnings("unchecked") + XACMLObjectBuilder<StatusType> statusTypeBuilder = + (XACMLObjectBuilder<StatusType>) + builderFactory.getBuilder(StatusType.DEFAULT_ELEMENT_NAME); + + @SuppressWarnings("unchecked") + XACMLObjectBuilder<StatusCodeType> statusCodeTypeBuilder = + (XACMLObjectBuilder<StatusCodeType>) + builderFactory.getBuilder(StatusCodeType.DEFAULT_ELEMENT_NAME); + + DecisionType decisionType = decisionTypeBuilder.buildObject(); + + String role = getSubjectRole(request); + if ("manager".equals(role)) { + decisionType.setDecision(DecisionType.DECISION.Permit); + } else { + decisionType.setDecision(DecisionType.DECISION.Deny); + } + + ResultType result = resultTypeBuilder.buildObject(); + result.setDecision(decisionType); + + StatusType status = statusTypeBuilder.buildObject(); + StatusCodeType statusCode = statusCodeTypeBuilder.buildObject(); + statusCode.setValue("urn:oasis:names:tc:xacml:1.0:status:ok"); + status.setStatusCode(statusCode); + result.setStatus(status); + + ResponseType response = responseTypeBuilder.buildObject(); + response.setResult(result); + + return response; + } + + private String getSubjectRole(RequestType request) { + List<SubjectType> subjects = request.getSubjects(); + if (subjects != null) { + for (SubjectType subject : subjects) { + List<AttributeType> attributes = subject.getAttributes(); + if (attributes != null) { + for (AttributeType attribute : attributes) { + if (XACMLConstants.SUBJECT_ROLE.equals(attribute.getAttributeID())) { + return attribute.getAttributeValues().get(0).getValue(); + } + } + } + } + } + return null; + } + + +} Modified: cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/DoubleItSaml.wsdl URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/DoubleItSaml.wsdl?rev=1414652&r1=1414651&r2=1414652&view=diff ============================================================================== --- cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/DoubleItSaml.wsdl (original) +++ cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/DoubleItSaml.wsdl Wed Nov 28 12:47:26 2012 @@ -347,6 +347,10 @@ <wsdl:port name="DoubleItInlinePolicyPort" binding="tns:DoubleItInlinePolicyBinding"> <soap:address location="https://localhost:9009/DoubleItSamlInlinePolicy" /> </wsdl:port> + <wsdl:port name="DoubleItSaml2PEPPort" + binding="tns:DoubleItSaml2SymmetricBinding"> + <soap:address location="http://localhost:9001/DoubleItSaml2PEP" /> + </wsdl:port> </wsdl:service> <wsp:Policy wsu:Id="DoubleItSaml1TransportPolicy"> Modified: cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/client/client.xml URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/client/client.xml?rev=1414652&r1=1414651&r2=1414652&view=diff ============================================================================== --- cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/client/client.xml (original) +++ cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/client/client.xml Wed Nov 28 12:47:26 2012 @@ -258,6 +258,15 @@ </wsp:Policy> </p:policies> </jaxws:features> - </jaxws:client> + </jaxws:client> + + <jaxws:client name="{http://www.example.org/contract/DoubleIt}DoubleItSaml2PEPPort" + createdFromAPI="true"> + <jaxws:properties> + <entry key="ws-security.encryption.properties" + value="org/apache/cxf/systest/ws/wssec10/client/bob.properties"/> + <entry key="ws-security.encryption.username" value="bob"/> + </jaxws:properties> + </jaxws:client> </beans> Modified: cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/server/server.xml URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/server/server.xml?rev=1414652&r1=1414651&r2=1414652&view=diff ============================================================================== --- cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/server/server.xml (original) +++ cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/server/server.xml Wed Nov 28 12:47:26 2012 @@ -378,4 +378,30 @@ </jaxws:endpoint> + <bean class="org.apache.cxf.systest.ws.saml.server.XACMLAuthorizingInterceptor" + id="XACMLInterceptor"> + </bean> + + <jaxws:endpoint + id="Saml2TokenOverSymmetricPEP" + address="http://localhost:${testutil.ports.Server}/DoubleItSaml2PEP" + serviceName="s:DoubleItService" + endpointName="s:DoubleItSaml2PEPPort" + xmlns:s="http://www.example.org/contract/DoubleIt" + implementor="org.apache.cxf.systest.ws.common.DoubleItPortTypeImpl" + wsdlLocation="org/apache/cxf/systest/ws/saml/DoubleItSaml.wsdl"> + + <jaxws:properties> + <entry key="ws-security.callback-handler" + value="org.apache.cxf.systest.ws.wssec10.client.KeystorePasswordCallback"/> + <entry key="ws-security.signature.properties" + value="org/apache/cxf/systest/ws/wssec10/client/bob.properties"/> + <entry key="ws-security.saml2.validator" + value="org.apache.cxf.systest.ws.saml.server.CustomSaml2Validator"/> + </jaxws:properties> + <jaxws:inInterceptors> + <ref bean="XACMLInterceptor"/> + </jaxws:inInterceptors> + </jaxws:endpoint> + </beans>
