Author: sergeyb
Date: Mon Mar  5 14:32:40 2012
New Revision: 1297072

URL: http://svn.apache.org/viewvc?rev=1297072&view=rev
Log:
[CXF-3589] Prototyping the skeleton code for supporting saml web sso on the SP 
side based on Colm's test

Added:
    
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/
    
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/RequestAssertionConsumerService.java
   (with props)
    
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/
    
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/AbstractServiceProviderFilter.java
   (with props)
    
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlPostBindingFilter.java
   (with props)
    
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlRedirectBindingFilter.java
   (with props)
    
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlRequestInfo.java
   (with props)
    
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlpRequestComponentBuilder.java
   (with props)

Added: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/RequestAssertionConsumerService.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/RequestAssertionConsumerService.java?rev=1297072&view=auto
==============================================================================
--- 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/RequestAssertionConsumerService.java
 (added)
+++ 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/RequestAssertionConsumerService.java
 Mon Mar  5 14:32:40 2012
@@ -0,0 +1,128 @@
+/**
+ * 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.rs.security.saml.sso;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.zip.DataFormatException;
+
+import javax.ws.rs.Encoded;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+
+import org.w3c.dom.Document;
+
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.rs.security.saml.DeflateEncoderDecoder;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.saml.ext.OpenSAMLUtil;
+import org.opensaml.xml.XMLObject;
+
+@Path("sso")
+public class RequestAssertionConsumerService {
+    private static final String SAML_RESPONSE = "SAMLResponse"; 
+    private static final String RELAY_STATE = "RelayState";
+
+    private boolean useDeflateEncoding = true;
+    
+    @POST
+    @Produces(MediaType.APPLICATION_FORM_URLENCODED)
+    public Response processSamlResponse(@Encoded @FormParam(RELAY_STATE) 
String relayState,
+                                     @Encoded @FormParam(SAML_RESPONSE) String 
encodedSamlResponse) {
+        org.opensaml.saml2.core.Response samlResponse = 
+            readSAMLResponse(encodedSamlResponse);
+
+        validateSamlResponse(samlResponse);
+        
+        // TODO: set the security context, 
+        // perhaps using the cookie or adding some query parameter 
+        // (relayState?) to the redirect URI
+        
+        // finally, redirect to the service provider endpoint
+        String responseTo = samlResponse.getInResponseTo();
+        UriBuilder builder = UriBuilder.fromPath(responseTo); 
+        // if needed: builder.queryParam("RelayState", relayState);
+        
+        return Response.seeOther(builder.build()).build();
+        
+    }
+    
+    @GET
+    public Response getSamlResponse(@Encoded @QueryParam(RELAY_STATE) String 
relayState,
+                                    @Encoded @QueryParam(SAML_RESPONSE) String 
samlResponse) {
+        return processSamlResponse(relayState, samlResponse);       
+    }
+    
+    private org.opensaml.saml2.core.Response readSAMLResponse(String 
samlResponse) {
+        if (StringUtils.isEmpty(samlResponse)) {
+            throw new WebApplicationException(400);
+        }
+        InputStream tokenStream = null;
+        try {
+            byte[] deflatedToken = Base64Utility.decode(samlResponse);
+            tokenStream = useDeflateEncoding() 
+                ? new DeflateEncoderDecoder().inflateToken(deflatedToken)
+                : new ByteArrayInputStream(deflatedToken); 
+        } catch (Base64Exception ex) {
+            throw new WebApplicationException(400);
+        } catch (DataFormatException ex) {
+            throw new WebApplicationException(400);
+        }    
+        
+        Document responseDoc = null;
+        try {
+            responseDoc = DOMUtils.readXml(new InputStreamReader(tokenStream, 
"UTF-8"));
+        } catch (Exception ex) {
+            throw new WebApplicationException(400);
+        }
+        XMLObject responseObject = null;
+        try {
+            responseObject = 
OpenSAMLUtil.fromDom(responseDoc.getDocumentElement());
+        } catch (WSSecurityException ex) {
+            throw new WebApplicationException(400);
+        }
+        if (!(responseObject instanceof org.opensaml.saml2.core.Response)) {
+            throw new WebApplicationException(400);
+        }
+        return (org.opensaml.saml2.core.Response)responseObject;
+    }
+    
+    protected void validateSamlResponse(org.opensaml.saml2.core.Response 
samlResponse) {
+        
+    }
+    
+    public void setUseDeflateEncoding(boolean deflate) {
+        useDeflateEncoding = deflate;
+    }
+    public boolean useDeflateEncoding() {
+        return useDeflateEncoding;
+    }
+}

Propchange: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/RequestAssertionConsumerService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/RequestAssertionConsumerService.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/AbstractServiceProviderFilter.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/AbstractServiceProviderFilter.java?rev=1297072&view=auto
==============================================================================
--- 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/AbstractServiceProviderFilter.java
 (added)
+++ 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/AbstractServiceProviderFilter.java
 Mon Mar  5 14:32:40 2012
@@ -0,0 +1,128 @@
+/**
+ * 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.rs.security.saml.sso.filter;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.Collections;
+
+import javax.ws.rs.core.UriInfo;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.jaxrs.ext.RequestHandler;
+import org.apache.cxf.jaxrs.impl.UriInfoImpl;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.rs.security.saml.DeflateEncoderDecoder;
+import org.apache.ws.security.saml.ext.OpenSAMLUtil;
+import org.apache.ws.security.util.DOM2Writer;
+import org.opensaml.common.SAMLVersion;
+import org.opensaml.saml2.core.AuthnContextClassRef;
+import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
+import org.opensaml.saml2.core.AuthnRequest;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.NameIDPolicy;
+import org.opensaml.saml2.core.RequestedAuthnContext;
+import org.opensaml.xml.io.MarshallingException;
+
+public abstract class AbstractServiceProviderFilter implements RequestHandler {
+    
+    protected static final String SAML_REQUEST = "SAMLRequest"; 
+    protected static final String RELAY_STATE = "RelayState";
+    
+    private String idpServiceAddress;
+    private String issuerId;
+    
+    protected boolean checkSecurityContext(Message m) {
+        return false;
+    }
+
+    public void setIdpServiceAddress(String idpServiceAddress) {
+        this.idpServiceAddress = idpServiceAddress;
+    }
+
+    public String getIdpServiceAddress() {
+        return idpServiceAddress;
+    }
+
+    protected AuthnRequest createAuthnRequest(Message m, Document doc) throws 
Exception {
+        Issuer issuer =
+            SamlpRequestComponentBuilder.createIssuer(issuerId);
+        NameIDPolicy nameIDPolicy =
+            SamlpRequestComponentBuilder.createNameIDPolicy(
+                true, "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", 
"Issuer"
+            );
+        
+        AuthnContextClassRef authnCtxClassRef =
+            SamlpRequestComponentBuilder.createAuthnCtxClassRef(
+                
"urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
+            );
+        RequestedAuthnContext authnCtx =
+            SamlpRequestComponentBuilder.createRequestedAuthnCtxPolicy(
+                AuthnContextComparisonTypeEnumeration.EXACT,
+                Collections.singletonList(authnCtxClassRef), null
+            );
+        
+        UriInfo ui = new UriInfoImpl(m);
+        //CHECKSTYLE:OFF
+        return SamlpRequestComponentBuilder.createAuthnRequest(
+                ui.getRequestUri().toString(), 
+                false, 
+                false,
+                "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", 
+                SAMLVersion.VERSION_20,
+                issuer, 
+                nameIDPolicy, 
+                authnCtx
+        );
+      //CHECKSTYLE:ON
+    }
+    
+    protected String encodeAuthnRequest(Element authnRequestElement)
+        throws MarshallingException, IOException {
+        String requestMessage = DOM2Writer.nodeToString(authnRequestElement);
+        
+        DeflateEncoderDecoder encoder = new DeflateEncoderDecoder();
+        byte[] deflatedBytes = 
encoder.deflateToken(requestMessage.getBytes("UTF-8"));
+        
+        String encodedRequestMessage = Base64Utility.encode(deflatedBytes);
+        return URLEncoder.encode(encodedRequestMessage, "UTF-8");
+    }
+
+    protected SamlRequestInfo createSamlResponseInfo(Message m) throws 
Exception {
+        Document doc = DOMUtils.createDocument();
+        doc.appendChild(doc.createElement("root"));
+ 
+        AuthnRequest authnRequest = createAuthnRequest(m, doc);
+        Element authnRequestElement = OpenSAMLUtil.toDom(authnRequest, doc);
+        String authnRequestEncoded = encodeAuthnRequest(authnRequestElement);
+        
+        SamlRequestInfo info = new SamlRequestInfo();
+        info.setEncodedSamlRequest(authnRequestEncoded);
+        // set relay state if any
+        return info;
+    }
+    
+    public void setIssuerId(String issuerId) {
+        this.issuerId = issuerId;
+    }
+}

Propchange: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/AbstractServiceProviderFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/AbstractServiceProviderFilter.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlPostBindingFilter.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlPostBindingFilter.java?rev=1297072&view=auto
==============================================================================
--- 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlPostBindingFilter.java
 (added)
+++ 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlPostBindingFilter.java
 Mon Mar  5 14:32:40 2012
@@ -0,0 +1,50 @@
+/**
+ * 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.rs.security.saml.sso.filter;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.message.Message;
+
+public class SamlPostBindingFilter extends AbstractServiceProviderFilter {
+    
+    public Response handleRequest(Message m, ClassResourceInfo resourceClass) {
+        if (checkSecurityContext(m)) {
+            return null;
+        } else {
+            try {
+                SamlRequestInfo info = createSamlResponseInfo(m);
+                info.setIdpServiceAddress(getIdpServiceAddress());
+                // This depends on RequestDispatcherProvider linking
+                // SamlResponseInfo with the jsp page which will fill
+                // in the XHTML form using SamlResponseInfo
+                // in principle we could've builf the XHTML form right here
+                // but it will be cleaner to get that done in JSP
+                return Response.ok(info).type("text/html").build();
+                
+            } catch (Exception ex) {
+                throw new WebApplicationException(ex);
+            }
+        }
+    }
+    
+    
+}

Propchange: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlPostBindingFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlPostBindingFilter.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlRedirectBindingFilter.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlRedirectBindingFilter.java?rev=1297072&view=auto
==============================================================================
--- 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlRedirectBindingFilter.java
 (added)
+++ 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlRedirectBindingFilter.java
 Mon Mar  5 14:32:40 2012
@@ -0,0 +1,49 @@
+/**
+ * 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.rs.security.saml.sso.filter;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.message.Message;
+
+public class SamlRedirectBindingFilter extends AbstractServiceProviderFilter {
+    
+    public Response handleRequest(Message m, ClassResourceInfo resourceClass) {
+        if (checkSecurityContext(m)) {
+            return null;
+        } else {
+            try {
+                SamlRequestInfo info = createSamlResponseInfo(m);
+                UriBuilder ub = UriBuilder.fromUri(getIdpServiceAddress());
+                ub.queryParam(SAML_REQUEST, info.getEncodedSamlRequest());
+                if (info.getRelayState() != null) {
+                    ub.queryParam(RELAY_STATE, info.getRelayState());    
+                }
+                return Response.seeOther(ub.build()).build();
+            } catch (Exception ex) {
+                throw new WebApplicationException(ex);
+            }
+        }
+    }
+    
+    
+}

Propchange: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlRedirectBindingFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlRedirectBindingFilter.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlRequestInfo.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlRequestInfo.java?rev=1297072&view=auto
==============================================================================
--- 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlRequestInfo.java
 (added)
+++ 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlRequestInfo.java
 Mon Mar  5 14:32:40 2012
@@ -0,0 +1,44 @@
+/**
+ * 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.rs.security.saml.sso.filter;
+
+public class SamlRequestInfo {
+    private String encodedSamlRequest;
+    private String relayState;
+    private String idpServiceAddress;
+    
+    public void setEncodedSamlRequest(String encodedSaml) {
+        this.encodedSamlRequest = encodedSaml;
+    }
+    public String getEncodedSamlRequest() {
+        return encodedSamlRequest;
+    }
+    public void setRelayState(String relayState) {
+        this.relayState = relayState;
+    }
+    public String getRelayState() {
+        return relayState;
+    }
+    public void setIdpServiceAddress(String idpServiceAddress) {
+        this.idpServiceAddress = idpServiceAddress;
+    }
+    public String getIdpServiceAddress() {
+        return idpServiceAddress;
+    }
+}

Propchange: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlRequestInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlRequestInfo.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlpRequestComponentBuilder.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlpRequestComponentBuilder.java?rev=1297072&view=auto
==============================================================================
--- 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlpRequestComponentBuilder.java
 (added)
+++ 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlpRequestComponentBuilder.java
 Mon Mar  5 14:32:40 2012
@@ -0,0 +1,171 @@
+/**
+ * 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.rs.security.saml.sso.filter;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.opensaml.Configuration;
+import org.opensaml.common.SAMLObjectBuilder;
+import org.opensaml.common.SAMLVersion;
+import org.opensaml.saml2.core.AuthnContextClassRef;
+import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
+import org.opensaml.saml2.core.AuthnContextDeclRef;
+import org.opensaml.saml2.core.AuthnRequest;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.NameIDPolicy;
+import org.opensaml.saml2.core.RequestedAuthnContext;
+import org.opensaml.xml.XMLObjectBuilderFactory;
+
+/**
+* A set of utility methods to construct SAMLP Request statements
+*/
+public final class SamlpRequestComponentBuilder {
+    
+    private static SAMLObjectBuilder<AuthnRequest> authnRequestBuilder;
+    
+    private static SAMLObjectBuilder<Issuer> issuerBuilder;
+    
+    private static SAMLObjectBuilder<NameIDPolicy> nameIDBuilder;
+    
+    private static SAMLObjectBuilder<RequestedAuthnContext> 
requestedAuthnCtxBuilder;
+    
+    private static SAMLObjectBuilder<AuthnContextClassRef> 
requestedAuthnCtxClassRefBuilder;
+    
+    private static XMLObjectBuilderFactory builderFactory = 
Configuration.getBuilderFactory();
+    
+    private SamlpRequestComponentBuilder() {
+        
+    }
+    
+    @SuppressWarnings("unchecked")
+    //CHECKSTYLE:OFF
+    public static AuthnRequest createAuthnRequest(
+        String serviceURL,
+        boolean forceAuthn,
+        boolean isPassive,
+        String protocolBinding,
+        SAMLVersion version,
+        Issuer issuer,
+        NameIDPolicy nameIDPolicy,
+        RequestedAuthnContext requestedAuthnCtx
+    ) {
+    //CHECKSTYLE:ON    
+        if (authnRequestBuilder == null) {
+            authnRequestBuilder = (SAMLObjectBuilder<AuthnRequest>)
+                builderFactory.getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
+        }
+        AuthnRequest authnRequest = authnRequestBuilder.buildObject();
+        authnRequest.setAssertionConsumerServiceURL(serviceURL);
+        authnRequest.setForceAuthn(forceAuthn);
+        authnRequest.setID(UUID.randomUUID().toString());
+        authnRequest.setIsPassive(isPassive);
+        authnRequest.setIssueInstant(new DateTime());
+        authnRequest.setProtocolBinding(protocolBinding);
+        authnRequest.setVersion(version);
+        
+        authnRequest.setIssuer(issuer);
+        authnRequest.setNameIDPolicy(nameIDPolicy);
+        authnRequest.setRequestedAuthnContext(requestedAuthnCtx);
+        
+        return authnRequest;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static Issuer createIssuer(
+        String issuerValue
+    ) {
+        if (issuerBuilder == null) {
+            issuerBuilder = (SAMLObjectBuilder<Issuer>)
+                builderFactory.getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
+        }
+        Issuer issuer = issuerBuilder.buildObject();
+        issuer.setValue(issuerValue);
+        
+        return issuer;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static NameIDPolicy createNameIDPolicy(
+        boolean allowCreate,
+        String format,
+        String spNameQualifier
+    ) {
+        if (nameIDBuilder == null) {
+            nameIDBuilder = (SAMLObjectBuilder<NameIDPolicy>)
+                builderFactory.getBuilder(NameIDPolicy.DEFAULT_ELEMENT_NAME);
+        }
+        NameIDPolicy nameId = nameIDBuilder.buildObject();
+        nameId.setAllowCreate(allowCreate);
+        nameId.setFormat(format);
+        nameId.setSPNameQualifier(spNameQualifier);
+        
+        return nameId;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static RequestedAuthnContext createRequestedAuthnCtxPolicy(
+        AuthnContextComparisonTypeEnumeration comparison,
+        List<AuthnContextClassRef> authnCtxClassRefList,
+        List<AuthnContextDeclRef> authnCtxDeclRefList
+    ) {
+        if (requestedAuthnCtxBuilder == null) {
+            requestedAuthnCtxBuilder = 
(SAMLObjectBuilder<RequestedAuthnContext>)
+                
builderFactory.getBuilder(RequestedAuthnContext.DEFAULT_ELEMENT_NAME);
+        }
+        RequestedAuthnContext authnCtx = 
requestedAuthnCtxBuilder.buildObject();
+        authnCtx.setComparison(comparison);
+        
+        if (authnCtxClassRefList != null) {
+            List<AuthnContextClassRef> classRefList = 
authnCtx.getAuthnContextClassRefs();
+            if (classRefList == null) {
+                classRefList = new ArrayList<AuthnContextClassRef>();
+            }
+            classRefList.addAll(authnCtxClassRefList);
+        }
+        
+        if (authnCtxDeclRefList != null) {
+            List<AuthnContextDeclRef> declRefList = 
authnCtx.getAuthnContextDeclRefs();
+            if (declRefList == null) {
+                declRefList = new ArrayList<AuthnContextDeclRef>();
+            }
+            declRefList.addAll(authnCtxDeclRefList);
+        }
+        
+        return authnCtx;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static AuthnContextClassRef createAuthnCtxClassRef(
+        String authnCtxClassRefValue
+    ) {
+        if (requestedAuthnCtxClassRefBuilder == null) {
+            requestedAuthnCtxClassRefBuilder = 
(SAMLObjectBuilder<AuthnContextClassRef>)
+                
builderFactory.getBuilder(AuthnContextClassRef.DEFAULT_ELEMENT_NAME);
+        }
+        AuthnContextClassRef authnCtxClassRef = 
requestedAuthnCtxClassRefBuilder.buildObject();
+        authnCtxClassRef.setAuthnContextClassRef(authnCtxClassRefValue);
+        
+        return authnCtxClassRef;
+    }
+    
+}
\ No newline at end of file

Propchange: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlpRequestComponentBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/sso/filter/SamlpRequestComponentBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date


Reply via email to