[seam-commits] Seam SVN: r13562 - in modules/security/trunk/impl: src/main and 11 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Fri Aug 6 10:08:06 EDT 2010


Author: marcelkolsteren
Date: 2010-08-06 10:08:04 -0400 (Fri, 06 Aug 2010)
New Revision: 13562

Added:
   modules/security/trunk/impl/src/main/java/META-INF/
   modules/security/trunk/impl/src/main/java/META-INF/MANIFEST.MF
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticationFilter.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticationService.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticator.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/InternalAuthenticator.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/InvalidRequestException.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/LoggedInEvent.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdConsumerManagerFactory.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdPrincipal.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdRequest.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdSingleLoginReceiver.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdSingleLoginSender.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdXrdsProvider.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/PagesSupportingExternalAuthentication.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/RequestContext.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/RequestOrResponse.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/Requests.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlConstants.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageFactory.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageReceiver.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageSender.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMetaDataProvider.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlProfile.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSignatureUtilForPostBinding.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSignatureUtilForRedirectBinding.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleLogoutReceiver.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleLogoutSender.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleSignOnReceiver.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleSignOnSender.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlUtils.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SeamSamlPrincipal.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/Binding.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/Configuration.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/OpenIdConfiguration.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlConfiguration.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlEndpoint.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlIdentityProvider.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlService.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/ServiceProvider.java
   modules/security/trunk/impl/src/main/resources/schema/
   modules/security/trunk/impl/src/main/resources/schema/config/
   modules/security/trunk/impl/src/main/resources/schema/config/external-authentication-config.xsd
   modules/security/trunk/impl/src/main/resources/schema/samlv2/
   modules/security/trunk/impl/src/main/resources/schema/samlv2/saml-schema-assertion-2.0.xsd
   modules/security/trunk/impl/src/main/resources/schema/samlv2/saml-schema-metadata-2.0.xsd
   modules/security/trunk/impl/src/main/resources/schema/samlv2/saml-schema-protocol-2.0.xsd
   modules/security/trunk/impl/src/main/resources/schema/samlv2/xenc-schema.xsd
   modules/security/trunk/impl/src/main/resources/schema/samlv2/xmldsig-core-schema.xsd
   modules/security/trunk/impl/src/main/resources/schema/xrds/
   modules/security/trunk/impl/src/main/resources/schema/xrds/xrd.xsd
   modules/security/trunk/impl/src/main/resources/schema/xrds/xrds.xsd
   modules/security/trunk/impl/src/main/xjb/
   modules/security/trunk/impl/src/main/xjb/config-bindings.xjb
   modules/security/trunk/impl/src/main/xjb/samlv2-bindings.xjb
   modules/security/trunk/impl/src/main/xjb/xrds-bindings.xjb
Modified:
   modules/security/trunk/impl/pom.xml
   modules/security/trunk/impl/src/main/
Log:
External authentication functionality (OpenID/SAMLv2), ported from the PicketLink Seam module. Not functional yet, and not integrated with the rest of the Seam Security module, but it compiles.

Modified: modules/security/trunk/impl/pom.xml
===================================================================
--- modules/security/trunk/impl/pom.xml	2010-08-05 17:54:51 UTC (rev 13561)
+++ modules/security/trunk/impl/pom.xml	2010-08-06 14:08:04 UTC (rev 13562)
@@ -14,6 +14,59 @@
    <packaging>jar</packaging>
    <name>Seam Security Implementation</name>
 
+   <build>
+      <plugins>
+         <plugin>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>jaxb2-maven-plugin</artifactId>
+            <version>1.3</version>
+            <executions>
+               <execution>
+                  <id>jaxb-saml</id>
+                  <configuration>
+                     <schemaDirectory>${basedir}/src/main/resources/schema/samlv2</schemaDirectory>
+                     <outputDirectory>${basedir}/src/main/generated-source</outputDirectory>
+                     <clearOutputDir>true</clearOutputDir>
+                     <staleFile>${project.build.directory}/.staleFlag_saml</staleFile>
+                     <bindingFiles>samlv2-bindings.xjb</bindingFiles>
+                  </configuration>
+                  <goals>
+                     <goal>xjc</goal>
+                  </goals>
+               </execution>
+               <execution>
+                  <id>jaxb-xrds</id>
+                  <configuration>
+                     <schemaDirectory>${basedir}/src/main/resources/schema/xrds</schemaDirectory>
+                     <packageName>org.jboss.seam.security.external_authentication.jaxb.xrds</packageName>
+                     <outputDirectory>${basedir}/src/main/generated-source</outputDirectory>
+                     <clearOutputDir>false</clearOutputDir>
+                     <staleFile>${project.build.directory}/.staleFlag_xrds</staleFile>
+                     <bindingFiles>xrds-bindings.xjb</bindingFiles>
+                  </configuration>
+                  <goals>
+                     <goal>xjc</goal>
+                  </goals>
+               </execution>
+               <execution>
+                  <id>jaxb-config</id>
+                  <configuration>
+                     <schemaDirectory>${basedir}/src/main/resources/schema/config</schemaDirectory>
+                     <packageName>org.jboss.seam.security.external_authentication.jaxb.config</packageName>
+                     <outputDirectory>${basedir}/src/main/generated-source</outputDirectory>
+                     <clearOutputDir>false</clearOutputDir>
+                     <staleFile>${project.build.directory}/.staleFlag_config</staleFile>
+                     <bindingFiles>config-bindings.xjb</bindingFiles>
+                  </configuration>
+                  <goals>
+                     <goal>xjc</goal>
+                  </goals>
+               </execution>
+            </executions>
+         </plugin>
+      </plugins>
+   </build>
+
    <dependencies>
 
       <dependency>
@@ -62,30 +115,30 @@
          <artifactId>seam-drools-api</artifactId>
 
          <exclusions>
-           <exclusion>
-             <groupId>com.sun.xml.bind</groupId>
-             <artifactId>jaxb-impl</artifactId>
-           </exclusion>
-           <exclusion>
-             <groupId>com.sun.xml.bind</groupId>
-             <artifactId>jaxb-xjc</artifactId>
-           </exclusion>
-           <exclusion>
-              <groupId>org.drools</groupId>
-              <artifactId>drools-decisiontables</artifactId>
-           </exclusion>
-           <exclusion>
-              <groupId>org.drools</groupId>
-              <artifactId>drools-workitems</artifactId>
-           </exclusion>
-           <exclusion>
-              <groupId>org.drools</groupId>
-              <artifactId>drools-transformer-xstream</artifactId>
-           </exclusion>
-           <exclusion>
-              <groupId>javax.el</groupId>
-              <artifactId>el-api</artifactId>
-           </exclusion>
+            <exclusion>
+               <groupId>com.sun.xml.bind</groupId>
+               <artifactId>jaxb-impl</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>com.sun.xml.bind</groupId>
+               <artifactId>jaxb-xjc</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>org.drools</groupId>
+               <artifactId>drools-decisiontables</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>org.drools</groupId>
+               <artifactId>drools-workitems</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>org.drools</groupId>
+               <artifactId>drools-transformer-xstream</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>javax.el</groupId>
+               <artifactId>el-api</artifactId>
+            </exclusion>
          </exclusions>
       </dependency>
 
@@ -140,10 +193,10 @@
          <groupId>org.picketlink.idm</groupId>
          <artifactId>picketlink-idm-core</artifactId>
          <exclusions>
-           <exclusion>
-             <groupId>log4j</groupId>
-             <artifactId>log4j</artifactId>
-           </exclusion>
+            <exclusion>
+               <groupId>log4j</groupId>
+               <artifactId>log4j</artifactId>
+            </exclusion>
          </exclusions>
       </dependency>
 
@@ -153,6 +206,37 @@
          <scope>provided</scope>
       </dependency>
 
+      <dependency>
+         <!-- Required until the Servlet 3.0 API can be resolved in Central -->
+         <groupId>org.jboss.spec.javax.servlet</groupId>
+         <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+         <scope>provided</scope>
+      </dependency>
+
+      <dependency>
+         <!-- This is necessary until a new JSF-API is published to central -->
+         <groupId>javax.faces</groupId>
+         <artifactId>jsf-api</artifactId>
+         <scope>provided</scope>
+      </dependency>
+
+      <dependency>
+         <groupId>org.openid4java</groupId>
+         <artifactId>openid4java</artifactId>
+         <version>0.9.5</version>
+      </dependency>
+
+      <!--
+         We need the JSR 105 API and implementation (for XML digital
+         signatures). This is part of JDK6, but Seam 3 is required to
+         compile with JDK5 as well.
+      -->
+      <dependency>
+         <groupId>org.apache</groupId>
+         <artifactId>xmlsec</artifactId>
+         <version>1.4.3</version>
+      </dependency>
+
    </dependencies>
 
 </project>


Property changes on: modules/security/trunk/impl/src/main
___________________________________________________________________
Name: svn:ignore
   + generated-source


Added: modules/security/trunk/impl/src/main/java/META-INF/MANIFEST.MF
===================================================================
--- modules/security/trunk/impl/src/main/java/META-INF/MANIFEST.MF	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/META-INF/MANIFEST.MF	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path: 
+

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticationFilter.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticationFilter.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticationFilter.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,220 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.io.IOException;
+
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.seam.security.Identity;
+import org.jboss.seam.security.external_authentication.configuration.Configuration;
+import org.jboss.seam.security.external_authentication.configuration.SamlIdentityProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Seam Servlet Filter supporting SAMLv2 authentication. It implements the Web
+ * Browser SSO Profile. For outgoing authentication requests it can use either
+ * HTTP Post or HTTP Redirect binding. For the responses, it uses HTTP Post
+ * binding, with or without signature validation.
+ */
+ at WebFilter
+public class ExternalAuthenticationFilter implements Filter
+{
+   public static final String IDP_ENTITY_ID_PARAMETER = "idpEntityId";
+
+   public static final String RETURN_URL_PARAMETER = "returnUrl";
+
+   public static final String OPEN_ID_PARAMETER = "openId";
+
+   private final Logger log = LoggerFactory.getLogger(ExternalAuthenticationFilter.class);
+
+   @Inject
+   private Configuration configuration;
+
+   @Inject
+   private SamlMessageReceiver samlMessageReceiver;
+
+   @Inject
+   private OpenIdSingleLoginReceiver openIdSingleLoginReceiver;
+
+   @Inject
+   private SamlSingleSignOnSender samlSingleSignOnSender;
+
+   @Inject
+   private OpenIdSingleLoginSender openIdSingleLoginSender;
+
+   @Inject
+   private SamlSingleLogoutSender samlSingleLogoutSender;
+
+   @Inject
+   private SamlMetaDataProvider samlMetaDataProvider;
+
+   @Inject
+   private OpenIdXrdsProvider openIdXrdsProvider;
+
+   @Inject
+   private Instance<Identity> identity;
+
+   public void init(FilterConfig filterConfig) throws ServletException
+   {
+      configuration.setContextRoot(filterConfig.getServletContext().getContextPath());
+   }
+
+   public void doFilter(ServletRequest request, ServletResponse response, final FilterChain chain) throws IOException, ServletException
+   {
+      if (!(request instanceof HttpServletRequest))
+      {
+         throw new ServletException("This filter can only process HttpServletRequest requests");
+      }
+
+      final HttpServletRequest httpRequest = (HttpServletRequest) request;
+      final HttpServletResponse httpResponse = (HttpServletResponse) response;
+
+      final ExternalAuthenticationService service = determineService(httpRequest);
+
+      if (service != null)
+      {
+         try
+         {
+            doFilter(httpRequest, httpResponse, service);
+         }
+         catch (InvalidRequestException e)
+         {
+            httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+            if (log.isInfoEnabled())
+            {
+               log.info("Bad request received from {0} ({1})", new Object[] { e.getCause(), httpRequest.getRemoteHost(), e.getDescription() });
+            }
+         }
+      }
+      else
+      {
+         // Request is not related to external authentication. Pass the request
+         // on to
+         // the next filter in the chain.
+         chain.doFilter(httpRequest, httpResponse);
+      }
+   }
+
+   private void doFilter(HttpServletRequest httpRequest, HttpServletResponse httpResponse, ExternalAuthenticationService service) throws InvalidRequestException, IOException, ServletException
+   {
+      switch (service)
+      {
+      case OPEN_ID_SERVICE:
+         openIdSingleLoginReceiver.handleIncomingMessage(httpRequest, httpResponse);
+         break;
+      case SAML_SINGLE_LOGOUT_SERVICE:
+         samlMessageReceiver.handleIncomingSamlMessage(SamlProfile.SINGLE_LOGOUT, httpRequest, httpResponse);
+         break;
+      case SAML_ASSERTION_CONSUMER_SERVICE:
+         samlMessageReceiver.handleIncomingSamlMessage(SamlProfile.SINGLE_SIGN_ON, httpRequest, httpResponse);
+         break;
+      case AUTHENTICATION_SERVICE:
+         String returnUrl = httpRequest.getParameter(RETURN_URL_PARAMETER);
+
+         String providerName = httpRequest.getParameter(IDP_ENTITY_ID_PARAMETER);
+         if (providerName != null)
+         {
+            SamlIdentityProvider identityProvider = configuration.getServiceProvider().getSamlConfiguration().getSamlIdentityProviderByEntityId(providerName);
+
+            // User requested a page for which login is required. Return a page
+            // that instructs the browser to post an authentication request to
+            // the IDP.
+            if (identityProvider instanceof SamlIdentityProvider)
+            {
+               samlSingleSignOnSender.sendAuthenticationRequestToIDP(httpRequest, httpResponse, (SamlIdentityProvider) identityProvider, returnUrl);
+            }
+            else
+            {
+               throw new RuntimeException("Only SAML identity providers are supported in this version");
+            }
+         }
+         else
+         {
+            String openId = httpRequest.getParameter(OPEN_ID_PARAMETER);
+            openIdSingleLoginSender.sendAuthRequest(openId, returnUrl, httpResponse);
+         }
+         break;
+      case LOGOUT_SERVICE:
+         if (!identity.get().isLoggedIn())
+         {
+            throw new RuntimeException("User not logged in.");
+         }
+         // FIXME SeamSamlPrincipal principal = (SeamSamlPrincipal)
+         // identity.getPrincipal();
+         SeamSamlPrincipal principal = (SeamSamlPrincipal) httpRequest.getUserPrincipal();
+         SamlIdentityProvider idp = principal.getIdentityProvider();
+         if (!(idp instanceof SamlIdentityProvider))
+         {
+            throw new RuntimeException("Only SAML identity providers are supported in this version");
+         }
+
+         samlSingleLogoutSender.sendSingleLogoutRequestToIDP(httpRequest, httpResponse, identity.get());
+         break;
+      case SAML_META_DATA_SERVICE:
+
+         samlMetaDataProvider.writeMetaData(httpResponse.getOutputStream());
+         httpResponse.setCharacterEncoding("UTF-8");
+         httpResponse.setContentType("application/xml");
+         httpResponse.flushBuffer();
+         break;
+      case OPEN_ID_XRDS_SERVICE:
+
+         openIdXrdsProvider.writeMetaData(httpResponse.getOutputStream());
+         httpResponse.setCharacterEncoding("UTF-8");
+         httpResponse.setContentType("application/xrds+xml");
+         httpResponse.flushBuffer();
+         break;
+      default:
+         throw new RuntimeException("Unsupported service " + service);
+      }
+   }
+
+   private ExternalAuthenticationService determineService(HttpServletRequest httpRequest)
+   {
+      String path = ((HttpServletRequest) httpRequest).getRequestURI().replace(".seam", "");
+
+      for (ExternalAuthenticationService service : ExternalAuthenticationService.values())
+      {
+         if (path.endsWith("/" + service.getName()))
+         {
+            return service;
+         }
+      }
+      return null;
+   }
+
+   public void destroy()
+   {
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticationFilter.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticationService.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticationService.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticationService.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,52 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+public enum ExternalAuthenticationService
+{
+
+   AUTHENTICATION_SERVICE("AuthenticationService"),
+
+   LOGOUT_SERVICE("LogoutService"),
+
+   SAML_ASSERTION_CONSUMER_SERVICE("AssertionConsumerService"),
+
+   SAML_SINGLE_LOGOUT_SERVICE("SingleLogoutService"),
+
+   SAML_META_DATA_SERVICE("MetaDataService"),
+
+   OPEN_ID_SERVICE("OpenIdService"),
+
+   OPEN_ID_XRDS_SERVICE("OpenIdXrdsService");
+
+   private String name;
+
+   private ExternalAuthenticationService(String name)
+   {
+      this.name = name;
+   }
+
+   public String getName()
+   {
+      return name;
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticationService.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticator.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticator.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticator.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,174 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.context.FacesContext;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.servlet.annotation.WebFilter;
+
+import org.jboss.seam.security.Identity;
+import org.jboss.seam.security.external_authentication.configuration.SamlIdentityProvider;
+import org.jboss.seam.security.external_authentication.configuration.ServiceProvider;
+
+/**
+ * Filter that manages the external authentication of users (using, for example,
+ * SAML or OpenID).
+ */
+ at Named("externalAuthenticator")
+ at WebFilter
+// FIXME: page scope
+public class ExternalAuthenticator
+{
+   private String returnUrl;
+
+   private String openId;
+
+   @Inject
+   private ServiceProvider serviceProvider;
+
+   @Inject
+   private Identity identity;
+
+   public void samlSignOn(String idpEntityId)
+   {
+      if (serviceProvider.getSamlConfiguration() == null)
+      {
+         throw new RuntimeException("SAML is not configured.");
+      }
+
+      SamlIdentityProvider idp = serviceProvider.getSamlConfiguration().getSamlIdentityProviderByEntityId(idpEntityId);
+      if (idp == null)
+      {
+         throw new RuntimeException("Identity provider " + idpEntityId + " not found");
+      }
+
+      String authenticationServiceURL = serviceProvider.getServiceURL(ExternalAuthenticationService.AUTHENTICATION_SERVICE);
+      Map<String, String> params = new HashMap<String, String>();
+      params.put(ExternalAuthenticationFilter.IDP_ENTITY_ID_PARAMETER, idpEntityId);
+      params.put(ExternalAuthenticationFilter.RETURN_URL_PARAMETER, returnUrl);
+      redirect(authenticationServiceURL, params);
+   }
+
+   public void openIdSignOn()
+   {
+      openIdSignOn(openId);
+   }
+
+   public void openIdSignOn(String openId)
+   {
+      if (serviceProvider.getOpenIdConfiguration() == null)
+      {
+         throw new RuntimeException("OpenID is not configured.");
+      }
+      String authenticationServiceURL = serviceProvider.getServiceURL(ExternalAuthenticationService.AUTHENTICATION_SERVICE);
+      Map<String, String> params = new HashMap<String, String>();
+      params.put(ExternalAuthenticationFilter.RETURN_URL_PARAMETER, returnUrl);
+      params.put(ExternalAuthenticationFilter.OPEN_ID_PARAMETER, openId);
+      redirect(authenticationServiceURL, params);
+   }
+
+   public void singleLogout()
+   {
+      if (!identity.isLoggedIn())
+      {
+         throw new RuntimeException("Not logged in");
+      }
+      if (false /* FIXME !(identity.getPrincipal() instanceof SeamSamlPrincipal) */)
+      {
+         throw new RuntimeException("Single logout is only supported for SAML");
+      }
+      String logoutServiceURL = serviceProvider.getServiceURL(ExternalAuthenticationService.LOGOUT_SERVICE);
+      redirect(logoutServiceURL, null);
+   }
+
+   private void redirect(String urlBase, Map<String, String> params)
+   {
+      StringBuilder url = new StringBuilder();
+      url.append(urlBase);
+      if (params != null && params.size() > 0)
+      {
+         url.append("?");
+         boolean first = true;
+         for (Map.Entry<String, String> paramEntry : params.entrySet())
+         {
+            if (first)
+            {
+               first = false;
+            }
+            else
+            {
+               url.append("&");
+            }
+            url.append(paramEntry.getKey());
+            url.append("=");
+            try
+            {
+               String paramValue = paramEntry.getValue();
+               if (paramValue == null || paramValue == "")
+                  throw new RuntimeException("Param Key:" + paramEntry.getKey() + " has value that is null");
+               url.append(URLEncoder.encode(paramValue, "UTF-8"));
+            }
+            catch (UnsupportedEncodingException e)
+            {
+               throw new RuntimeException(e);
+            }
+         }
+      }
+
+      try
+      {
+         FacesContext.getCurrentInstance().getExternalContext().redirect(url.toString());
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException(e);
+
+      }
+   }
+
+   public String getReturnUrl()
+   {
+      return returnUrl;
+   }
+
+   public void setReturnUrl(String returnUrl)
+   {
+      this.returnUrl = returnUrl;
+   }
+
+   public String getOpenId()
+   {
+      return openId;
+   }
+
+   public void setOpenId(String openId)
+   {
+      this.openId = openId;
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/ExternalAuthenticator.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/InternalAuthenticator.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/InternalAuthenticator.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/InternalAuthenticator.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,78 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.security.Principal;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.security.auth.login.LoginException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.jboss.seam.security.Identity;
+import org.jboss.seam.security.events.LoginFailedEvent;
+import org.jboss.seam.security.events.PostAuthenticateEvent;
+import org.jboss.seam.security.external_authentication.configuration.ServiceProvider;
+
+ at Named("internalAuthenticator")
+public class InternalAuthenticator
+{
+   @Inject
+   private Identity identity;
+
+   @Inject
+   private ServiceProvider serviceProvider;
+
+   @Inject
+   private BeanManager beanManager;
+
+   public boolean authenticate(Principal principal, HttpServletRequest httpRequest)
+   {
+      List<String> roles = new LinkedList<String>();
+      Boolean internallyAuthenticated = null; // FIXME =
+      // serviceProvider.getInternalAuthenticationMethod().invoke(principal,
+      // roles);
+
+      beanManager.fireEvent(new PostAuthenticateEvent());
+
+      if (internallyAuthenticated)
+      {
+         // FIXME identity.acceptExternallyAuthenticatedPrincipal(principal);
+
+         for (String role : roles)
+         {
+            // FIXME identity.addRole(role);
+         }
+
+         beanManager.fireEvent(new LoggedInEvent(null) /* FIXME: no user */);
+      }
+      else
+      {
+         beanManager.fireEvent(new LoginFailedEvent(new LoginException()));
+      }
+
+      return internallyAuthenticated;
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/InternalAuthenticator.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/InvalidRequestException.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/InvalidRequestException.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/InvalidRequestException.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+/**
+ * Exception thrown to indicate that the request is invalid.
+ */
+public class InvalidRequestException extends Exception
+{
+   private static final long serialVersionUID = -9127592026257210986L;
+
+   private String description;
+
+   private Exception cause;
+
+   public InvalidRequestException(String description)
+   {
+      this(description, null);
+   }
+
+   public InvalidRequestException(String description, Exception cause)
+   {
+      super();
+      this.description = description;
+      this.cause = cause;
+   }
+
+   public String getDescription()
+   {
+      return description;
+   }
+
+   public Exception getCause()
+   {
+      return cause;
+   }
+
+   public void setCause(Exception cause)
+   {
+      this.cause = cause;
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/InvalidRequestException.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/LoggedInEvent.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/LoggedInEvent.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/LoggedInEvent.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,32 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+public class LoggedInEvent
+{
+
+   public LoggedInEvent(Object object)
+   {
+      // TODO Auto-generated constructor stub
+   }
+
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/LoggedInEvent.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdConsumerManagerFactory.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdConsumerManagerFactory.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdConsumerManagerFactory.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.openid4java.consumer.ConsumerManager;
+
+ at Named("openIdConsumerManager")
+ at ApplicationScoped
+public class OpenIdConsumerManagerFactory
+{
+   private ConsumerManager consumerManager;
+
+   @Produces
+   public ConsumerManager getConsumerManager()
+   {
+      return consumerManager;
+   }
+
+   @Inject
+   public void startup() throws Exception
+   {
+      consumerManager = new ConsumerManager();
+   }
+}
\ No newline at end of file


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdConsumerManagerFactory.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdPrincipal.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdPrincipal.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdPrincipal.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.net.URL;
+import java.security.Principal;
+import java.util.List;
+import java.util.Map;
+
+public class OpenIdPrincipal implements Principal
+{
+   private String identifier;
+
+   private URL openIdProvider;
+
+   private Map<String, List<String>> attributes;
+
+   public OpenIdPrincipal(String identifier, URL openIdProvider, Map<String, List<String>> attributes)
+   {
+      super();
+      this.identifier = identifier;
+      this.openIdProvider = openIdProvider;
+      this.attributes = attributes;
+   }
+
+   public String getName()
+   {
+      return identifier;
+   }
+
+   public String getIdentifier()
+   {
+      return identifier;
+   }
+
+   public URL getOpenIdProvider()
+   {
+      return openIdProvider;
+   }
+
+   public Map<String, List<String>> getAttributes()
+   {
+      return attributes;
+   }
+
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdPrincipal.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdRequest.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdRequest.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdRequest.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import javax.enterprise.context.SessionScoped;
+import javax.inject.Named;
+
+import org.openid4java.discovery.DiscoveryInformation;
+
+ at Named("openIdRequest")
+ at SessionScoped
+public class OpenIdRequest
+{
+   private DiscoveryInformation discoveryInformation;
+
+   private String returnUrl;
+
+   public DiscoveryInformation getDiscoveryInformation()
+   {
+      return discoveryInformation;
+   }
+
+   public void setDiscoveryInformation(DiscoveryInformation discoveryInformation)
+   {
+      this.discoveryInformation = discoveryInformation;
+   }
+
+   public String getReturnUrl()
+   {
+      return returnUrl;
+   }
+
+   public void setReturnUrl(String returnUrl)
+   {
+      this.returnUrl = returnUrl;
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdRequest.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdSingleLoginReceiver.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdSingleLoginReceiver.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdSingleLoginReceiver.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,139 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.security.auth.login.LoginException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.seam.security.events.LoginFailedEvent;
+import org.jboss.seam.security.external_authentication.configuration.ServiceProvider;
+import org.openid4java.OpenIDException;
+import org.openid4java.consumer.ConsumerManager;
+import org.openid4java.consumer.VerificationResult;
+import org.openid4java.discovery.DiscoveryInformation;
+import org.openid4java.discovery.Identifier;
+import org.openid4java.message.AuthSuccess;
+import org.openid4java.message.ParameterList;
+import org.openid4java.message.ax.AxMessage;
+import org.openid4java.message.ax.FetchResponse;
+
+ at Named("openIdSingleLoginReceiver")
+public class OpenIdSingleLoginReceiver
+{
+   @Inject
+   private OpenIdRequest openIdRequest;
+
+   @Inject
+   private ConsumerManager openIdConsumerManager;
+
+   @Inject
+   private InternalAuthenticator internalAuthenticator;
+
+   @Inject
+   private ServiceProvider serviceProvider;
+
+   @Inject
+   private BeanManager manager;
+
+   @SuppressWarnings("unchecked")
+   public void handleIncomingMessage(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws InvalidRequestException
+   {
+      try
+      {
+         // extract the parameters from the authentication response
+         // (which comes in as a HTTP request from the OpenID provider)
+         ParameterList response = new ParameterList(httpRequest.getParameterMap());
+
+         // retrieve the previously stored discovery information
+         DiscoveryInformation discovered = openIdRequest.getDiscoveryInformation();
+
+         // extract the receiving URL from the HTTP request
+         StringBuffer receivingURL = httpRequest.getRequestURL();
+         String queryString = httpRequest.getQueryString();
+         if (queryString != null && queryString.length() > 0)
+            receivingURL.append("?").append(httpRequest.getQueryString());
+
+         // verify the response; ConsumerManager needs to be the same
+         // (static) instance used to place the authentication request
+         VerificationResult verification = openIdConsumerManager.verify(receivingURL.toString(), response, discovered);
+
+         boolean authenticated = true;
+
+         // examine the verification result and extract the verified identifier
+         Identifier identifier = verification.getVerifiedId();
+
+         if (identifier != null)
+         {
+            AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse();
+
+            Map<String, List<String>> attributes = null;
+            if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX))
+            {
+               FetchResponse fetchResp = (FetchResponse) authSuccess.getExtension(AxMessage.OPENID_NS_AX);
+
+               attributes = fetchResp.getAttributes();
+            }
+
+            OpenIdPrincipal principal = createPrincipal(identifier.getIdentifier(), discovered.getOPEndpoint(), attributes);
+
+            authenticated = internalAuthenticator.authenticate(principal, httpRequest);
+         }
+         else
+         {
+            manager.fireEvent(new LoginFailedEvent(new LoginException()));
+            authenticated = false;
+         }
+
+         if (authenticated)
+         {
+            httpResponse.sendRedirect(openIdRequest.getReturnUrl());
+         }
+         else
+         {
+            httpResponse.sendRedirect(serviceProvider.getFailedAuthenticationUrl());
+         }
+      }
+      catch (OpenIDException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException(e);
+      }
+
+   }
+
+   private OpenIdPrincipal createPrincipal(String identifier, URL openIdProvider, Map<String, List<String>> attributes)
+   {
+      return new OpenIdPrincipal(identifier, openIdProvider, attributes);
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdSingleLoginReceiver.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdSingleLoginSender.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdSingleLoginSender.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdSingleLoginSender.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,113 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.security.auth.login.LoginException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.seam.security.events.LoginFailedEvent;
+import org.jboss.seam.security.events.PreAuthenticateEvent;
+import org.jboss.seam.security.external_authentication.configuration.ServiceProvider;
+import org.jboss.seam.security.external_authentication.jaxb.config.OpenIdAttributeType;
+import org.openid4java.OpenIDException;
+import org.openid4java.consumer.ConsumerManager;
+import org.openid4java.discovery.DiscoveryInformation;
+import org.openid4java.message.AuthRequest;
+import org.openid4java.message.ax.FetchRequest;
+
+ at Named("org.jboss.seam.security.external_authentication.openIdSingleLoginSender")
+public class OpenIdSingleLoginSender
+{
+   @Inject
+   private OpenIdRequest openIdRequest;
+
+   @Inject
+   private ConsumerManager openIdConsumerManager;
+
+   @Inject
+   private ServiceProvider serviceProvider;
+
+   @Inject
+   private BeanManager manager;
+
+   public String sendAuthRequest(String openId, String returnUrl, HttpServletResponse httpResponse)
+   {
+      try
+      {
+         @SuppressWarnings("unchecked")
+         List<DiscoveryInformation> discoveries = openIdConsumerManager.discover(openId);
+
+         DiscoveryInformation discovered = openIdConsumerManager.associate(discoveries);
+
+         openIdRequest.setDiscoveryInformation(discovered);
+         openIdRequest.setReturnUrl(returnUrl);
+
+         String openIdServiceUrl = serviceProvider.getServiceURL(ExternalAuthenticationService.OPEN_ID_SERVICE);
+         String realm = serviceProvider.getOpenIdRealm();
+         AuthRequest authReq = openIdConsumerManager.authenticate(discovered, openIdServiceUrl, realm);
+
+         // Request attributes
+         List<OpenIdAttributeType> attributes = serviceProvider.getOpenIdConfiguration().getAttributes();
+         if (attributes.size() > 0)
+         {
+            FetchRequest fetch = FetchRequest.createFetchRequest();
+            for (OpenIdAttributeType attribute : attributes)
+            {
+               fetch.addAttribute(attribute.getAlias(), attribute.getTypeUri(), attribute.isRequired());
+            }
+            // attach the extension to the authentication request
+            authReq.addExtension(fetch);
+         }
+
+         String url = authReq.getDestinationUrl(true);
+
+         manager.fireEvent(new PreAuthenticateEvent());
+
+         httpResponse.sendRedirect(url);
+      }
+      catch (OpenIDException e)
+      {
+         try
+         {
+            manager.fireEvent(new LoginFailedEvent(new LoginException()));
+
+            httpResponse.sendRedirect(serviceProvider.getFailedAuthenticationUrl());
+         }
+         catch (IOException e1)
+         {
+            throw new RuntimeException(e);
+         }
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException(e);
+      }
+
+      return null;
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdSingleLoginSender.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdXrdsProvider.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdXrdsProvider.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdXrdsProvider.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,79 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.io.OutputStream;
+
+import javax.inject.Inject;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+
+import org.jboss.seam.security.external_authentication.configuration.ServiceProvider;
+import org.jboss.seam.security.external_authentication.jaxb.xrds.ObjectFactory;
+import org.jboss.seam.security.external_authentication.jaxb.xrds.Service;
+import org.jboss.seam.security.external_authentication.jaxb.xrds.Type;
+import org.jboss.seam.security.external_authentication.jaxb.xrds.URIPriorityAppendPattern;
+import org.jboss.seam.security.external_authentication.jaxb.xrds.XRD;
+import org.jboss.seam.security.external_authentication.jaxb.xrds.XRDS;
+import org.openid4java.discovery.DiscoveryInformation;
+
+public class OpenIdXrdsProvider
+{
+   @Inject
+   private ServiceProvider serviceProvider;
+
+   public void writeMetaData(OutputStream stream)
+   {
+      try
+      {
+         ObjectFactory objectFactory = new ObjectFactory();
+
+         XRDS xrds = objectFactory.createXRDS();
+
+         XRD xrd = objectFactory.createXRD();
+
+         Type type = objectFactory.createType();
+         type.setValue(DiscoveryInformation.OPENID2_RP);
+         URIPriorityAppendPattern uri = objectFactory.createURIPriorityAppendPattern();
+         uri.setValue(serviceProvider.getServiceURL(ExternalAuthenticationService.OPEN_ID_SERVICE));
+
+         Service service = objectFactory.createService();
+         service.getType().add(type);
+         service.getURI().add(uri);
+
+         xrd.getService().add(service);
+
+         xrds.getOtherelement().add(xrd);
+
+         JAXBContext jaxbContext = JAXBContext.newInstance("org.jboss.seam.security.external_authentication.jaxb.xrds");
+         Marshaller marshaller = jaxbContext.createMarshaller();
+         marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
+         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+         marshaller.marshal(xrds, stream);
+      }
+      catch (JAXBException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/OpenIdXrdsProvider.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/PagesSupportingExternalAuthentication.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/PagesSupportingExternalAuthentication.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/PagesSupportingExternalAuthentication.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+/**
+ * Override of Seam's Pages component. It replaces the login page redirection method with a version
+ * that redirects to an URL that is filtered by the SamlAuthenticationFilter.
+ */
+
+// FIXME
+
+//@ApplicationScoped
+//@BypassInterceptors
+//@Name("org.jboss.seam.navigation.pages")
+//@Injectstall(precedence = Install.FRAMEWORK, classDependencies = "javax.faces.context.FacesContext")
+//@Startup
+//public class PagesSupportingExternalAuthentication extends Pages
+//{
+//   @Override
+//   public void redirectToLoginView()
+//   {
+//      notLoggedIn();
+//
+//      HttpServletRequest httpRequest = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext()
+//            .getRequest();
+//
+//      StringBuffer returnUrl = httpRequest.getRequestURL();
+//
+//      ExternalAuthenticator externalAuthenticator = (ExternalAuthenticator) Component
+//            .getInstance(ExternalAuthenticator.class);
+//      externalAuthenticator.setReturnUrl(returnUrl.toString());
+//
+//      ServiceProvider serviceProvider = Configuration.instance().getServiceProvider();
+//
+//      // Use default SAML identity provider, if configured
+//      SamlConfiguration samlConfiguration = serviceProvider.getSamlConfiguration();
+//      if (samlConfiguration != null && samlConfiguration.getDefaultIdentityProvider() != null)
+//      {
+//         externalAuthenticator.samlSignOn(samlConfiguration.getDefaultIdentityProvider().getEntityId());
+//      }
+//      else
+//      {
+//         // Otherwise, use default OpenId identity provider, if configured
+//         OpenIdConfiguration openIdConfiguration = serviceProvider.getOpenIdConfiguration();
+//         if (openIdConfiguration != null && openIdConfiguration.getDefaultOpenIdProvider() != null)
+//         {
+//            externalAuthenticator.openIdSignOn(openIdConfiguration.getDefaultOpenIdProvider());
+//         }
+//         else
+//         {
+//            // Otherwise, redirect to the login view, so that the user can choose an IDP
+//            if (getLoginViewId() == null)
+//            {
+//               throw new RuntimeException("Login view id not specified in pages.xml.");
+//            }
+//            Map<String, Object> parameters = new HashMap<String, Object>();
+//            parameters.put(ExternalAuthenticationFilter.RETURN_URL_PARAMETER, returnUrl);
+//            FacesManager.instance().redirect(getLoginViewId(), parameters, false);
+//         }
+//      }
+//   }
+// }


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/PagesSupportingExternalAuthentication.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/RequestContext.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/RequestContext.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/RequestContext.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,75 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import org.jboss.seam.security.external_authentication.configuration.SamlIdentityProvider;
+
+/**
+ * Context of an authentication request.
+ * 
+ */
+public class RequestContext
+{
+   private String id;
+
+   private SamlIdentityProvider identityProvider;
+
+   private String urlToRedirectToAfterLogin;
+
+   public RequestContext(String id, SamlIdentityProvider identityProvider, String urlToRedirectToAfterLogin)
+   {
+      super();
+      this.id = id;
+      this.identityProvider = identityProvider;
+      this.urlToRedirectToAfterLogin = urlToRedirectToAfterLogin;
+   }
+
+   public String getId()
+   {
+      return id;
+   }
+
+   public void setId(String id)
+   {
+      this.id = id;
+   }
+
+   public SamlIdentityProvider getIdentityProvider()
+   {
+      return identityProvider;
+   }
+
+   public void setIdentityProvider(SamlIdentityProvider identityProvider)
+   {
+      this.identityProvider = identityProvider;
+   }
+
+   public String getUrlToRedirectToAfterLogin()
+   {
+      return urlToRedirectToAfterLogin;
+   }
+
+   public void setUrlToRedirectToAfterLogin(String urlToRedirectToAfterLogin)
+   {
+      this.urlToRedirectToAfterLogin = urlToRedirectToAfterLogin;
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/RequestContext.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/RequestOrResponse.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/RequestOrResponse.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/RequestOrResponse.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,37 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+public enum RequestOrResponse
+{
+   REQUEST, RESPONSE;
+
+   public boolean isRequest()
+   {
+      return this == REQUEST;
+   }
+
+   public boolean isResponse()
+   {
+      return this == RESPONSE;
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/RequestOrResponse.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/Requests.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/Requests.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/Requests.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.enterprise.context.SessionScoped;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.seam.security.external_authentication.configuration.SamlIdentityProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Session scoped component that stores requests that have been sent to the
+ * identity provider.
+ */
+ at SessionScoped
+public class Requests
+{
+   private Map<String, RequestContext> requests = new HashMap<String, RequestContext>();
+
+   private Logger log = LoggerFactory.getLogger(Requests.class);
+
+   public void addRequest(String id, SamlIdentityProvider identityProvider, String urlToRedirectToAfterLogin)
+   {
+      requests.put(id, new RequestContext(id, identityProvider, urlToRedirectToAfterLogin));
+   }
+
+   public RequestContext getRequest(String id)
+   {
+      return requests.get(id);
+   }
+
+   public void removeRequest(String id)
+   {
+      requests.remove(id);
+   }
+
+   public void redirect(String id, HttpServletResponse response)
+   {
+      String requestURL = requests.get(id).getUrlToRedirectToAfterLogin();
+      if (requestURL == null)
+      {
+         throw new RuntimeException("Couldn't find URL to redirect to for request " + id);
+      }
+      try
+      {
+         if (log.isDebugEnabled())
+         {
+            log.debug("Redirecting to " + requestURL);
+         }
+         response.sendRedirect(requestURL);
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/Requests.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlConstants.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlConstants.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlConstants.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,59 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+public class SamlConstants
+{
+   // Query string parameters used by the HTTP_Redirect binding
+   public static final String QSP_SAML_REQUEST = "SAMLRequest";
+
+   public static final String QSP_SAML_RESPONSE = "SAMLResponse";
+
+   public static final String QSP_SIGNATURE = "Signature";
+
+   public static final String QSP_SIG_ALG = "SigAlg";
+
+   public static final String QSP_RELAY_STATE = "RelayState";
+
+   public static final String HTTP_POST_BINDING = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";
+
+   public static final String HTTP_REDIRECT_BINDING = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect";
+
+   public static final String CONFIRMATION_METHOD_BEARER = "urn:oasis:names:tc:SAML:2.0:cm:bearer";
+
+   public static final String VERSION_2_0 = "2.0";
+
+   public static final String PROTOCOL_NSURI = "urn:oasis:names:tc:SAML:2.0:protocol";
+
+   public static final String STATUS_SUCCESS = "urn:oasis:names:tc:SAML:2.0:status:Success";
+
+   public static final String XMLDSIG_NSURI = "http://www.w3.org/2000/09/xmldsig#";
+
+   public static final String SIGNATURE_SHA1_WITH_DSA = "http://www.w3.org/2000/09/xmldsig#dsa-sha1";
+
+   public static final String SIGNATURE_SHA1_WITH_RSA = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
+
+   public static final String DSA_SIGNATURE_ALGORITHM = "SHA1withDSA";
+
+   public static final String RSA_SIGNATURE_ALGORITHM = "SHA1withRSA";
+
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlConstants.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageFactory.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageFactory.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageFactory.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,128 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.util.UUID;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.jboss.seam.security.external_authentication.configuration.ServiceProvider;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.NameIDType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.AuthnRequestType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.LogoutRequestType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.ObjectFactory;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.RequestAbstractType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.StatusCodeType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.StatusResponseType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.StatusType;
+
+public class SamlMessageFactory
+{
+   @Inject
+   private ServiceProvider serviceProvider;
+
+   public StatusResponseType createStatusResponse(RequestAbstractType request, String statusCode, String statusMessage)
+   {
+      ObjectFactory objectFactory = new ObjectFactory();
+      org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.ObjectFactory assertionObjectFactory = new org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.ObjectFactory();
+
+      StatusResponseType response = objectFactory.createStatusResponseType();
+
+      response.setID(generateId());
+      response.setIssueInstant(SamlUtils.getXMLGregorianCalendar());
+
+      NameIDType issuer = assertionObjectFactory.createNameIDType();
+      issuer.setValue(serviceProvider.getSamlConfiguration().getEntityId());
+      response.setIssuer(issuer);
+
+      response.setVersion(SamlConstants.VERSION_2_0);
+      response.setInResponseTo(request.getID());
+
+      StatusCodeType statusCodeJaxb = objectFactory.createStatusCodeType();
+      statusCodeJaxb.setValue(statusCode);
+
+      StatusType statusType = objectFactory.createStatusType();
+      statusType.setStatusCode(statusCodeJaxb);
+      if (statusMessage != null)
+      {
+         statusType.setStatusMessage(statusMessage);
+      }
+
+      response.setStatus(statusType);
+
+      return response;
+   }
+
+   public AuthnRequestType createAuthnRequest()
+   {
+      ObjectFactory objectFactory = new ObjectFactory();
+      org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.ObjectFactory assertionObjectFactory = new org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.ObjectFactory();
+
+      AuthnRequestType authnRequest = objectFactory.createAuthnRequestType();
+
+      authnRequest.setID(generateId());
+      authnRequest.setIssueInstant(SamlUtils.getXMLGregorianCalendar());
+
+      NameIDType issuer = assertionObjectFactory.createNameIDType();
+      issuer.setValue(serviceProvider.getSamlConfiguration().getEntityId());
+      authnRequest.setIssuer(issuer);
+
+      authnRequest.setVersion(SamlConstants.VERSION_2_0);
+
+      // Fill in the optional fields that indicate where and how the response
+      // should be delivered.
+      authnRequest.setAssertionConsumerServiceURL(serviceProvider.getServiceURL(ExternalAuthenticationService.SAML_ASSERTION_CONSUMER_SERVICE));
+      authnRequest.setProtocolBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST");
+
+      return authnRequest;
+   }
+
+   public LogoutRequestType createLogoutRequest(SeamSamlPrincipal principal) throws ConfigurationException
+   {
+      ObjectFactory objectFactory = new ObjectFactory();
+      org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.ObjectFactory assertionObjectFactory = new org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.ObjectFactory();
+
+      LogoutRequestType logoutRequest = objectFactory.createLogoutRequestType();
+
+      logoutRequest.setID(generateId());
+      logoutRequest.setIssueInstant(SamlUtils.getXMLGregorianCalendar());
+
+      NameIDType issuer = assertionObjectFactory.createNameIDType();
+      issuer.setValue(serviceProvider.getSamlConfiguration().getEntityId());
+      logoutRequest.setIssuer(issuer);
+
+      NameIDType nameID = assertionObjectFactory.createNameIDType();
+      nameID.setValue(principal.getNameId().getValue());
+      logoutRequest.setNameID(nameID);
+
+      logoutRequest.setVersion(SamlConstants.VERSION_2_0);
+      logoutRequest.getSessionIndex().add(principal.getSessionIndex());
+
+      return logoutRequest;
+   }
+
+   private String generateId()
+   {
+      return "ID_" + UUID.randomUUID();
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageFactory.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageReceiver.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageReceiver.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageReceiver.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,279 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterInputStream;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jboss.seam.security.external_authentication.configuration.SamlIdentityProvider;
+import org.jboss.seam.security.external_authentication.configuration.ServiceProvider;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.RequestAbstractType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.StatusResponseType;
+import org.jboss.seam.security.util.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+public class SamlMessageReceiver
+{
+   private static final Logger log = LoggerFactory.getLogger(SamlMessageReceiver.class);
+
+   @Inject
+   private Requests requests;
+
+   @Inject
+   private SamlSingleLogoutReceiver samlSingleLogoutReceiver;
+
+   @Inject
+   private SamlSingleSignOnReceiver samlSingleSignOnReceiver;
+
+   @Inject
+   private ServiceProvider serviceProvider;
+
+   @Inject
+   private SamlSignatureUtilForPostBinding signatureUtilForPostBinding;
+
+   @Inject
+   private SamlSignatureUtilForRedirectBinding signatureUtilForRedirectBinding;
+
+   private JAXBContext jaxbContext;
+
+   @Inject
+   public void init()
+   {
+      try
+      {
+         jaxbContext = JAXBContext.newInstance(StatusResponseType.class);
+      }
+      catch (JAXBException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   public void handleIncomingSamlMessage(SamlProfile samlProfile, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws InvalidRequestException
+   {
+      String samlRequestParam = httpRequest.getParameter(SamlConstants.QSP_SAML_REQUEST);
+      String samlResponseParam = httpRequest.getParameter(SamlConstants.QSP_SAML_RESPONSE);
+
+      RequestOrResponse requestOrResponse;
+      String samlMessage;
+
+      if (samlRequestParam != null && samlResponseParam == null)
+      {
+         samlMessage = samlRequestParam;
+         requestOrResponse = RequestOrResponse.REQUEST;
+      }
+      else if (samlRequestParam == null && samlResponseParam != null)
+      {
+         samlMessage = samlResponseParam;
+         requestOrResponse = RequestOrResponse.RESPONSE;
+      }
+      else
+      {
+         throw new InvalidRequestException("SAML message should either have a SAMLRequest parameter or a SAMLResponse parameter");
+      }
+
+      InputStream is;
+      if (httpRequest.getMethod().equals("POST"))
+      {
+         byte[] decodedMessage = Base64.decode(samlMessage);
+         is = new ByteArrayInputStream(decodedMessage);
+      }
+      else
+      {
+         String urlDecoded;
+         try
+         {
+            urlDecoded = URLDecoder.decode(samlMessage, "UTF-8");
+         }
+         catch (UnsupportedEncodingException e)
+         {
+            throw new RuntimeException(e);
+         }
+         byte[] base64Decoded = Base64.decode(urlDecoded);
+         ByteArrayInputStream bais = new ByteArrayInputStream(base64Decoded);
+         is = new InflaterInputStream(bais, new Inflater(true));
+      }
+
+      Document document = getDocument(is);
+      String issuerEntityId;
+      RequestAbstractType samlRequest = null;
+      StatusResponseType samlResponse = null;
+      if (requestOrResponse.isRequest())
+      {
+         samlRequest = getSamlRequest(document);
+         issuerEntityId = samlRequest.getIssuer().getValue();
+      }
+      else
+      {
+         samlResponse = getSamlResponse(document);
+         issuerEntityId = samlResponse.getIssuer().getValue();
+      }
+      if (log.isDebugEnabled())
+      {
+         log.debug("Received from IDP: " + SamlUtils.getDocumentAsString(document));
+      }
+
+      SamlIdentityProvider idp = serviceProvider.getSamlConfiguration().getSamlIdentityProviderByEntityId(issuerEntityId);
+      if (idp == null)
+      {
+         throw new InvalidRequestException("Received message from unknown idp " + issuerEntityId);
+      }
+
+      boolean validate;
+      if (samlProfile == SamlProfile.SINGLE_SIGN_ON)
+      {
+         validate = serviceProvider.getSamlConfiguration().isWantAssertionsSigned();
+      }
+      else
+      {
+         validate = idp.isSingleLogoutMessagesSigned();
+      }
+
+      if (validate)
+      {
+         if (log.isDebugEnabled())
+         {
+            log.debug("Validating the signature");
+         }
+         if (httpRequest.getMethod().equals("POST"))
+         {
+            signatureUtilForPostBinding.validateSignature(idp, document);
+         }
+         else
+         {
+            signatureUtilForRedirectBinding.validateSignature(idp, httpRequest, requestOrResponse);
+         }
+      }
+
+      RequestContext requestContext = null;
+      if (requestOrResponse.isResponse() && samlResponse.getInResponseTo() != null)
+      {
+         requestContext = requests.getRequest(samlResponse.getInResponseTo());
+         if (requestContext == null)
+         {
+            throw new InvalidRequestException("No request that corresponds with the received response");
+         }
+         else if (!(requestContext.getIdentityProvider().equals(idp)))
+         {
+            throw new InvalidRequestException("Identity provider of request and response do not match");
+         }
+      }
+
+      if (samlProfile == SamlProfile.SINGLE_SIGN_ON)
+      {
+         if (requestOrResponse.isRequest())
+         {
+            throw new InvalidRequestException("Assertion consumer service can only process SAML responses");
+         }
+         else
+         {
+            samlSingleSignOnReceiver.processIDPResponse(httpRequest, httpResponse, samlResponse, requestContext, idp);
+         }
+      }
+      else
+      {
+         if (requestOrResponse.isRequest())
+         {
+            samlSingleLogoutReceiver.processIDPRequest(httpRequest, httpResponse, samlRequest, idp);
+         }
+         else
+         {
+            samlSingleLogoutReceiver.processIDPResponse(httpRequest, httpResponse, samlResponse, requestContext, idp);
+         }
+      }
+   }
+
+   private RequestAbstractType getSamlRequest(Document document) throws InvalidRequestException
+   {
+      try
+      {
+         Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+         @SuppressWarnings("unchecked")
+         JAXBElement<RequestAbstractType> jaxbRequest = (JAXBElement<RequestAbstractType>) unmarshaller.unmarshal(document);
+         RequestAbstractType request = jaxbRequest.getValue();
+         return request;
+      }
+      catch (JAXBException e)
+      {
+         throw new InvalidRequestException("SAML message could not be parsed", e);
+      }
+   }
+
+   private StatusResponseType getSamlResponse(Document document) throws InvalidRequestException
+   {
+      try
+      {
+         Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+         @SuppressWarnings("unchecked")
+         JAXBElement<StatusResponseType> jaxbResponseType = (JAXBElement<StatusResponseType>) unmarshaller.unmarshal(document);
+         StatusResponseType statusResponse = jaxbResponseType.getValue();
+         return statusResponse;
+      }
+      catch (JAXBException e)
+      {
+         throw new InvalidRequestException("SAML message could not be parsed", e);
+      }
+   }
+
+   private Document getDocument(InputStream is) throws InvalidRequestException
+   {
+      try
+      {
+         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+         factory.setNamespaceAware(true);
+         factory.setXIncludeAware(true);
+         DocumentBuilder builder = factory.newDocumentBuilder();
+         return builder.parse(is);
+      }
+      catch (ParserConfigurationException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (SAXException e)
+      {
+         throw new InvalidRequestException("SAML request could not be parsed", e);
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageReceiver.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageSender.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageSender.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageSender.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,366 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.bind.Binder;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jboss.seam.security.external_authentication.configuration.Binding;
+import org.jboss.seam.security.external_authentication.configuration.SamlEndpoint;
+import org.jboss.seam.security.external_authentication.configuration.SamlIdentityProvider;
+import org.jboss.seam.security.external_authentication.configuration.SamlService;
+import org.jboss.seam.security.external_authentication.configuration.ServiceProvider;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.AuthnRequestType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.LogoutRequestType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.ObjectFactory;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.RequestAbstractType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.StatusResponseType;
+import org.jboss.seam.security.util.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+ at Named("org.picketlink.identity.seam.federation.samlMessageSender")
+public class SamlMessageSender
+{
+   private Logger log = LoggerFactory.getLogger(SamlMessageSender.class);
+
+   @Inject
+   private ServiceProvider serviceProvider;
+
+   @Inject
+   private SamlSignatureUtilForPostBinding signatureUtilForPostBinding;
+
+   @Inject
+   private SamlSignatureUtilForRedirectBinding signatureUtilForRedirectBinding;
+
+   private JAXBContext jaxbContextRequestAbstractType;
+
+   private JAXBContext jaxbContextStatusResponseType;
+
+   @Inject
+   public void init()
+   {
+      try
+      {
+         jaxbContextRequestAbstractType = JAXBContext.newInstance(RequestAbstractType.class);
+         jaxbContextStatusResponseType = JAXBContext.newInstance(StatusResponseType.class);
+      }
+      catch (JAXBException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   public void sendRequestToIDP(HttpServletRequest request, HttpServletResponse response, SamlIdentityProvider samlIdentityProvider, SamlProfile profile, RequestAbstractType samlRequest)
+   {
+      Document message = null;
+      SamlEndpoint endpoint = null;
+      try
+      {
+         SamlService service = samlIdentityProvider.getService(profile);
+         endpoint = service.getEndpointForBinding(Binding.HTTP_Post);
+         if (endpoint == null)
+         {
+            endpoint = service.getEndpointForBinding(Binding.HTTP_Redirect);
+         }
+         if (endpoint == null)
+         {
+            throw new RuntimeException("Idp " + samlIdentityProvider.getEntityId() + " has no endpoint found for profile " + profile);
+         }
+         samlRequest.setDestination(endpoint.getLocation());
+
+         JAXBElement<?> requestElement;
+         if (samlRequest instanceof AuthnRequestType)
+         {
+            AuthnRequestType authnRequest = (AuthnRequestType) samlRequest;
+            requestElement = new ObjectFactory().createAuthnRequest(authnRequest);
+         }
+         else if (samlRequest instanceof LogoutRequestType)
+         {
+            LogoutRequestType logoutRequest = (LogoutRequestType) samlRequest;
+            requestElement = new ObjectFactory().createLogoutRequest(logoutRequest);
+         }
+         else
+         {
+            throw new RuntimeException("Currently only authentication and logout requests can be sent");
+         }
+
+         Binder<Node> binder = jaxbContextRequestAbstractType.createBinder();
+
+         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+         factory.setNamespaceAware(true);
+         factory.setXIncludeAware(true);
+         DocumentBuilder builder;
+         builder = factory.newDocumentBuilder();
+         message = builder.newDocument();
+
+         binder.marshal(requestElement, message);
+      }
+      catch (JAXBException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (ParserConfigurationException e)
+      {
+         throw new RuntimeException(e);
+      }
+
+      sendMessageToIDP(request, response, samlIdentityProvider, message, RequestOrResponse.REQUEST, endpoint);
+   }
+
+   public void sendResponseToIDP(HttpServletRequest request, HttpServletResponse response, SamlIdentityProvider samlIdentityProvider, SamlEndpoint endpoint, StatusResponseType samlResponse)
+   {
+      Document message = null;
+      try
+      {
+         samlResponse.setDestination(endpoint.getResponseLocation());
+
+         JAXBElement<StatusResponseType> responseElement;
+         if (endpoint.getService().getProfile().equals(SamlProfile.SINGLE_LOGOUT))
+         {
+            responseElement = new ObjectFactory().createLogoutResponse(samlResponse);
+         }
+         else
+         {
+            throw new RuntimeException("Responses can currently only be created for the single logout service");
+         }
+
+         Binder<Node> binder = jaxbContextStatusResponseType.createBinder();
+
+         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+         factory.setNamespaceAware(true);
+         factory.setXIncludeAware(true);
+         DocumentBuilder builder;
+         builder = factory.newDocumentBuilder();
+         message = builder.newDocument();
+
+         binder.marshal(responseElement, message);
+      }
+      catch (JAXBException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (ParserConfigurationException e)
+      {
+         throw new RuntimeException(e);
+      }
+
+      sendMessageToIDP(request, response, samlIdentityProvider, message, RequestOrResponse.RESPONSE, endpoint);
+   }
+
+   private void sendMessageToIDP(HttpServletRequest request, HttpServletResponse response, SamlIdentityProvider samlIdentityProvider, Document message, RequestOrResponse requestOrResponse, SamlEndpoint endpoint)
+   {
+      if (log.isDebugEnabled())
+      {
+         log.debug("Sending over to IDP: " + SamlUtils.getDocumentAsString(message));
+      }
+
+      try
+      {
+         boolean signMessage;
+         if (endpoint.getService().getProfile().equals(SamlProfile.SINGLE_SIGN_ON))
+         {
+            signMessage = samlIdentityProvider.isWantAuthnRequestsSigned();
+         }
+         else
+         {
+            signMessage = samlIdentityProvider.isWantSingleLogoutMessagesSigned();
+         }
+
+         PrivateKey privateKey = serviceProvider.getSamlConfiguration().getPrivateKey();
+
+         if (endpoint.getBinding() == Binding.HTTP_Redirect)
+         {
+            byte[] responseBytes = SamlUtils.getDocumentAsString(message).getBytes("UTF-8");
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            Deflater deflater = new Deflater(Deflater.DEFLATED, true);
+            DeflaterOutputStream deflaterStream = new DeflaterOutputStream(baos, deflater);
+            deflaterStream.write(responseBytes);
+            deflaterStream.finish();
+
+            byte[] deflatedMsg = baos.toByteArray();
+            String urlEncodedResponse = Base64.encodeBytes(deflatedMsg);
+
+            String finalDest = endpoint.getLocation() + getQueryString(urlEncodedResponse, signMessage, requestOrResponse, privateKey);
+            SamlUtils.sendRedirect(finalDest, response);
+         }
+         else
+         {
+            if (signMessage)
+            {
+               PublicKey publicKey = serviceProvider.getSamlConfiguration().getCertificate().getPublicKey();
+               signSAMLDocument(message, new KeyPair(publicKey, privateKey));
+            }
+            byte[] responseBytes = SamlUtils.getDocumentAsString(message).getBytes("UTF-8");
+
+            String samlResponse = Base64.encodeBytes(responseBytes, Base64.DONT_BREAK_LINES);
+
+            sendPost(endpoint.getLocation(), samlResponse, response, requestOrResponse.isRequest());
+
+         }
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   private void signSAMLDocument(Document samlDocument, KeyPair keypair)
+   {
+      // Get the ID from the root
+      String id = samlDocument.getDocumentElement().getAttribute("ID");
+
+      String referenceURI = "#" + id;
+
+      signatureUtilForPostBinding.sign(samlDocument, keypair, DigestMethod.SHA1, SignatureMethod.RSA_SHA1, referenceURI);
+   }
+
+   private String getQueryString(String urlEncodedSamlMessage, boolean supportSignature, RequestOrResponse requestOrResponse, PrivateKey signingKey)
+   {
+      StringBuilder sb = new StringBuilder();
+      sb.append("?");
+
+      if (supportSignature)
+      {
+         try
+         {
+            sb.append(getURLWithSignature(requestOrResponse, urlEncodedSamlMessage, signingKey));
+         }
+         catch (IOException e)
+         {
+            throw new RuntimeException(e);
+         }
+         catch (GeneralSecurityException e)
+         {
+            throw new RuntimeException(e);
+         }
+      }
+      else
+      {
+         if (requestOrResponse == RequestOrResponse.REQUEST)
+         {
+            sb.append(SamlConstants.QSP_SAML_REQUEST);
+         }
+         else
+         {
+            sb.append(SamlConstants.QSP_SAML_RESPONSE);
+         }
+         sb.append("=").append(urlEncodedSamlMessage);
+      }
+      return sb.toString();
+   }
+
+   private void sendPost(String destination, String samlMessage, HttpServletResponse response, boolean request) throws IOException
+   {
+      String key = request ? SamlConstants.QSP_SAML_REQUEST : SamlConstants.QSP_SAML_RESPONSE;
+
+      if (destination == null)
+         throw new IllegalStateException("Destination is null");
+
+      response.setContentType("text/html");
+      PrintWriter out = response.getWriter();
+      response.setCharacterEncoding("UTF-8");
+      response.setHeader("Pragma", "no-cache");
+      response.setHeader("Cache-Control", "no-cache, no-store");
+      StringBuilder builder = new StringBuilder();
+
+      builder.append("<HTML>");
+      builder.append("<HEAD>");
+      if (request)
+         builder.append("<TITLE>HTTP Post Binding (Request)</TITLE>");
+      else
+         builder.append("<TITLE>HTTP Post Binding Response (Response)</TITLE>");
+
+      builder.append("</HEAD>");
+      builder.append("<BODY Onload=\"document.forms[0].submit()\">");
+
+      builder.append("<FORM METHOD=\"POST\" ACTION=\"" + destination + "\">");
+      builder.append("<INPUT TYPE=\"HIDDEN\" NAME=\"" + key + "\"" + " VALUE=\"" + samlMessage + "\"/>");
+      builder.append("</FORM></BODY></HTML>");
+
+      String str = builder.toString();
+      out.println(str);
+      out.close();
+   }
+
+   private String getURLWithSignature(RequestOrResponse requestOrResponse, String urlEncodedResponse, PrivateKey signingKey) throws IOException, GeneralSecurityException
+   {
+      String messageParameter;
+      if (requestOrResponse == RequestOrResponse.REQUEST)
+      {
+         messageParameter = SamlConstants.QSP_SAML_REQUEST;
+      }
+      else
+      {
+         messageParameter = SamlConstants.QSP_SAML_RESPONSE;
+      }
+
+      byte[] signature = signatureUtilForRedirectBinding.computeSignature(messageParameter + "=" + urlEncodedResponse, signingKey);
+      String sigAlgo = signingKey.getAlgorithm();
+
+      StringBuilder sb = new StringBuilder();
+      sb.append(messageParameter + "=").append(urlEncodedResponse);
+
+      try
+      {
+         sb.append("&").append(SamlConstants.QSP_SIG_ALG).append("=");
+         String sigAlg = signatureUtilForRedirectBinding.getXMLSignatureAlgorithmURI(sigAlgo);
+         sb.append(URLEncoder.encode(sigAlg, "UTF-8"));
+
+         sb.append("&").append(SamlConstants.QSP_SIGNATURE).append("=");
+         String base64encodedSignature = Base64.encodeBytes(signature, Base64.DONT_BREAK_LINES);
+         sb.append(URLEncoder.encode(base64encodedSignature, "UTF-8"));
+      }
+      catch (UnsupportedEncodingException e)
+      {
+         throw new RuntimeException(e);
+      }
+
+      return sb.toString();
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMessageSender.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMetaDataProvider.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMetaDataProvider.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMetaDataProvider.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,130 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.io.OutputStream;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import javax.inject.Inject;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+
+import org.jboss.seam.security.external_authentication.configuration.ServiceProvider;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata.EntityDescriptorType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata.IndexedEndpointType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata.KeyDescriptorType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata.KeyTypes;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata.ObjectFactory;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata.SPSSODescriptorType;
+import org.jboss.seam.security.external_authentication.jaxb.xmldsig.KeyInfoType;
+import org.jboss.seam.security.external_authentication.jaxb.xmldsig.X509DataType;
+
+public class SamlMetaDataProvider
+{
+   @Inject
+   private ServiceProvider serviceProvider;
+
+   public void writeMetaData(OutputStream stream)
+   {
+      try
+      {
+         ObjectFactory metaDataFactory = new ObjectFactory();
+
+         IndexedEndpointType acsRedirectEndpoint = metaDataFactory.createIndexedEndpointType();
+         acsRedirectEndpoint.setBinding(SamlConstants.HTTP_REDIRECT_BINDING);
+         acsRedirectEndpoint.setLocation(serviceProvider.getServiceURL(ExternalAuthenticationService.SAML_ASSERTION_CONSUMER_SERVICE));
+
+         IndexedEndpointType acsPostEndpoint = metaDataFactory.createIndexedEndpointType();
+         acsPostEndpoint.setBinding(SamlConstants.HTTP_POST_BINDING);
+         acsPostEndpoint.setLocation(serviceProvider.getServiceURL(ExternalAuthenticationService.SAML_ASSERTION_CONSUMER_SERVICE));
+
+         IndexedEndpointType sloRedirectEndpoint = metaDataFactory.createIndexedEndpointType();
+         sloRedirectEndpoint.setBinding(SamlConstants.HTTP_REDIRECT_BINDING);
+         sloRedirectEndpoint.setLocation(serviceProvider.getServiceURL(ExternalAuthenticationService.SAML_SINGLE_LOGOUT_SERVICE));
+
+         IndexedEndpointType sloPostEndpoint = metaDataFactory.createIndexedEndpointType();
+         sloPostEndpoint.setBinding(SamlConstants.HTTP_POST_BINDING);
+         sloPostEndpoint.setLocation(serviceProvider.getServiceURL(ExternalAuthenticationService.SAML_SINGLE_LOGOUT_SERVICE));
+
+         SPSSODescriptorType spSsoDescriptor = metaDataFactory.createSPSSODescriptorType();
+         spSsoDescriptor.setAuthnRequestsSigned(serviceProvider.getSamlConfiguration().isAuthnRequestsSigned());
+         spSsoDescriptor.setWantAssertionsSigned(serviceProvider.getSamlConfiguration().isWantAssertionsSigned());
+
+         spSsoDescriptor.getAssertionConsumerService().add(acsRedirectEndpoint);
+         spSsoDescriptor.getAssertionConsumerService().add(acsPostEndpoint);
+         spSsoDescriptor.getSingleLogoutService().add(sloRedirectEndpoint);
+         spSsoDescriptor.getSingleLogoutService().add(sloPostEndpoint);
+
+         spSsoDescriptor.getProtocolSupportEnumeration().add(SamlConstants.PROTOCOL_NSURI);
+
+         spSsoDescriptor.getNameIDFormat().add("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent");
+         spSsoDescriptor.getNameIDFormat().add("urn:oasis:names:tc:SAML:2.0:nameid-format:transient");
+         spSsoDescriptor.getNameIDFormat().add("urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified");
+         spSsoDescriptor.getNameIDFormat().add("urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress");
+
+         org.jboss.seam.security.external_authentication.jaxb.xmldsig.ObjectFactory signatureFactory = new org.jboss.seam.security.external_authentication.jaxb.xmldsig.ObjectFactory();
+
+         X509Certificate certificate = serviceProvider.getSamlConfiguration().getCertificate();
+         if (certificate == null)
+            throw new RuntimeException("Certificate obtained from configuration is null");
+
+         JAXBElement<byte[]> X509Certificate;
+         try
+         {
+            X509Certificate = signatureFactory.createX509DataTypeX509Certificate(certificate.getEncoded());
+         }
+         catch (CertificateEncodingException e)
+         {
+            throw new RuntimeException(e);
+         }
+
+         X509DataType X509Data = signatureFactory.createX509DataType();
+         X509Data.getX509IssuerSerialOrX509SKIOrX509SubjectName().add(X509Certificate);
+
+         KeyInfoType keyInfo = signatureFactory.createKeyInfoType();
+         keyInfo.getContent().add(signatureFactory.createX509Data(X509Data));
+
+         KeyDescriptorType keyDescriptor = metaDataFactory.createKeyDescriptorType();
+         keyDescriptor.setUse(KeyTypes.SIGNING);
+         keyDescriptor.setKeyInfo(keyInfo);
+
+         spSsoDescriptor.getKeyDescriptor().add(keyDescriptor);
+
+         EntityDescriptorType entityDescriptor = metaDataFactory.createEntityDescriptorType();
+         entityDescriptor.setEntityID(serviceProvider.getSamlConfiguration().getEntityId());
+         entityDescriptor.getRoleDescriptorOrIDPSSODescriptorOrSPSSODescriptor().add(spSsoDescriptor);
+
+         JAXBContext jaxbContext = JAXBContext.newInstance("org.picketlink.identity.federation.saml.v2.metadata");
+         Marshaller marshaller = jaxbContext.createMarshaller();
+         marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
+         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+         marshaller.marshal(metaDataFactory.createEntityDescriptor(entityDescriptor), stream);
+      }
+      catch (JAXBException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlMetaDataProvider.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlProfile.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlProfile.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlProfile.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,27 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+public enum SamlProfile
+{
+   SINGLE_SIGN_ON, SINGLE_LOGOUT
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlProfile.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSignatureUtilForPostBinding.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSignatureUtilForPostBinding.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSignatureUtilForPostBinding.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,199 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.security.AccessController;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Key;
+import java.security.KeyException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PrivilegedAction;
+import java.security.PublicKey;
+import java.security.Security;
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.dom.DOMSignContext;
+import javax.xml.crypto.dsig.dom.DOMValidateContext;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
+import javax.xml.crypto.dsig.keyinfo.KeyValue;
+import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
+import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+
+import org.jboss.seam.security.external_authentication.configuration.SamlIdentityProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+public class SamlSignatureUtilForPostBinding
+{
+   private Logger log = LoggerFactory.getLogger(SamlSignatureUtilForPostBinding.class);
+
+   private XMLSignatureFactory fac = getXMLSignatureFactory();
+
+   private XMLSignatureFactory getXMLSignatureFactory()
+   {
+      if (Security.getProvider("DOM") != null)
+      {
+         return XMLSignatureFactory.getInstance("DOM");
+      }
+      else
+      {
+         // No security provider found for the XML Digital Signature API (JSR
+         // 105). Probably we have to do with JDK 1.5 or lower.
+         // See
+         // http://weblogs.java.net/blog/2008/02/27/using-jsr-105-jdk-14-or-15.
+         // We assume that the reference implementation of JSR 105 is available
+         // at runtime.
+         return XMLSignatureFactory.getInstance("DOM", new org.jcp.xml.dsig.internal.dom.XMLDSigRI());
+      }
+   }
+
+   static
+   {
+      AccessController.doPrivileged(new PrivilegedAction<Object>()
+      {
+         public Object run()
+         {
+            System.setProperty("org.apache.xml.security.ignoreLineBreaks", "true");
+            return null;
+         }
+      });
+   };
+
+   public Document sign(Document doc, KeyPair keyPair, String digestMethod, String signatureMethod, String referenceURI)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Document to be signed={0}", new Object[] { SamlUtils.getDocumentAsString(doc) });
+      }
+      PrivateKey signingKey = keyPair.getPrivate();
+      PublicKey publicKey = keyPair.getPublic();
+
+      DOMSignContext dsc = new DOMSignContext(signingKey, doc.getDocumentElement());
+      dsc.setDefaultNamespacePrefix("dsig");
+
+      try
+      {
+         DigestMethod digestMethodObj = fac.newDigestMethod(digestMethod, null);
+         Transform transform = fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
+
+         List<Transform> transformList = Collections.singletonList(transform);
+         Reference ref = fac.newReference(referenceURI, digestMethodObj, transformList, null, null);
+
+         String canonicalizationMethodType = CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS;
+         CanonicalizationMethod canonicalizationMethod = fac.newCanonicalizationMethod(canonicalizationMethodType, (C14NMethodParameterSpec) null);
+
+         List<Reference> referenceList = Collections.singletonList(ref);
+         SignatureMethod signatureMethodObj = fac.newSignatureMethod(signatureMethod, null);
+         SignedInfo si = fac.newSignedInfo(canonicalizationMethod, signatureMethodObj, referenceList);
+
+         KeyInfoFactory kif = fac.getKeyInfoFactory();
+         KeyValue kv = kif.newKeyValue(publicKey);
+         KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));
+
+         XMLSignature signature = fac.newXMLSignature(si, ki);
+
+         signature.sign(dsc);
+      }
+      catch (XMLSignatureException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (NoSuchAlgorithmException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (InvalidAlgorithmParameterException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (KeyException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (MarshalException e)
+      {
+         throw new RuntimeException(e);
+
+      }
+      return doc;
+   }
+
+   public void validateSignature(SamlIdentityProvider idp, Document signedDoc) throws InvalidRequestException
+   {
+      Key publicKey = idp.getPublicKey();
+
+      NodeList nl = signedDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
+      if (nl == null || nl.getLength() == 0)
+      {
+         throw new InvalidRequestException("Signature element is not present or has zero length.");
+      }
+
+      try
+      {
+         DOMValidateContext valContext = new DOMValidateContext(publicKey, nl.item(0));
+         XMLSignature signature = fac.unmarshalXMLSignature(valContext);
+         boolean signatureValid = signature.validate(valContext);
+
+         if (log.isTraceEnabled() && !signatureValid)
+         {
+            boolean sv = signature.getSignatureValue().validate(valContext);
+            log.trace("Signature validation status: " + sv);
+
+            @SuppressWarnings("unchecked")
+            List<Reference> references = signature.getSignedInfo().getReferences();
+            for (Reference ref : references)
+            {
+               log.trace("[Ref id=" + ref.getId() + ":uri=" + ref.getURI() + "] validity status:" + ref.validate(valContext));
+            }
+         }
+
+         if (!signatureValid)
+         {
+            throw new InvalidRequestException("Invalid signature.");
+         }
+      }
+      catch (XMLSignatureException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (MarshalException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+}
\ No newline at end of file


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSignatureUtilForPostBinding.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSignatureUtilForRedirectBinding.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSignatureUtilForRedirectBinding.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSignatureUtilForRedirectBinding.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,174 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.security.GeneralSecurityException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.jboss.seam.security.external_authentication.configuration.SamlIdentityProvider;
+import org.jboss.seam.security.util.Base64;
+
+public class SamlSignatureUtilForRedirectBinding
+{
+   byte[] computeSignature(String requestOrResponseKeyValuePair, PrivateKey signingKey) throws IOException, GeneralSecurityException
+   {
+      StringBuilder sb = new StringBuilder();
+      sb.append(requestOrResponseKeyValuePair);
+      String algo = signingKey.getAlgorithm();
+
+      String sigAlg = getXMLSignatureAlgorithmURI(algo);
+      sigAlg = URLEncoder.encode(sigAlg, "UTF-8");
+      sb.append("&SigAlg=").append(sigAlg);
+
+      byte[] sigValue = sign(sb.toString(), signingKey);
+
+      return sigValue;
+   }
+
+   private byte[] sign(String stringToBeSigned, PrivateKey signingKey) throws GeneralSecurityException
+   {
+      String algo = signingKey.getAlgorithm();
+      Signature sig = getSignature(algo);
+      sig.initSign(signingKey);
+      sig.update(stringToBeSigned.getBytes());
+      return sig.sign();
+   }
+
+   public void validateSignature(SamlIdentityProvider idp, HttpServletRequest httpRequest, RequestOrResponse requestOrResponse) throws InvalidRequestException
+   {
+      String sigValueParam = httpRequest.getParameter(SamlConstants.QSP_SIGNATURE);
+      if (sigValueParam == null)
+      {
+         throw new InvalidRequestException("Signature parameter is not present.");
+      }
+
+      String decodedString;
+      try
+      {
+         decodedString = URLDecoder.decode(sigValueParam, "UTF-8");
+      }
+      catch (UnsupportedEncodingException e)
+      {
+         throw new RuntimeException(e);
+      }
+
+      byte[] sigValue = Base64.decode(decodedString);
+
+      String samlMessageParameter;
+      if (requestOrResponse == RequestOrResponse.REQUEST)
+      {
+         samlMessageParameter = SamlConstants.QSP_SAML_REQUEST;
+      }
+      else
+      {
+         samlMessageParameter = SamlConstants.QSP_SAML_RESPONSE;
+      }
+
+      // Construct the url again
+      String reqFromURL = httpRequest.getParameter(samlMessageParameter);
+      String relayStateFromURL = httpRequest.getParameter(SamlConstants.QSP_RELAY_STATE);
+      String sigAlgFromURL = httpRequest.getParameter(SamlConstants.QSP_SIG_ALG);
+
+      StringBuilder sb = new StringBuilder();
+      sb.append(samlMessageParameter).append("=").append(reqFromURL);
+
+      if (relayStateFromURL != null && relayStateFromURL.length() != 0)
+      {
+         sb.append("&").append(SamlConstants.QSP_RELAY_STATE).append("=").append(relayStateFromURL);
+      }
+      sb.append("&").append(SamlConstants.QSP_SIG_ALG).append("=").append(sigAlgFromURL);
+
+      PublicKey validatingKey = idp.getPublicKey();
+
+      boolean isValid;
+      try
+      {
+         isValid = validate(sb.toString().getBytes("UTF-8"), sigValue, validatingKey);
+      }
+      catch (UnsupportedEncodingException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (GeneralSecurityException e)
+      {
+         throw new RuntimeException(e);
+      }
+
+      if (!isValid)
+      {
+         throw new InvalidRequestException("Invalid signature.");
+      }
+   }
+
+   private boolean validate(byte[] signedContent, byte[] signatureValue, PublicKey validatingKey) throws GeneralSecurityException
+   {
+      // We assume that the sigatureValue has the same algorithm as the public
+      // key
+      // If not, there will be an exception anyway
+      String algo = validatingKey.getAlgorithm();
+      Signature sig = getSignature(algo);
+
+      sig.initVerify(validatingKey);
+      sig.update(signedContent);
+      return sig.verify(signatureValue);
+   }
+
+   private Signature getSignature(String algo) throws GeneralSecurityException
+   {
+      Signature sig = null;
+
+      if ("DSA".equalsIgnoreCase(algo))
+      {
+         sig = Signature.getInstance(SamlConstants.DSA_SIGNATURE_ALGORITHM);
+      }
+      else if ("RSA".equalsIgnoreCase(algo))
+      {
+         sig = Signature.getInstance(SamlConstants.RSA_SIGNATURE_ALGORITHM);
+      }
+      else
+         throw new RuntimeException("Unknown signature algorithm:" + algo);
+      return sig;
+   }
+
+   public String getXMLSignatureAlgorithmURI(String algo)
+   {
+      String xmlSignatureAlgo = null;
+
+      if ("DSA".equalsIgnoreCase(algo))
+      {
+         xmlSignatureAlgo = SamlConstants.SIGNATURE_SHA1_WITH_DSA;
+      }
+      else if ("RSA".equalsIgnoreCase(algo))
+      {
+         xmlSignatureAlgo = SamlConstants.SIGNATURE_SHA1_WITH_RSA;
+      }
+      return xmlSignatureAlgo;
+   }
+}
\ No newline at end of file


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSignatureUtilForRedirectBinding.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleLogoutReceiver.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleLogoutReceiver.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleLogoutReceiver.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,94 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.seam.security.Identity;
+import org.jboss.seam.security.external_authentication.configuration.Binding;
+import org.jboss.seam.security.external_authentication.configuration.SamlEndpoint;
+import org.jboss.seam.security.external_authentication.configuration.SamlIdentityProvider;
+import org.jboss.seam.security.external_authentication.configuration.ServiceProvider;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.LogoutRequestType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.RequestAbstractType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.StatusResponseType;
+
+public class SamlSingleLogoutReceiver
+{
+   @Inject
+   private SamlMessageFactory samlMessageFactory;
+
+   @Inject
+   private SamlMessageSender samlMessageSender;
+
+   @Inject
+   private Identity identity;
+
+   @Inject
+   private ServiceProvider serviceProvider;
+
+   public void processIDPRequest(HttpServletRequest httpRequest, HttpServletResponse httpResponse, RequestAbstractType request, SamlIdentityProvider idp) throws InvalidRequestException
+   {
+      if (!(request instanceof LogoutRequestType))
+      {
+         throw new InvalidRequestException("Request should be a single logout request.");
+      }
+
+      if (!identity.isLoggedIn())
+      {
+         throw new InvalidRequestException("No active session to logout.");
+      }
+
+      // FIXME: Identity.instance().logout();
+
+      StatusResponseType response = samlMessageFactory.createStatusResponse(request, SamlConstants.STATUS_SUCCESS, null);
+
+      Binding binding = httpRequest.getMethod().equals("POST") ? Binding.HTTP_Post : Binding.HTTP_Redirect;
+      SamlEndpoint endpoint = idp.getService(SamlProfile.SINGLE_LOGOUT).getEndpointForBinding(binding);
+
+      samlMessageSender.sendResponseToIDP(httpRequest, httpResponse, idp, endpoint, response);
+   }
+
+   public void processIDPResponse(HttpServletRequest httpRequest, HttpServletResponse httpResponse, StatusResponseType response, RequestContext requestContext, SamlIdentityProvider idp)
+   {
+      if (response.getStatus() != null && response.getStatus().getStatusCode().getValue().equals(SamlConstants.STATUS_SUCCESS))
+      {
+         // FIXME Identity.instance().logout();
+      }
+      else
+      {
+         throw new RuntimeException("Single logout failed. Status code: " + (response.getStatus() == null ? "null" : response.getStatus().getStatusCode().getValue()));
+      }
+      try
+      {
+         httpResponse.sendRedirect(serviceProvider.getLoggedOutUrl());
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleLogoutReceiver.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleLogoutSender.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleLogoutSender.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleLogoutSender.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.seam.security.Identity;
+import org.jboss.seam.security.external_authentication.configuration.SamlIdentityProvider;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.LogoutRequestType;
+
+public class SamlSingleLogoutSender
+{
+   @Inject
+   private Requests requests;
+
+   @Inject
+   private SamlMessageSender samlMessageSender;
+
+   @Inject
+   private SamlMessageFactory samlMessageFactory;
+
+   public void sendSingleLogoutRequestToIDP(HttpServletRequest request, HttpServletResponse response, Identity identity)
+   {
+      SeamSamlPrincipal principal = (SeamSamlPrincipal) null; // FIXME:
+                                                              // identity.getPrincipal()
+                                                              // is not
+                                                              // available any
+                                                              // more
+      SamlIdentityProvider idp = (SamlIdentityProvider) principal.getIdentityProvider();
+      LogoutRequestType logoutRequest;
+      try
+      {
+         logoutRequest = samlMessageFactory.createLogoutRequest(principal);
+         requests.addRequest(logoutRequest.getID(), idp, null);
+      }
+      catch (ConfigurationException e)
+      {
+         throw new RuntimeException(e);
+      }
+
+      samlMessageSender.sendRequestToIDP(request, response, idp, SamlProfile.SINGLE_LOGOUT, logoutRequest);
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleLogoutSender.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleSignOnReceiver.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleSignOnReceiver.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleSignOnReceiver.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,314 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.security.auth.login.LoginException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.bind.JAXBElement;
+import javax.xml.datatype.DatatypeConstants;
+
+import org.jboss.seam.security.Identity;
+import org.jboss.seam.security.events.LoginFailedEvent;
+import org.jboss.seam.security.events.PostAuthenticateEvent;
+import org.jboss.seam.security.external_authentication.configuration.SamlIdentityProvider;
+import org.jboss.seam.security.external_authentication.configuration.ServiceProvider;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.AssertionType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.AttributeStatementType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.AttributeType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.AuthnStatementType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.NameIDType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.StatementAbstractType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.SubjectConfirmationDataType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.SubjectConfirmationType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.ResponseType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.StatusResponseType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.StatusType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SamlSingleSignOnReceiver
+{
+   private Logger log = LoggerFactory.getLogger(SamlSingleSignOnReceiver.class);
+
+   @Inject
+   private Requests requests;
+
+   @Inject
+   private Identity identity;
+
+   @Inject
+   private InternalAuthenticator internalAuthenticator;
+
+   @Inject
+   private ServiceProvider serviceProvider;
+
+   @Inject
+   private BeanManager beanManager;
+
+   public void processIDPResponse(HttpServletRequest httpRequest, HttpServletResponse httpResponse, StatusResponseType statusResponse, RequestContext requestContext, SamlIdentityProvider idp) throws InvalidRequestException
+   {
+      StatusType status = statusResponse.getStatus();
+      if (status == null)
+      {
+         throw new InvalidRequestException("Response does not contain a status");
+      }
+
+      String statusValue = status.getStatusCode().getValue();
+      if (SamlConstants.STATUS_SUCCESS.equals(statusValue) == false)
+      {
+         throw new RuntimeException("IDP returned status " + statusValue);
+      }
+
+      if (!(statusResponse instanceof ResponseType))
+      {
+         throw new InvalidRequestException("Response does not have type ResponseType");
+      }
+
+      ResponseType response = (ResponseType) statusResponse;
+
+      List<Object> assertions = response.getAssertionOrEncryptedAssertion();
+      if (assertions.size() == 0)
+      {
+         throw new RuntimeException("IDP response does not contain assertions");
+      }
+
+      SeamSamlPrincipal principal = getAuthenticatedUser(response, requestContext);
+      if (principal == null)
+      {
+         try
+         {
+            beanManager.fireEvent(new PostAuthenticateEvent());
+            beanManager.fireEvent(new LoginFailedEvent(new LoginException()));
+
+            httpResponse.sendRedirect(serviceProvider.getFailedAuthenticationUrl());
+         }
+         catch (IOException e)
+         {
+            throw new RuntimeException(e);
+         }
+      }
+      else
+      {
+         // Login the user, and redirect to the requested page.
+         principal.setIdentityProvider(idp);
+         loginUser(httpRequest, httpResponse, principal, requestContext);
+      }
+   }
+
+   private SeamSamlPrincipal getAuthenticatedUser(ResponseType responseType, RequestContext requestContext)
+   {
+      SeamSamlPrincipal principal = null;
+
+      for (Object assertion : responseType.getAssertionOrEncryptedAssertion())
+      {
+         if (assertion instanceof AssertionType)
+         {
+            SeamSamlPrincipal assertionSubject = handleAssertion((AssertionType) assertion, requestContext);
+            if (principal == null)
+            {
+               principal = assertionSubject;
+            }
+            else
+            {
+               log.warn("Multiple authenticated users found in assertions. Using the first one.");
+            }
+         }
+         else
+         {
+            /* assertion instanceof EncryptedElementType */
+            log.warn("Encountered encrypted assertion. Skipping it because decryption is not yet supported.");
+         }
+      }
+      return principal;
+   }
+
+   private SeamSamlPrincipal handleAssertion(AssertionType assertion, RequestContext requestContext)
+   {
+      if (SamlUtils.hasAssertionExpired(assertion))
+      {
+         log.warn("Received assertion not processed because it has expired.");
+         return null;
+      }
+
+      AuthnStatementType authnStatement = extractValidAuthnStatement(assertion);
+      if (authnStatement == null)
+      {
+         log.warn("Received assertion not processed because it doesn't contain a valid authnStatement.");
+         return null;
+      }
+
+      NameIDType nameId = validateSubjectAndExtractNameID(assertion, requestContext);
+      if (nameId == null)
+      {
+         log.warn("Received assertion not processed because it doesn't contain a valid subject.");
+         return null;
+      }
+
+      SeamSamlPrincipal principal = new SeamSamlPrincipal();
+      principal.setAssertion(assertion);
+      principal.setSessionIndex(authnStatement.getSessionIndex());
+      principal.setNameId(nameId);
+
+      for (StatementAbstractType statement : assertion.getStatementOrAuthnStatementOrAuthzDecisionStatement())
+      {
+         if (statement instanceof AttributeStatementType)
+         {
+            AttributeStatementType attributeStatement = (AttributeStatementType) statement;
+            List<AttributeType> attributes = new LinkedList<AttributeType>();
+            for (Object object : attributeStatement.getAttributeOrEncryptedAttribute())
+            {
+               if (object instanceof AttributeType)
+               {
+                  attributes.add((AttributeType) object);
+               }
+               else
+               {
+                  log.warn("Encrypted attributes are not supported. Ignoring the attribute.");
+               }
+            }
+            principal.setAttributes(attributes);
+         }
+      }
+
+      return principal;
+   }
+
+   private AuthnStatementType extractValidAuthnStatement(AssertionType assertion)
+   {
+      for (StatementAbstractType statement : assertion.getStatementOrAuthnStatementOrAuthzDecisionStatement())
+      {
+         if (statement instanceof AuthnStatementType)
+         {
+            AuthnStatementType authnStatement = (AuthnStatementType) statement;
+            return authnStatement;
+         }
+      }
+
+      return null;
+   }
+
+   private NameIDType validateSubjectAndExtractNameID(AssertionType assertion, RequestContext requestContext)
+   {
+      NameIDType nameId = null;
+      boolean validConfirmationFound = false;
+
+      for (JAXBElement<?> contentElement : assertion.getSubject().getContent())
+      {
+         if (contentElement.getValue() instanceof NameIDType)
+         {
+            nameId = (NameIDType) contentElement.getValue();
+         }
+         if (contentElement.getValue() instanceof SubjectConfirmationType)
+         {
+            SubjectConfirmationType confirmation = (SubjectConfirmationType) contentElement.getValue();
+            if (confirmation.getMethod().equals(SamlConstants.CONFIRMATION_METHOD_BEARER))
+            {
+               SubjectConfirmationDataType confirmationData = confirmation.getSubjectConfirmationData();
+
+               boolean validRecipient = confirmationData.getRecipient().equals(serviceProvider.getServiceURL(ExternalAuthenticationService.SAML_ASSERTION_CONSUMER_SERVICE));
+
+               boolean notTooLate = confirmationData.getNotOnOrAfter().compare(SamlUtils.getXMLGregorianCalendar()) == DatatypeConstants.GREATER;
+
+               boolean validInResponseTo = requestContext == null || confirmationData.getInResponseTo().equals(requestContext.getId());
+
+               if (validRecipient && notTooLate && validInResponseTo)
+               {
+                  validConfirmationFound = true;
+               }
+            }
+         }
+      }
+
+      if (validConfirmationFound)
+      {
+         return nameId;
+      }
+      else
+      {
+         return null;
+      }
+   }
+
+   private void loginUser(HttpServletRequest httpRequest, HttpServletResponse httpResponse, SeamSamlPrincipal principal, RequestContext requestContext)
+   {
+      if (identity.isLoggedIn())
+      {
+         throw new RuntimeException("User is already logged in.");
+      }
+
+      boolean internallyAuthenticated = internalAuthenticator.authenticate(principal, httpRequest);
+
+      try
+      {
+         if (internallyAuthenticated)
+         {
+            if (requestContext == null)
+            {
+               redirectForUnsolicitedAuthentication(httpRequest, httpResponse);
+            }
+            else
+            {
+               requests.redirect(requestContext.getId(), httpResponse);
+            }
+         }
+         else
+         {
+            httpResponse.sendRedirect(serviceProvider.getFailedAuthenticationUrl());
+         }
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   private void redirectForUnsolicitedAuthentication(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException
+   {
+      String relayState = httpRequest.getParameter("RelayState");
+
+      /* Unsolicited authentication. */
+
+      if (relayState != null)
+      {
+         httpResponse.sendRedirect(relayState);
+      }
+      else
+      {
+         String unsolicitedAuthenticationUrl = serviceProvider.getUnsolicitedAuthenticationUrl();
+         if (unsolicitedAuthenticationUrl != null)
+         {
+            httpResponse.sendRedirect(unsolicitedAuthenticationUrl);
+         }
+         else
+         {
+            throw new RuntimeException("Unsolicited login could not be handled because the unsolicitedAuthenticationViewId property has not been configured");
+         }
+      }
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleSignOnReceiver.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleSignOnSender.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleSignOnSender.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleSignOnSender.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,35 @@
+package org.jboss.seam.security.external_authentication;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.seam.security.events.PreAuthenticateEvent;
+import org.jboss.seam.security.external_authentication.configuration.SamlIdentityProvider;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol.AuthnRequestType;
+
+public class SamlSingleSignOnSender
+{
+   @Inject
+   private Requests requests;
+
+   @Inject
+   private SamlMessageFactory samlMessageFactory;
+
+   @Inject
+   private SamlMessageSender samlMessageSender;
+
+   @Inject
+   private BeanManager beanManager;
+
+   public void sendAuthenticationRequestToIDP(HttpServletRequest request, HttpServletResponse response, SamlIdentityProvider samlIdentityProvider, String returnUrl)
+   {
+      AuthnRequestType authnRequest = samlMessageFactory.createAuthnRequest();
+      requests.addRequest(authnRequest.getID(), samlIdentityProvider, returnUrl);
+
+      beanManager.fireEvent(new PreAuthenticateEvent());
+
+      samlMessageSender.sendRequestToIDP(request, response, samlIdentityProvider, SamlProfile.SINGLE_SIGN_ON, authnRequest);
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlSingleSignOnSender.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlUtils.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlUtils.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlUtils.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,128 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.GregorianCalendar;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeConstants;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.AssertionType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.ConditionsType;
+import org.w3c.dom.Document;
+
+public class SamlUtils
+{
+
+   public static XMLGregorianCalendar getXMLGregorianCalendar()
+   {
+      try
+      {
+         DatatypeFactory dtf = DatatypeFactory.newInstance();
+         return dtf.newXMLGregorianCalendar(new GregorianCalendar());
+      }
+      catch (DatatypeConfigurationException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   public static boolean hasAssertionExpired(AssertionType assertion)
+   {
+      ConditionsType conditionsType = assertion.getConditions();
+      if (conditionsType != null)
+      {
+         XMLGregorianCalendar now = getXMLGregorianCalendar();
+         XMLGregorianCalendar notBefore = conditionsType.getNotBefore();
+         XMLGregorianCalendar notOnOrAfter = conditionsType.getNotOnOrAfter();
+
+         int val = notBefore.compare(now);
+         if (val == DatatypeConstants.INDETERMINATE || val == DatatypeConstants.GREATER)
+         {
+            return true;
+         }
+
+         val = notOnOrAfter.compare(now);
+         if (val != DatatypeConstants.GREATER)
+         {
+            return true;
+         }
+
+         return false;
+      }
+      else
+      {
+         return false;
+      }
+   }
+
+   public static String getDocumentAsString(Document document)
+   {
+      Source source = new DOMSource(document);
+      StringWriter sw = new StringWriter();
+
+      Result streamResult = new StreamResult(sw);
+      try
+      {
+         Transformer transformer = TransformerFactory.newInstance().newTransformer();
+         transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+         transformer.setOutputProperty(OutputKeys.INDENT, "no");
+         transformer.transform(source, streamResult);
+      }
+      catch (TransformerException e)
+      {
+         throw new RuntimeException(e);
+      }
+
+      return sw.toString();
+   }
+
+   public static void sendRedirect(String destination, HttpServletResponse response)
+   {
+      response.setCharacterEncoding("UTF-8");
+      response.setHeader("Location", destination);
+      response.setHeader("Pragma", "no-cache");
+      response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate,private");
+      response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+      try
+      {
+         response.sendRedirect(destination);
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException();
+      }
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SamlUtils.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SeamSamlPrincipal.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SeamSamlPrincipal.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SeamSamlPrincipal.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,99 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication;
+
+import java.security.Principal;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.jboss.seam.security.external_authentication.configuration.SamlIdentityProvider;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.AssertionType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.AttributeType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion.NameIDType;
+
+public class SeamSamlPrincipal implements Principal
+{
+   private NameIDType nameId;
+
+   private SamlIdentityProvider identityProvider;
+
+   private List<AttributeType> attributes = new LinkedList<AttributeType>();
+
+   private String sessionIndex;
+
+   private AssertionType assertion;
+
+   public NameIDType getNameId()
+   {
+      return nameId;
+   }
+
+   public void setNameId(NameIDType nameId)
+   {
+      this.nameId = nameId;
+   }
+
+   public SamlIdentityProvider getIdentityProvider()
+   {
+      return identityProvider;
+   }
+
+   public void setIdentityProvider(SamlIdentityProvider identityProvider)
+   {
+      this.identityProvider = identityProvider;
+   }
+
+   public List<AttributeType> getAttributes()
+   {
+      return attributes;
+   }
+
+   public void setAttributes(List<AttributeType> attributes)
+   {
+      this.attributes = attributes;
+   }
+
+   public String getSessionIndex()
+   {
+      return sessionIndex;
+   }
+
+   public void setSessionIndex(String sessionIndex)
+   {
+      this.sessionIndex = sessionIndex;
+   }
+
+   public AssertionType getAssertion()
+   {
+      return assertion;
+   }
+
+   public void setAssertion(AssertionType assertion)
+   {
+      this.assertion = assertion;
+   }
+
+   public String getName()
+   {
+      return nameId.getValue();
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/SeamSamlPrincipal.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/Binding.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/Binding.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/Binding.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,27 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication.configuration;
+
+public enum Binding
+{
+   HTTP_Redirect, HTTP_Post
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/Binding.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/Configuration.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/Configuration.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/Configuration.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,129 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication.configuration;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.jboss.seam.security.external_authentication.jaxb.config.ExternalAuthenticationConfigType;
+import org.jboss.seam.security.external_authentication.jaxb.config.ServiceProviderType;
+import org.xml.sax.SAXException;
+
+ at Named("configuration")
+ at ApplicationScoped
+// FIXME @Startup
+public class Configuration
+{
+   private final static String CONFIGURATION_FILE = "/external-authentication-config.xml";
+
+   private String contextRoot;
+
+   private Map<String, ServiceProvider> serviceProviderMap = new HashMap<String, ServiceProvider>();
+
+   @Inject
+   public void init()
+   {
+      List<ServiceProvider> serviceProviders = new LinkedList<ServiceProvider>();
+      ExternalAuthenticationConfigType externalAuthenticationConfig = readConfigurationFile();
+      for (ServiceProviderType serviceProvider : externalAuthenticationConfig.getServiceProvider())
+      {
+         serviceProviders.add(new ServiceProvider(this, serviceProvider));
+      }
+
+      for (ServiceProvider sp : serviceProviders)
+      {
+         if (serviceProviderMap.containsKey(sp.getHostname()))
+         {
+            throw new RuntimeException("Two service providers have the same hostname");
+         }
+         serviceProviderMap.put(sp.getHostname(), sp);
+      }
+   }
+
+   private ExternalAuthenticationConfigType readConfigurationFile()
+   {
+      ExternalAuthenticationConfigType externalAuthenticationConfig;
+      try
+      {
+         JAXBContext jaxbContext = JAXBContext.newInstance("org.jboss.seam.security.external_authentication.jaxb.config");
+         Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+         URL schemaURL = getClass().getResource("/schema/config/external-authentication-config.xsd");
+         Schema schema;
+         try
+         {
+            schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(schemaURL);
+         }
+         catch (SAXException e)
+         {
+            throw new RuntimeException(e);
+         }
+         unmarshaller.setSchema(schema);
+
+         JAXBElement<?> o = (JAXBElement<?>) unmarshaller.unmarshal(getClass().getResource(CONFIGURATION_FILE));
+         externalAuthenticationConfig = (ExternalAuthenticationConfigType) o.getValue();
+      }
+      catch (JAXBException e)
+      {
+         throw new RuntimeException(e);
+      }
+      return externalAuthenticationConfig;
+   }
+
+   public void setContextRoot(String contextRoot)
+   {
+      this.contextRoot = contextRoot;
+   }
+
+   public String getContextRoot()
+   {
+      return contextRoot;
+   }
+
+   // FIXME @Factory(scope = ScopeType.EVENT, autoCreate = true, value =
+   // "org.jboss.seam.security.external_authentication.serviceProvider")
+   public ServiceProvider getServiceProvider()
+   {
+      String hostname = null; // FIXME =
+      // ServletContexts.instance().getRequest().getServerName();
+      ;
+      return serviceProviderMap.get(hostname);
+   }
+
+   public ServiceProvider getServiceProvider(String hostname)
+   {
+      return serviceProviderMap.get(hostname);
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/Configuration.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/OpenIdConfiguration.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/OpenIdConfiguration.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/OpenIdConfiguration.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,50 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication.configuration;
+
+import java.util.List;
+
+import org.jboss.seam.security.external_authentication.jaxb.config.OpenIdAttributeType;
+import org.jboss.seam.security.external_authentication.jaxb.config.OpenIdConfigType;
+
+public class OpenIdConfiguration
+{
+   private List<OpenIdAttributeType> attributes;
+
+   private String defaultOpenIdProvider;
+
+   public OpenIdConfiguration(OpenIdConfigType openIdConfig)
+   {
+      attributes = openIdConfig.getAttribute();
+      defaultOpenIdProvider = openIdConfig.getDefaultOpenIdProvider();
+   }
+
+   public List<OpenIdAttributeType> getAttributes()
+   {
+      return attributes;
+   }
+
+   public String getDefaultOpenIdProvider()
+   {
+      return defaultOpenIdProvider;
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/OpenIdConfiguration.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlConfiguration.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlConfiguration.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlConfiguration.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,271 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication.configuration;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.jboss.seam.security.external_authentication.jaxb.config.SamlConfigType;
+import org.jboss.seam.security.external_authentication.jaxb.config.SamlIdentityProviderType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata.EntitiesDescriptorType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata.EntityDescriptorType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata.IDPSSODescriptorType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata.RoleDescriptorType;
+
+public class SamlConfiguration
+{
+   private static final String SAML_ENTITIES_FILE = "/saml-entities.xml";
+
+   private Map<String, IDPSSODescriptorType> idpMetaInfo = new HashMap<String, IDPSSODescriptorType>();
+
+   private String entityId;
+
+   private SamlIdentityProvider defaultIdentityProvider;
+
+   private List<SamlIdentityProvider> identityProviders = new LinkedList<SamlIdentityProvider>();
+
+   private boolean authnRequestsSigned = false;
+
+   private boolean wantAssertionsSigned = false;
+
+   private PrivateKey privateKey;
+
+   private X509Certificate certificate;
+
+   public SamlConfiguration(SamlConfigType samlConfig)
+   {
+      readSamlMetaInformation();
+
+      this.entityId = samlConfig.getServiceProviderEntityId();
+      this.authnRequestsSigned = samlConfig.isAuthnRequestsSigned();
+      this.wantAssertionsSigned = samlConfig.isWantAssertionsSigned();
+
+      for (SamlIdentityProviderType samlIdp : samlConfig.getSamlIdentityProvider())
+      {
+         IDPSSODescriptorType idpSsoDescriptor = idpMetaInfo.get(samlIdp.getEntityId());
+         if (idpSsoDescriptor == null)
+         {
+            throw new RuntimeException("Saml identity provider with entity id \"" + samlIdp.getEntityId() + "\" not found in metadata.");
+         }
+         SamlIdentityProvider samlIdentityProvider = new SamlIdentityProvider(samlIdp.getEntityId(), idpSsoDescriptor);
+         identityProviders.add(samlIdentityProvider);
+
+         samlIdentityProvider.setWantSingleLogoutMessagesSigned(samlIdp.isWantSingleLogoutMessagesSigned());
+         samlIdentityProvider.setSingleLogoutMessagesSigned(samlIdp.isSingleLogoutMessagesSigned());
+      }
+
+      boolean wantAuthnRequestsSigned = false;
+
+      for (SamlIdentityProvider identityProvider : identityProviders)
+      {
+         if (identityProvider instanceof SamlIdentityProvider)
+         {
+            if (((SamlIdentityProvider) identityProvider).isWantAuthnRequestsSigned())
+            {
+               wantAuthnRequestsSigned = true;
+            }
+         }
+         if (identityProvider.getEntityId().equals(samlConfig.getDefaultIdentityProvider()))
+         {
+            defaultIdentityProvider = identityProvider;
+         }
+      }
+
+      if (wantAuthnRequestsSigned && !samlConfig.isAuthnRequestsSigned())
+      {
+         throw new RuntimeException("Configuration error: at least one identity provider wants the authentication requests signed, but the service provider doesn't sign authentication requests.");
+      }
+
+      String keyStoreUrl = samlConfig.getKeyStoreUrl();
+      String keyStorePass = samlConfig.getKeyStorePass();
+      String signingKeyAlias = samlConfig.getSigningKeyAlias();
+      String signingKeyPass = samlConfig.getSigningKeyPass();
+      if (signingKeyPass == null)
+      {
+         signingKeyPass = keyStorePass;
+      }
+
+      getSigningKeyPair(keyStoreUrl, keyStorePass, signingKeyAlias, signingKeyPass);
+   }
+
+   private void readSamlMetaInformation()
+   {
+      try
+      {
+         JAXBContext jaxbContext = JAXBContext.newInstance("org.picketlink.identity.federation.saml.v2.metadata");
+         Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+         JAXBElement<?> o = (JAXBElement<?>) unmarshaller.unmarshal(getClass().getResource(SAML_ENTITIES_FILE));
+         EntitiesDescriptorType entitiesDescriptor = (EntitiesDescriptorType) o.getValue();
+         readEntitiesDescriptor(entitiesDescriptor);
+      }
+      catch (JAXBException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   private void readEntitiesDescriptor(EntitiesDescriptorType entitiesDescriptor)
+   {
+      for (Object object : entitiesDescriptor.getEntityDescriptorOrEntitiesDescriptor())
+      {
+         if (object instanceof EntityDescriptorType)
+         {
+            EntityDescriptorType entityDescriptor = (EntityDescriptorType) object;
+            String entityId = entityDescriptor.getEntityID();
+
+            for (RoleDescriptorType roleDescriptor : entityDescriptor.getRoleDescriptorOrIDPSSODescriptorOrSPSSODescriptor())
+            {
+               if (roleDescriptor instanceof IDPSSODescriptorType)
+               {
+                  IDPSSODescriptorType IDPSSODescriptor = (IDPSSODescriptorType) roleDescriptor;
+                  idpMetaInfo.put(entityId, IDPSSODescriptor);
+               }
+            }
+         }
+         else
+         {
+            EntitiesDescriptorType descriptor = (EntitiesDescriptorType) object;
+            readEntitiesDescriptor(descriptor);
+         }
+      }
+   }
+
+   private void getSigningKeyPair(String keyStoreUrl, String keyStorePass, String signingKeyAlias, String signingKeyPass)
+   {
+      final String classPathPrefix = "classpath:";
+
+      try
+      {
+         KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+         InputStream keyStoreStream;
+         if (keyStoreUrl.startsWith(classPathPrefix))
+         {
+            keyStoreStream = getClass().getClassLoader().getResourceAsStream(keyStoreUrl.substring(classPathPrefix.length()));
+         }
+         else
+         {
+            keyStoreStream = new URL(keyStoreUrl).openStream();
+         }
+         char[] keyStorePwd = keyStorePass != null ? keyStorePass.toCharArray() : null;
+         keyStore.load(keyStoreStream, keyStorePwd);
+
+         certificate = (X509Certificate) keyStore.getCertificate(signingKeyAlias);
+
+         char[] signingKeyPwd = signingKeyPass != null ? signingKeyPass.toCharArray() : null;
+
+         privateKey = (PrivateKey) keyStore.getKey(signingKeyAlias, signingKeyPwd);
+      }
+      catch (KeyStoreException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (NoSuchAlgorithmException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (CertificateException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (MalformedURLException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (UnrecoverableKeyException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   public String getEntityId()
+   {
+      return entityId;
+   }
+
+   public SamlIdentityProvider getDefaultIdentityProvider()
+   {
+      return defaultIdentityProvider;
+   }
+
+   public List<SamlIdentityProvider> getIdentityProviders()
+   {
+      return identityProviders;
+   }
+
+   public boolean isAuthnRequestsSigned()
+   {
+      return authnRequestsSigned;
+   }
+
+   public boolean isWantAssertionsSigned()
+   {
+      return wantAssertionsSigned;
+   }
+
+   public PrivateKey getPrivateKey()
+   {
+      return privateKey;
+   }
+
+   public X509Certificate getCertificate()
+   {
+      return certificate;
+   }
+
+   public SamlIdentityProvider getSamlIdentityProviderByEntityId(String entityId)
+   {
+      for (SamlIdentityProvider identityProvider : identityProviders)
+      {
+         if (identityProvider instanceof SamlIdentityProvider)
+         {
+            SamlIdentityProvider samlIdentityProvider = (SamlIdentityProvider) identityProvider;
+            if (samlIdentityProvider.getEntityId().equals(entityId))
+            {
+               return samlIdentityProvider;
+            }
+         }
+      }
+      return null;
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlConfiguration.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlEndpoint.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlEndpoint.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlEndpoint.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,62 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication.configuration;
+
+public class SamlEndpoint
+{
+   private Binding binding;
+
+   private String location;
+
+   private String responseLocation;
+
+   private SamlService service;
+
+   public SamlEndpoint(SamlService service, Binding binding, String location, String responseLocation)
+   {
+      super();
+      this.service = service;
+      this.binding = binding;
+      this.location = location;
+      this.responseLocation = responseLocation;
+   }
+
+   public SamlService getService()
+   {
+      return service;
+   }
+
+   public Binding getBinding()
+   {
+      return binding;
+   }
+
+   public String getLocation()
+   {
+      return location;
+   }
+
+   public String getResponseLocation()
+   {
+      return responseLocation != null ? responseLocation : location;
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlEndpoint.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlIdentityProvider.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlIdentityProvider.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlIdentityProvider.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,149 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication.configuration;
+
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.security.cert.X509Certificate;
+import javax.xml.bind.JAXBElement;
+
+import org.jboss.seam.security.external_authentication.SamlProfile;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata.IDPSSODescriptorType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata.KeyDescriptorType;
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata.KeyTypes;
+import org.jboss.seam.security.external_authentication.jaxb.xmldsig.X509DataType;
+
+public class SamlIdentityProvider
+{
+   private String entityId;
+
+   private Map<SamlProfile, SamlService> services = new HashMap<SamlProfile, SamlService>();
+
+   private PublicKey publicKey;
+
+   private boolean wantAuthnRequestsSigned;
+
+   private boolean wantSingleLogoutMessagesSigned;
+
+   private boolean singleLogoutMessagesSigned;
+
+   public SamlIdentityProvider(String entityId, IDPSSODescriptorType IDPSSODescriptor)
+   {
+      this.entityId = entityId;
+
+      wantAuthnRequestsSigned = IDPSSODescriptor.isWantAuthnRequestsSigned();
+
+      services.put(SamlProfile.SINGLE_SIGN_ON, new SamlService(SamlProfile.SINGLE_SIGN_ON, IDPSSODescriptor.getSingleSignOnService()));
+      services.put(SamlProfile.SINGLE_LOGOUT, new SamlService(SamlProfile.SINGLE_LOGOUT, IDPSSODescriptor.getSingleLogoutService()));
+
+      for (KeyDescriptorType keyDescriptor : IDPSSODescriptor.getKeyDescriptor())
+      {
+         if (keyDescriptor.getUse().equals(KeyTypes.SIGNING))
+         {
+            for (Object content : keyDescriptor.getKeyInfo().getContent())
+            {
+               if (content instanceof JAXBElement<?> && ((JAXBElement<?>) content).getValue() instanceof X509DataType)
+               {
+                  X509DataType X509Data = (X509DataType) ((JAXBElement<?>) content).getValue();
+                  for (Object object : X509Data.getX509IssuerSerialOrX509SKIOrX509SubjectName())
+                  {
+                     if (object instanceof JAXBElement<?>)
+                     {
+                        JAXBElement<?> el = (JAXBElement<?>) object;
+                        if (el.getName().getLocalPart().equals("X509Certificate"))
+                        {
+                           byte[] certificate = (byte[]) el.getValue();
+                           try
+                           {
+                              X509Certificate cert = X509Certificate.getInstance(certificate);
+                              publicKey = cert.getPublicKey();
+                           }
+                           catch (javax.security.cert.CertificateException e)
+                           {
+                              throw new RuntimeException(e);
+                           }
+                        }
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+
+   public String getEntityId()
+   {
+      return entityId;
+   }
+
+   public void setEntityId(String entityId)
+   {
+      this.entityId = entityId;
+   }
+
+   public SamlService getService(SamlProfile service)
+   {
+      return services.get(service);
+   }
+
+   public PublicKey getPublicKey()
+   {
+      return publicKey;
+   }
+
+   public void setPublicKey(PublicKey publicKey)
+   {
+      this.publicKey = publicKey;
+   }
+
+   public boolean isWantAuthnRequestsSigned()
+   {
+      return wantAuthnRequestsSigned;
+   }
+
+   public void setWantAuthnRequestsSigned(boolean wantAuthnRequestsSigned)
+   {
+      this.wantAuthnRequestsSigned = wantAuthnRequestsSigned;
+   }
+
+   public boolean isWantSingleLogoutMessagesSigned()
+   {
+      return wantSingleLogoutMessagesSigned;
+   }
+
+   public void setWantSingleLogoutMessagesSigned(boolean wantSingleLogoutMessagesSigned)
+   {
+      this.wantSingleLogoutMessagesSigned = wantSingleLogoutMessagesSigned;
+   }
+
+   public boolean isSingleLogoutMessagesSigned()
+   {
+      return singleLogoutMessagesSigned;
+   }
+
+   public void setSingleLogoutMessagesSigned(boolean singleLogoutMessagesSigned)
+   {
+      this.singleLogoutMessagesSigned = singleLogoutMessagesSigned;
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlIdentityProvider.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlService.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlService.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlService.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,85 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication.configuration;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata.EndpointType;
+import org.jboss.seam.security.external_authentication.SamlProfile;
+
+public class SamlService
+{
+   private SamlProfile profile;
+
+   private List<SamlEndpoint> serviceEndpoints = new LinkedList<SamlEndpoint>();
+
+   public SamlService(SamlProfile profile, List<EndpointType> endpoints)
+   {
+      this.profile = profile;
+
+      for (EndpointType endpoint : endpoints)
+      {
+         Binding binding = null;
+         if (endpoint.getBinding().endsWith("HTTP-Redirect"))
+         {
+            binding = Binding.HTTP_Redirect;
+         }
+         else if (endpoint.getBinding().endsWith("HTTP-POST"))
+         {
+            binding = Binding.HTTP_Post;
+         }
+         else
+         {
+            // ignore other bindings
+         }
+         if (binding != null)
+         {
+            SamlEndpoint samlEndpoint = new SamlEndpoint(this, binding, endpoint.getLocation(), endpoint.getResponseLocation());
+            serviceEndpoints.add(samlEndpoint);
+         }
+      }
+   }
+
+   public SamlProfile getProfile()
+   {
+      return profile;
+   }
+
+   public List<SamlEndpoint> getServiceEndpoints()
+   {
+      return serviceEndpoints;
+   }
+
+   public SamlEndpoint getEndpointForBinding(Binding binding)
+   {
+      for (SamlEndpoint endpoint : serviceEndpoints)
+      {
+         if (endpoint.getBinding() == binding)
+         {
+            return endpoint;
+         }
+      }
+
+      return null;
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/SamlService.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/ServiceProvider.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/ServiceProvider.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/ServiceProvider.java	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,171 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.security.external_authentication.configuration;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.el.MethodExpression;
+
+import org.jboss.seam.security.external_authentication.ExternalAuthenticationService;
+import org.jboss.seam.security.external_authentication.jaxb.config.ServiceProviderType;
+
+public class ServiceProvider
+{
+   private Configuration configuration;
+
+   private SamlConfiguration samlConfiguration;
+
+   private OpenIdConfiguration openIdConfiguration;
+
+   private String hostname;
+
+   private String protocol;
+
+   private int port;
+
+   private String loggedOutUrl;
+
+   private String unsolicitedAuthenticationUrl;
+
+   private String failedAuthenticationUrl;
+
+   private MethodExpression internalAuthenticationMethod;
+
+   public ServiceProvider(Configuration configuration, ServiceProviderType serviceProvider)
+   {
+      this.configuration = configuration;
+
+      hostname = serviceProvider.getHostname();
+      protocol = serviceProvider.getProtocol().value();
+
+      loggedOutUrl = serviceProvider.getLoggedOutUrl();
+      unsolicitedAuthenticationUrl = serviceProvider.getUnsolicitedAuthenticationUrl();
+      failedAuthenticationUrl = serviceProvider.getFailedAuthenticationUrl();
+
+      internalAuthenticationMethod = null; // FIXME =
+      // Expressions.instance().createMethodExpression(serviceProvider.getInternalAuthenticationMethod(),
+      // Boolean.class, Principal.class,
+      // List.class);
+
+      if (serviceProvider.getPort() == null)
+      {
+         if (protocol.equals("http"))
+         {
+            port = 8080;
+         }
+         else
+         {
+            port = 8443;
+         }
+      }
+      else
+      {
+         port = serviceProvider.getPort().intValue();
+      }
+
+      if (serviceProvider.getSamlConfig() != null)
+      {
+         samlConfiguration = new SamlConfiguration(serviceProvider.getSamlConfig());
+      }
+
+      if (serviceProvider.getOpenIdConfig() != null)
+      {
+         openIdConfiguration = new OpenIdConfiguration(serviceProvider.getOpenIdConfig());
+      }
+   }
+
+   public String getServiceURL(ExternalAuthenticationService service)
+   {
+      String path = configuration.getContextRoot() + "/" + service.getName() + ".seam";
+      return createURL(path);
+   }
+
+   public String getOpenIdRealm()
+   {
+      return createURL("");
+   }
+
+   private String createURL(String path)
+   {
+      try
+      {
+         if (protocol.equals("http") && port == 80 || protocol.equals("https") && port == 443)
+         {
+            return new URL(protocol, hostname, path).toExternalForm();
+         }
+         else
+         {
+            return new URL(protocol, hostname, port, path).toExternalForm();
+         }
+      }
+      catch (MalformedURLException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   public SamlConfiguration getSamlConfiguration()
+   {
+      return samlConfiguration;
+   }
+
+   public OpenIdConfiguration getOpenIdConfiguration()
+   {
+      return openIdConfiguration;
+   }
+
+   public String getHostname()
+   {
+      return hostname;
+   }
+
+   public String getProtocol()
+   {
+      return protocol;
+   }
+
+   public int getPort()
+   {
+      return port;
+   }
+
+   public String getLoggedOutUrl()
+   {
+      return loggedOutUrl;
+   }
+
+   public String getUnsolicitedAuthenticationUrl()
+   {
+      return unsolicitedAuthenticationUrl;
+   }
+
+   public String getFailedAuthenticationUrl()
+   {
+      return failedAuthenticationUrl;
+   }
+
+   public MethodExpression getInternalAuthenticationMethod()
+   {
+      return internalAuthenticationMethod;
+   }
+}


Property changes on: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/external_authentication/configuration/ServiceProvider.java
___________________________________________________________________
Name: svn
   + eol-style=native
Name: svn:keywords
   + Revision Author Date

Added: modules/security/trunk/impl/src/main/resources/schema/config/external-authentication-config.xsd
===================================================================
--- modules/security/trunk/impl/src/main/resources/schema/config/external-authentication-config.xsd	                        (rev 0)
+++ modules/security/trunk/impl/src/main/resources/schema/config/external-authentication-config.xsd	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:seam:security:external_authentication:config"
+  xmlns:tns="urn:seam:security:external_authentication:config" elementFormDefault="qualified">
+  <complexType name="ExternalAuthenticationConfigType">
+    <annotation>
+      <documentation>
+        Configuration for the external authentication of users
+        (using for example SAMLv2 or OpenID).
+			</documentation>
+    </annotation>
+    <sequence minOccurs="0" maxOccurs="unbounded">
+      <element name="ServiceProvider" type="tns:ServiceProviderType" />
+    </sequence>
+  </complexType>
+  <complexType name="ServiceProviderType">
+    <annotation>
+      <documentation>
+        Configuration for one service provider (relying
+        party).
+			</documentation>
+    </annotation>
+    <sequence>
+      <element name="SamlConfig" type="tns:SamlConfigType" minOccurs="0" />
+      <element name="OpenIdConfig" type="tns:OpenIdConfigType" minOccurs="0" />
+    </sequence>
+    <attribute name="protocol" type="tns:ProtocolTypes" use="optional" default="https">
+      <annotation>
+        <documentation>Protocol that is used for the service provider (http
+          or https). Default: https.
+				</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="hostname" type="string" use="required">
+      <annotation>
+        <documentation>Name of the system that hosts the application.
+				</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="port" type="integer" use="optional">
+      <annotation>
+        <documentation>Port that is used for the service provider. Default:
+          8080 if the protocol is http, 8443 if the protocol is https.
+				</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="unsolicitedAuthenticationUrl" type="string" use="required">
+      <annotation>
+        <documentation>URL to which the browser should be redirected by
+          default after succesful unsolicited authentication (IDP initiated
+          login).</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="loggedOutUrl" type="string" use="required">
+      <annotation>
+        <documentation>URL where the browser is redirected to after a
+          succesful logout.
+				</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="failedAuthenticationUrl" type="string" use="required">
+      <annotation>
+        <documentation>URL where the browser is redirected to after
+          failed
+          authentication.
+				</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="internalAuthenticationMethod" type="string" use="required">
+      <annotation>
+        <documentation>After succesful external authentication, this method
+          is called, to determine whether the authenticated principal is
+          allowed to login. The principal is passed to this method.
+				</documentation>
+      </annotation>
+    </attribute>
+  </complexType>
+  <complexType name="SamlConfigType">
+    <annotation>
+      <documentation>
+        Configuration for SAMLv2.
+			</documentation>
+    </annotation>
+    <sequence minOccurs="0" maxOccurs="unbounded">
+      <element name="SamlIdentityProvider" type="tns:SamlIdentityProviderType" />
+    </sequence>
+    <attribute name="authnRequestsSigned" type="boolean" use="optional" default="false">
+      <annotation>
+        <documentation>Indicates whether the service provider signs outgoing
+          authentication requests.</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="wantAssertionsSigned" type="boolean" use="optional" default="true">
+      <annotation>
+        <documentation>Specifies whether assertions received from the IDP
+          are required to have a valid signature.</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="serviceProviderEntityId" type="string" use="required">
+      <annotation>
+        <documentation>SAML entity id for this service provider.
+				</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="defaultIdentityProvider" type="string" use="optional">
+      <annotation>
+        <documentation>Name of the default identity provider.
+				</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="keyStoreUrl" type="string" use="required">
+      <annotation>
+        <documentation>URL of the keystore.</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="keyStorePass" type="string" use="required">
+      <annotation>
+        <documentation>Password of the keystore.</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="signingKeyAlias" type="string" use="required">
+      <annotation>
+        <documentation>Alias of the key that is used for signing outgoing
+          messages.</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="signingKeyPass" type="string" use="optional">
+      <annotation>
+        <documentation>Password of the key that is used for signing outgoing
+          messages. Defaults to the keyStorePass.s</documentation>
+      </annotation>
+    </attribute>
+  </complexType>
+  <complexType name="OpenIdConfigType">
+    <annotation>
+      <documentation>
+        Configuration for OpenID.
+			</documentation>
+    </annotation>
+    <sequence minOccurs="0" maxOccurs="unbounded">
+      <element name="Attribute" type="tns:OpenIdAttributeType" />
+    </sequence>
+    <attribute name="defaultOpenIdProvider" type="string" use="optional">
+      <annotation>
+        <documentation>URL of the default OpenID provider.
+				</documentation>
+      </annotation>
+    </attribute>
+  </complexType>
+  <complexType name="OpenIdAttributeType">
+    <annotation>
+      <documentation>
+        OpenId attribute.
+			</documentation>
+    </annotation>
+    <attribute name="Alias" type="string" use="required">
+      <annotation>
+        <documentation>Alias.</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="TypeUri" type="string" use="required">
+      <annotation>
+        <documentation>The URI identifying the attribute type.
+				</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="Required" type="boolean" use="required">
+      <annotation>
+        <documentation>Indicates whether the attribute is required.
+				</documentation>
+      </annotation>
+    </attribute>
+  </complexType>
+  <simpleType name="ProtocolTypes">
+    <restriction base="string">
+      <enumeration value="http" />
+      <enumeration value="https" />
+    </restriction>
+  </simpleType>
+  <complexType name="SamlIdentityProviderType">
+    <attribute name="entityId" type="string" use="required">
+      <annotation>
+        <documentation>entity id of the SAML identity provider
+				</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="singleLogoutMessagesSigned" type="boolean" use="optional" default="false">
+      <annotation>
+        <documentation>Indicates whether outgoing logout requests and
+          responses are signed by the identity provider.
+						</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="wantSingleLogoutMessagesSigned" type="boolean" use="optional" default="false">
+      <annotation>
+        <documentation>Indicates whether the identity provider wants
+          incoming single logout requests and responses to be signed.
+				</documentation>
+      </annotation>
+    </attribute>
+  </complexType>
+  <element name="ExternalAuthenticationConfig" type="tns:ExternalAuthenticationConfigType" />
+</schema>
\ No newline at end of file

Added: modules/security/trunk/impl/src/main/resources/schema/samlv2/saml-schema-assertion-2.0.xsd
===================================================================
--- modules/security/trunk/impl/src/main/resources/schema/samlv2/saml-schema-assertion-2.0.xsd	                        (rev 0)
+++ modules/security/trunk/impl/src/main/resources/schema/samlv2/saml-schema-assertion-2.0.xsd	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="US-ASCII"?>
+<schema
+    targetNamespace="urn:oasis:names:tc:SAML:2.0:assertion"
+    xmlns="http://www.w3.org/2001/XMLSchema"
+    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+    xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+    xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
+    elementFormDefault="unqualified"
+    attributeFormDefault="unqualified"
+    blockDefault="substitution"
+    version="2.0">
+    <import namespace="http://www.w3.org/2000/09/xmldsig#"
+        schemaLocation="xmldsig-core-schema.xsd"/>
+    <import namespace="http://www.w3.org/2001/04/xmlenc#"
+        schemaLocation="xenc-schema.xsd"/>
+    <annotation>
+        <documentation>
+            Document identifier: saml-schema-assertion-2.0
+            Location: http://docs.oasis-open.org/security/saml/v2.0/
+            Revision history:
+            V1.0 (November, 2002):
+              Initial Standard Schema.
+            V1.1 (September, 2003):
+              Updates within the same V1.0 namespace.
+            V2.0 (March, 2005):
+              New assertion schema for SAML V2.0 namespace.
+        </documentation>
+    </annotation>
+    <attributeGroup name="IDNameQualifiers">
+        <attribute name="NameQualifier" type="string" use="optional"/>
+        <attribute name="SPNameQualifier" type="string" use="optional"/>
+    </attributeGroup>
+    <element name="BaseID" type="saml:BaseIDAbstractType"/>
+    <complexType name="BaseIDAbstractType" abstract="true">
+        <attributeGroup ref="saml:IDNameQualifiers"/>
+    </complexType>
+    <element name="NameID" type="saml:NameIDType"/>
+    <complexType name="NameIDType">
+        <simpleContent>
+            <extension base="string">
+                <attributeGroup ref="saml:IDNameQualifiers"/>
+                <attribute name="Format" type="anyURI" use="optional"/>
+                <attribute name="SPProvidedID" type="string" use="optional"/>
+            </extension>
+        </simpleContent>
+    </complexType>
+    <complexType name="EncryptedElementType">
+        <sequence>
+            <element ref="xenc:EncryptedData"/>
+            <element ref="xenc:EncryptedKey" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+    </complexType>
+    <element name="EncryptedID" type="saml:EncryptedElementType"/>
+    <element name="Issuer" type="saml:NameIDType"/>
+    <element name="AssertionIDRef" type="NCName"/>
+    <element name="AssertionURIRef" type="anyURI"/>
+    <element name="Assertion" type="saml:AssertionType"/>
+    <complexType name="AssertionType">
+        <sequence>
+            <element ref="saml:Issuer"/>
+            <element ref="ds:Signature" minOccurs="0"/>
+            <element ref="saml:Subject" minOccurs="0"/>
+            <element ref="saml:Conditions" minOccurs="0"/>
+            <element ref="saml:Advice" minOccurs="0"/>
+            <choice minOccurs="0" maxOccurs="unbounded">
+                <element ref="saml:Statement"/>
+                <element ref="saml:AuthnStatement"/>
+                <element ref="saml:AuthzDecisionStatement"/>
+                <element ref="saml:AttributeStatement"/>
+            </choice>
+        </sequence>
+        <attribute name="Version" type="string" use="required"/>
+        <attribute name="ID" type="ID" use="required"/>
+        <attribute name="IssueInstant" type="dateTime" use="required"/>
+    </complexType>
+    <element name="Subject" type="saml:SubjectType"/>
+    <complexType name="SubjectType">
+        <choice>
+            <sequence>
+                <choice>
+                    <element ref="saml:BaseID"/>
+                    <element ref="saml:NameID"/>
+                    <element ref="saml:EncryptedID"/>
+                </choice>
+                <element ref="saml:SubjectConfirmation" minOccurs="0" maxOccurs="unbounded"/>
+            </sequence>
+            <element ref="saml:SubjectConfirmation" maxOccurs="unbounded"/>
+        </choice>
+    </complexType>
+    <element name="SubjectConfirmation" type="saml:SubjectConfirmationType"/>
+    <complexType name="SubjectConfirmationType">
+        <sequence>
+            <choice minOccurs="0">
+                <element ref="saml:BaseID"/>
+                <element ref="saml:NameID"/>
+                <element ref="saml:EncryptedID"/>
+            </choice>
+            <element ref="saml:SubjectConfirmationData" minOccurs="0"/>
+        </sequence>
+        <attribute name="Method" type="anyURI" use="required"/>
+    </complexType>
+    <element name="SubjectConfirmationData" type="saml:SubjectConfirmationDataType"/>
+    <complexType name="SubjectConfirmationDataType" mixed="true">
+        <complexContent>
+            <restriction base="anyType">
+                <sequence>
+                    <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+                <attribute name="NotBefore" type="dateTime" use="optional"/>
+                <attribute name="NotOnOrAfter" type="dateTime" use="optional"/>
+                <attribute name="Recipient" type="anyURI" use="optional"/>
+                <attribute name="InResponseTo" type="NCName" use="optional"/>
+                <attribute name="Address" type="string" use="optional"/>
+                <anyAttribute namespace="##other" processContents="lax"/>
+            </restriction>
+        </complexContent>
+    </complexType>
+    <complexType name="KeyInfoConfirmationDataType" mixed="false">
+        <complexContent>
+            <restriction base="saml:SubjectConfirmationDataType">
+                <sequence>
+                    <element ref="ds:KeyInfo" maxOccurs="unbounded"/>
+                </sequence>
+            </restriction>
+        </complexContent>
+    </complexType>
+    <element name="Conditions" type="saml:ConditionsType"/>
+    <complexType name="ConditionsType">
+        <choice minOccurs="0" maxOccurs="unbounded">
+            <element ref="saml:Condition"/>
+            <element ref="saml:AudienceRestriction"/>
+            <element ref="saml:OneTimeUse"/>
+            <element ref="saml:ProxyRestriction"/>
+        </choice>
+        <attribute name="NotBefore" type="dateTime" use="optional"/>
+        <attribute name="NotOnOrAfter" type="dateTime" use="optional"/>
+    </complexType>
+    <element name="Condition" type="saml:ConditionAbstractType"/>
+    <complexType name="ConditionAbstractType" abstract="true"/>
+    <element name="AudienceRestriction" type="saml:AudienceRestrictionType"/>
+    <complexType name="AudienceRestrictionType">
+        <complexContent>
+            <extension base="saml:ConditionAbstractType">
+                <sequence>
+                    <element ref="saml:Audience" maxOccurs="unbounded"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="Audience" type="anyURI"/>
+    <element name="OneTimeUse" type="saml:OneTimeUseType" />
+    <complexType name="OneTimeUseType">
+        <complexContent>
+            <extension base="saml:ConditionAbstractType"/>
+        </complexContent>
+    </complexType>
+    <element name="ProxyRestriction" type="saml:ProxyRestrictionType"/>
+    <complexType name="ProxyRestrictionType">
+    <complexContent>
+        <extension base="saml:ConditionAbstractType">
+            <sequence>
+                <element ref="saml:Audience" minOccurs="0" maxOccurs="unbounded"/>
+            </sequence>
+            <attribute name="Count" type="nonNegativeInteger" use="optional"/>
+        </extension>
+	</complexContent>
+    </complexType>
+    <element name="Advice" type="saml:AdviceType"/>
+    <complexType name="AdviceType">
+        <choice minOccurs="0" maxOccurs="unbounded">
+            <element ref="saml:AssertionIDRef"/>
+            <element ref="saml:AssertionURIRef"/>
+            <element ref="saml:Assertion"/>
+            <element ref="saml:EncryptedAssertion"/>
+            <any namespace="##other" processContents="lax"/>
+        </choice>
+    </complexType>
+    <element name="EncryptedAssertion" type="saml:EncryptedElementType"/>
+    <element name="Statement" type="saml:StatementAbstractType"/>
+    <complexType name="StatementAbstractType" abstract="true"/>
+    <element name="AuthnStatement" type="saml:AuthnStatementType"/>
+    <complexType name="AuthnStatementType">
+        <complexContent>
+            <extension base="saml:StatementAbstractType">
+                <sequence>
+                    <element ref="saml:SubjectLocality" minOccurs="0"/>
+                    <element ref="saml:AuthnContext"/>
+                </sequence>
+                <attribute name="AuthnInstant" type="dateTime" use="required"/>
+                <attribute name="SessionIndex" type="string" use="optional"/>
+                <attribute name="SessionNotOnOrAfter" type="dateTime" use="optional"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="SubjectLocality" type="saml:SubjectLocalityType"/>
+    <complexType name="SubjectLocalityType">
+        <attribute name="Address" type="string" use="optional"/>
+        <attribute name="DNSName" type="string" use="optional"/>
+    </complexType>
+    <element name="AuthnContext" type="saml:AuthnContextType"/>
+    <complexType name="AuthnContextType">
+        <sequence>
+            <choice>
+                <sequence>
+                    <element ref="saml:AuthnContextClassRef"/>
+                    <choice minOccurs="0">
+                        <element ref="saml:AuthnContextDecl"/>
+                        <element ref="saml:AuthnContextDeclRef"/>
+                    </choice>
+                </sequence>
+                <choice>
+                    <element ref="saml:AuthnContextDecl"/>
+                    <element ref="saml:AuthnContextDeclRef"/>
+                </choice>
+            </choice>
+            <element ref="saml:AuthenticatingAuthority" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+    </complexType>
+    <element name="AuthnContextClassRef" type="anyURI"/>
+    <element name="AuthnContextDeclRef" type="anyURI"/>
+    <element name="AuthnContextDecl" type="anyType"/>
+    <element name="AuthenticatingAuthority" type="anyURI"/>
+    <element name="AuthzDecisionStatement" type="saml:AuthzDecisionStatementType"/>
+    <complexType name="AuthzDecisionStatementType">
+        <complexContent>
+            <extension base="saml:StatementAbstractType">
+                <sequence>
+                    <element ref="saml:Action" maxOccurs="unbounded"/>
+                    <element ref="saml:Evidence" minOccurs="0"/>
+                </sequence>
+                <attribute name="Resource" type="anyURI" use="required"/>
+                <attribute name="Decision" type="saml:DecisionType" use="required"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <simpleType name="DecisionType">
+        <restriction base="string">
+            <enumeration value="Permit"/>
+            <enumeration value="Deny"/>
+            <enumeration value="Indeterminate"/>
+        </restriction>
+    </simpleType>
+    <element name="Action" type="saml:ActionType"/>
+    <complexType name="ActionType">
+        <simpleContent>
+            <extension base="string">
+                <attribute name="Namespace" type="anyURI" use="required"/>
+            </extension>
+        </simpleContent>
+    </complexType>
+    <element name="Evidence" type="saml:EvidenceType"/>
+    <complexType name="EvidenceType">
+        <choice maxOccurs="unbounded">
+            <element ref="saml:AssertionIDRef"/>
+            <element ref="saml:AssertionURIRef"/>
+            <element ref="saml:Assertion"/>
+            <element ref="saml:EncryptedAssertion"/>
+        </choice>
+    </complexType>
+    <element name="AttributeStatement" type="saml:AttributeStatementType"/>
+    <complexType name="AttributeStatementType">
+        <complexContent>
+            <extension base="saml:StatementAbstractType">
+                <choice maxOccurs="unbounded">
+                    <element ref="saml:Attribute"/>
+                    <element ref="saml:EncryptedAttribute"/>
+                </choice>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="Attribute" type="saml:AttributeType"/>
+    <complexType name="AttributeType">
+        <sequence>
+            <element ref="saml:AttributeValue" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+        <attribute name="Name" type="string" use="required"/>
+        <attribute name="NameFormat" type="anyURI" use="optional"/>
+        <attribute name="FriendlyName" type="string" use="optional"/>
+        <anyAttribute namespace="##other" processContents="lax"/>
+    </complexType>
+    <element name="AttributeValue" type="anyType" nillable="true"/>
+    <element name="EncryptedAttribute" type="saml:EncryptedElementType"/>
+</schema>

Added: modules/security/trunk/impl/src/main/resources/schema/samlv2/saml-schema-metadata-2.0.xsd
===================================================================
--- modules/security/trunk/impl/src/main/resources/schema/samlv2/saml-schema-metadata-2.0.xsd	                        (rev 0)
+++ modules/security/trunk/impl/src/main/resources/schema/samlv2/saml-schema-metadata-2.0.xsd	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,345 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="urn:oasis:names:tc:SAML:2.0:metadata"
+	xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+	xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+	xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified"
+	attributeFormDefault="unqualified" blockDefault="substitution" version="2.0">
+	<import namespace="http://www.w3.org/2000/09/xmldsig#"
+		schemaLocation="xmldsig-core-schema.xsd" />
+	<import namespace="http://www.w3.org/2001/04/xmlenc#"
+		schemaLocation="xenc-schema.xsd" />
+	<import namespace="urn:oasis:names:tc:SAML:2.0:assertion"
+		schemaLocation="saml-schema-assertion-2.0.xsd" />
+	<import namespace="http://www.w3.org/XML/1998/namespace"
+		schemaLocation="http://www.w3.org/2001/xml.xsd" />
+	<annotation>
+		<documentation>
+			Document identifier: saml-schema-metadata-2.0
+			Location: http://docs.oasis-open.org/security/saml/v2.0/
+			Revision history:
+			V2.0 (March, 2005):
+			Schema for SAML metadata, first published in SAML 2.0.
+        </documentation>
+	</annotation>
+
+	<simpleType name="entityIDType">
+		<restriction base="anyURI">
+			<maxLength value="1024" />
+		</restriction>
+	</simpleType>
+	<complexType name="localizedNameType">
+		<simpleContent>
+			<extension base="string">
+				<attribute ref="xml:lang" use="required" />
+			</extension>
+		</simpleContent>
+	</complexType>
+	<complexType name="localizedURIType">
+		<simpleContent>
+			<extension base="anyURI">
+				<attribute ref="xml:lang" use="required" />
+			</extension>
+		</simpleContent>
+	</complexType>
+
+	<element name="Extensions" type="md:ExtensionsType" />
+	<complexType final="#all" name="ExtensionsType">
+		<sequence>
+			<any namespace="##other" processContents="lax" maxOccurs="unbounded" />
+		</sequence>
+	</complexType>
+
+	<complexType name="EndpointType">
+		<sequence>
+			<any namespace="##other" processContents="lax" minOccurs="0"
+				maxOccurs="unbounded" />
+		</sequence>
+		<attribute name="Binding" type="anyURI" use="required" />
+		<attribute name="Location" type="anyURI" use="required" />
+		<attribute name="ResponseLocation" type="anyURI" use="optional" />
+		<anyAttribute namespace="##other" processContents="lax" />
+	</complexType>
+
+	<complexType name="IndexedEndpointType">
+		<complexContent>
+			<extension base="md:EndpointType">
+				<attribute name="index" type="unsignedShort" use="required" />
+				<attribute name="isDefault" type="boolean" use="optional" />
+			</extension>
+		</complexContent>
+	</complexType>
+
+	<element name="EntitiesDescriptor" type="md:EntitiesDescriptorType" />
+	<complexType name="EntitiesDescriptorType">
+		<sequence>
+			<element ref="ds:Signature" minOccurs="0" />
+			<element ref="md:Extensions" minOccurs="0" />
+			<choice minOccurs="1" maxOccurs="unbounded">
+				<element ref="md:EntityDescriptor" />
+				<element ref="md:EntitiesDescriptor" />
+			</choice>
+		</sequence>
+		<attribute name="validUntil" type="dateTime" use="optional" />
+		<attribute name="cacheDuration" type="duration" use="optional" />
+		<attribute name="ID" type="ID" use="optional" />
+		<attribute name="Name" type="string" use="optional" />
+	</complexType>
+
+	<element name="EntityDescriptor" type="md:EntityDescriptorType" />
+	<complexType name="EntityDescriptorType">
+		<sequence>
+			<element ref="ds:Signature" minOccurs="0" />
+			<element ref="md:Extensions" minOccurs="0" />
+			<choice>
+				<choice maxOccurs="unbounded">
+					<element ref="md:RoleDescriptor" />
+					<element ref="md:IDPSSODescriptor" />
+					<element ref="md:SPSSODescriptor" />
+					<element ref="md:AuthnAuthorityDescriptor" />
+					<element ref="md:AttributeAuthorityDescriptor" />
+					<element ref="md:PDPDescriptor" />
+				</choice>
+				<element ref="md:AffiliationDescriptor" />
+			</choice>
+			<element ref="md:Organization" minOccurs="0" />
+			<element ref="md:ContactPerson" minOccurs="0" maxOccurs="unbounded" />
+			<element ref="md:AdditionalMetadataLocation" minOccurs="0"
+				maxOccurs="unbounded" />
+		</sequence>
+		<attribute name="entityID" type="md:entityIDType" use="required" />
+		<attribute name="validUntil" type="dateTime" use="optional" />
+		<attribute name="cacheDuration" type="duration" use="optional" />
+		<attribute name="ID" type="ID" use="optional" />
+		<anyAttribute namespace="##other" processContents="lax" />
+	</complexType>
+
+	<element name="Organization" type="md:OrganizationType" />
+	<complexType name="OrganizationType">
+		<sequence>
+			<element ref="md:Extensions" minOccurs="0" />
+			<element ref="md:OrganizationName" maxOccurs="unbounded" />
+			<element ref="md:OrganizationDisplayName" maxOccurs="unbounded" />
+			<element ref="md:OrganizationURL" maxOccurs="unbounded" />
+		</sequence>
+		<anyAttribute namespace="##other" processContents="lax" />
+	</complexType>
+	<element name="OrganizationName" type="md:localizedNameType" />
+	<element name="OrganizationDisplayName" type="md:localizedNameType" />
+	<element name="OrganizationURL" type="md:localizedURIType" />
+	<element name="ContactPerson" type="md:ContactType" />
+	<complexType name="ContactType">
+		<sequence>
+			<element ref="md:Extensions" minOccurs="0" />
+			<element ref="md:Company" minOccurs="0" />
+			<element ref="md:GivenName" minOccurs="0" />
+			<element ref="md:SurName" minOccurs="0" />
+			<element ref="md:EmailAddress" minOccurs="0" maxOccurs="unbounded" />
+			<element ref="md:TelephoneNumber" minOccurs="0" maxOccurs="unbounded" />
+		</sequence>
+		<attribute name="contactType" type="md:ContactTypeType" use="required" />
+		<anyAttribute namespace="##other" processContents="lax" />
+	</complexType>
+	<element name="Company" type="string" />
+	<element name="GivenName" type="string" />
+	<element name="SurName" type="string" />
+	<element name="EmailAddress" type="anyURI" />
+	<element name="TelephoneNumber" type="string" />
+	<simpleType name="ContactTypeType">
+		<restriction base="string">
+			<enumeration value="technical" />
+			<enumeration value="support" />
+			<enumeration value="administrative" />
+			<enumeration value="billing" />
+			<enumeration value="other" />
+		</restriction>
+	</simpleType>
+
+	<element name="AdditionalMetadataLocation" type="md:AdditionalMetadataLocationType" />
+	<complexType name="AdditionalMetadataLocationType">
+		<simpleContent>
+			<extension base="anyURI">
+				<attribute name="namespace" type="anyURI" use="required" />
+			</extension>
+		</simpleContent>
+	</complexType>
+
+	<element name="RoleDescriptor" type="md:RoleDescriptorType" />
+	<complexType name="RoleDescriptorType" abstract="true">
+		<sequence>
+			<element ref="ds:Signature" minOccurs="0" />
+			<element ref="md:Extensions" minOccurs="0" />
+			<element ref="md:KeyDescriptor" minOccurs="0" maxOccurs="unbounded" />
+			<element ref="md:Organization" minOccurs="0" />
+			<element ref="md:ContactPerson" minOccurs="0" maxOccurs="unbounded" />
+		</sequence>
+		<attribute name="ID" type="ID" use="optional" />
+		<attribute name="validUntil" type="dateTime" use="optional" />
+		<attribute name="cacheDuration" type="duration" use="optional" />
+		<attribute name="protocolSupportEnumeration" type="md:anyURIListType"
+			use="required" />
+		<attribute name="errorURL" type="anyURI" use="optional" />
+		<anyAttribute namespace="##other" processContents="lax" />
+	</complexType>
+	<simpleType name="anyURIListType">
+		<list itemType="anyURI" />
+	</simpleType>
+
+	<element name="KeyDescriptor" type="md:KeyDescriptorType" />
+	<complexType name="KeyDescriptorType">
+		<sequence>
+			<element ref="ds:KeyInfo" />
+			<element ref="md:EncryptionMethod" minOccurs="0" maxOccurs="unbounded" />
+		</sequence>
+		<attribute name="use" type="md:KeyTypes" use="optional" />
+	</complexType>
+	<simpleType name="KeyTypes">
+		<restriction base="string">
+			<enumeration value="encryption" />
+			<enumeration value="signing" />
+		</restriction>
+	</simpleType>
+	<element name="EncryptionMethod" type="xenc:EncryptionMethodType" />
+
+	<complexType name="SSODescriptorType" abstract="true">
+		<complexContent>
+			<extension base="md:RoleDescriptorType">
+				<sequence>
+					<element ref="md:ArtifactResolutionService" minOccurs="0"
+						maxOccurs="unbounded" />
+					<element ref="md:SingleLogoutService" minOccurs="0"
+						maxOccurs="unbounded" />
+					<element ref="md:ManageNameIDService" minOccurs="0"
+						maxOccurs="unbounded" />
+					<element ref="md:NameIDFormat" minOccurs="0" maxOccurs="unbounded" />
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="ArtifactResolutionService" type="md:IndexedEndpointType" />
+	<element name="SingleLogoutService" type="md:EndpointType" />
+	<element name="ManageNameIDService" type="md:EndpointType" />
+	<element name="NameIDFormat" type="anyURI" />
+
+	<element name="IDPSSODescriptor" type="md:IDPSSODescriptorType" />
+	<complexType name="IDPSSODescriptorType">
+		<complexContent>
+			<extension base="md:SSODescriptorType">
+				<sequence>
+					<element ref="md:SingleSignOnService" maxOccurs="unbounded" />
+					<element ref="md:NameIDMappingService" minOccurs="0"
+						maxOccurs="unbounded" />
+					<element ref="md:AssertionIDRequestService" minOccurs="0"
+						maxOccurs="unbounded" />
+					<element ref="md:AttributeProfile" minOccurs="0" maxOccurs="unbounded" />
+					<element ref="saml:Attribute" minOccurs="0" maxOccurs="unbounded" />
+				</sequence>
+				<attribute name="WantAuthnRequestsSigned" type="boolean"
+					use="optional" />
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="SingleSignOnService" type="md:EndpointType" />
+	<element name="NameIDMappingService" type="md:EndpointType" />
+	<element name="AssertionIDRequestService" type="md:EndpointType" />
+	<element name="AttributeProfile" type="anyURI" />
+
+	<element name="SPSSODescriptor" type="md:SPSSODescriptorType" />
+	<complexType name="SPSSODescriptorType">
+		<complexContent>
+			<extension base="md:SSODescriptorType">
+				<sequence>
+					<element ref="md:AssertionConsumerService" maxOccurs="unbounded" />
+					<element ref="md:AttributeConsumingService" minOccurs="0"
+						maxOccurs="unbounded" />
+				</sequence>
+				<attribute name="AuthnRequestsSigned" type="boolean" use="optional" />
+				<attribute name="WantAssertionsSigned" type="boolean" use="optional" />
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="AssertionConsumerService" type="md:IndexedEndpointType" />
+	<element name="AttributeConsumingService" type="md:AttributeConsumingServiceType" />
+	<complexType name="AttributeConsumingServiceType">
+		<sequence>
+			<element ref="md:ServiceName" maxOccurs="unbounded" />
+			<element ref="md:ServiceDescription" minOccurs="0" maxOccurs="unbounded" />
+			<element ref="md:RequestedAttribute" maxOccurs="unbounded" />
+		</sequence>
+		<attribute name="index" type="unsignedShort" use="required" />
+		<attribute name="isDefault" type="boolean" use="optional" />
+	</complexType>
+	<element name="ServiceName" type="md:localizedNameType" />
+	<element name="ServiceDescription" type="md:localizedNameType" />
+	<element name="RequestedAttribute" type="md:RequestedAttributeType" />
+	<complexType name="RequestedAttributeType">
+		<complexContent>
+			<extension base="saml:AttributeType">
+				<attribute name="isRequired" type="boolean" use="optional" />
+			</extension>
+		</complexContent>
+	</complexType>
+
+	<element name="AuthnAuthorityDescriptor" type="md:AuthnAuthorityDescriptorType" />
+	<complexType name="AuthnAuthorityDescriptorType">
+		<complexContent>
+			<extension base="md:RoleDescriptorType">
+				<sequence>
+					<element ref="md:AuthnQueryService" maxOccurs="unbounded" />
+					<element ref="md:AssertionIDRequestService" minOccurs="0"
+						maxOccurs="unbounded" />
+					<element ref="md:NameIDFormat" minOccurs="0" maxOccurs="unbounded" />
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="AuthnQueryService" type="md:EndpointType" />
+
+	<element name="PDPDescriptor" type="md:PDPDescriptorType" />
+	<complexType name="PDPDescriptorType">
+		<complexContent>
+			<extension base="md:RoleDescriptorType">
+				<sequence>
+					<element ref="md:AuthzService" maxOccurs="unbounded" />
+					<element ref="md:AssertionIDRequestService" minOccurs="0"
+						maxOccurs="unbounded" />
+					<element ref="md:NameIDFormat" minOccurs="0" maxOccurs="unbounded" />
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="AuthzService" type="md:EndpointType" />
+
+	<element name="AttributeAuthorityDescriptor" type="md:AttributeAuthorityDescriptorType" />
+	<complexType name="AttributeAuthorityDescriptorType">
+		<complexContent>
+			<extension base="md:RoleDescriptorType">
+				<sequence>
+					<element ref="md:AttributeService" maxOccurs="unbounded" />
+					<element ref="md:AssertionIDRequestService" minOccurs="0"
+						maxOccurs="unbounded" />
+					<element ref="md:NameIDFormat" minOccurs="0" maxOccurs="unbounded" />
+					<element ref="md:AttributeProfile" minOccurs="0" maxOccurs="unbounded" />
+					<element ref="saml:Attribute" minOccurs="0" maxOccurs="unbounded" />
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="AttributeService" type="md:EndpointType" />
+
+	<element name="AffiliationDescriptor" type="md:AffiliationDescriptorType" />
+	<complexType name="AffiliationDescriptorType">
+		<sequence>
+			<element ref="ds:Signature" minOccurs="0" />
+			<element ref="md:Extensions" minOccurs="0" />
+			<element ref="md:AffiliateMember" maxOccurs="unbounded" />
+			<element ref="md:KeyDescriptor" minOccurs="0" maxOccurs="unbounded" />
+		</sequence>
+		<attribute name="affiliationOwnerID" type="md:entityIDType"
+			use="required" />
+		<attribute name="validUntil" type="dateTime" use="optional" />
+		<attribute name="cacheDuration" type="duration" use="optional" />
+		<attribute name="ID" type="ID" use="optional" />
+		<anyAttribute namespace="##other" processContents="lax" />
+	</complexType>
+	<element name="AffiliateMember" type="md:entityIDType" />
+</schema>

Added: modules/security/trunk/impl/src/main/resources/schema/samlv2/saml-schema-protocol-2.0.xsd
===================================================================
--- modules/security/trunk/impl/src/main/resources/schema/samlv2/saml-schema-protocol-2.0.xsd	                        (rev 0)
+++ modules/security/trunk/impl/src/main/resources/schema/samlv2/saml-schema-protocol-2.0.xsd	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,302 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema
+    targetNamespace="urn:oasis:names:tc:SAML:2.0:protocol"
+    xmlns="http://www.w3.org/2001/XMLSchema"
+    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
+    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+    xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+    elementFormDefault="unqualified"
+    attributeFormDefault="unqualified"
+    blockDefault="substitution"
+    version="2.0">
+    <import namespace="urn:oasis:names:tc:SAML:2.0:assertion"
+        schemaLocation="saml-schema-assertion-2.0.xsd"/>
+    <import namespace="http://www.w3.org/2000/09/xmldsig#"
+        schemaLocation="xmldsig-core-schema.xsd"/>
+    <annotation>
+        <documentation>
+            Document identifier: saml-schema-protocol-2.0
+            Location: http://docs.oasis-open.org/security/saml/v2.0/
+            Revision history:
+            V1.0 (November, 2002):
+              Initial Standard Schema.
+            V1.1 (September, 2003):
+              Updates within the same V1.0 namespace.
+            V2.0 (March, 2005):
+              New protocol schema based in a SAML V2.0 namespace.
+     </documentation>
+    </annotation>
+    <complexType name="RequestAbstractType" abstract="true">
+        <sequence>
+            <element ref="saml:Issuer" minOccurs="0"/>
+            <element ref="ds:Signature" minOccurs="0"/>
+            <element ref="samlp:Extensions" minOccurs="0"/>
+        </sequence>
+        <attribute name="ID" type="ID" use="required"/>
+        <attribute name="Version" type="string" use="required"/>
+        <attribute name="IssueInstant" type="dateTime" use="required"/>
+        <attribute name="Destination" type="anyURI" use="optional"/>
+    	<attribute name="Consent" type="anyURI" use="optional"/>
+    </complexType>
+    <element name="Extensions" type="samlp:ExtensionsType"/>
+    <complexType name="ExtensionsType">
+        <sequence>
+            <any namespace="##other" processContents="lax" maxOccurs="unbounded"/>
+        </sequence>
+    </complexType>
+    <complexType name="StatusResponseType">
+    	<sequence>
+            <element ref="saml:Issuer" minOccurs="0"/>
+            <element ref="ds:Signature" minOccurs="0"/>
+            <element ref="samlp:Extensions" minOccurs="0"/>
+            <element ref="samlp:Status"/>
+    	</sequence>
+    	<attribute name="ID" type="ID" use="required"/>
+    	<attribute name="InResponseTo" type="NCName" use="optional"/>
+    	<attribute name="Version" type="string" use="required"/>
+    	<attribute name="IssueInstant" type="dateTime" use="required"/>
+    	<attribute name="Destination" type="anyURI" use="optional"/>
+    	<attribute name="Consent" type="anyURI" use="optional"/>
+    </complexType>
+    <element name="Status" type="samlp:StatusType"/>
+    <complexType name="StatusType">
+        <sequence>
+            <element ref="samlp:StatusCode"/>
+            <element ref="samlp:StatusMessage" minOccurs="0"/>
+            <element ref="samlp:StatusDetail" minOccurs="0"/>
+        </sequence>
+    </complexType>
+    <element name="StatusCode" type="samlp:StatusCodeType"/>
+    <complexType name="StatusCodeType">
+        <sequence>
+            <element ref="samlp:StatusCode" minOccurs="0"/>
+        </sequence>
+        <attribute name="Value" type="anyURI" use="required"/>
+    </complexType>
+    <element name="StatusMessage" type="string"/>
+    <element name="StatusDetail" type="samlp:StatusDetailType"/>
+    <complexType name="StatusDetailType">
+        <sequence>
+            <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+    </complexType>
+    <element name="AssertionIDRequest" type="samlp:AssertionIDRequestType"/>
+    <complexType name="AssertionIDRequestType">
+    	<complexContent>
+            <extension base="samlp:RequestAbstractType">
+                <sequence>
+                    <element ref="saml:AssertionIDRef" maxOccurs="unbounded"/>
+                </sequence>
+            </extension>
+    	</complexContent>
+    </complexType>
+    <element name="SubjectQuery" type="samlp:SubjectQueryAbstractType"/>
+    <complexType name="SubjectQueryAbstractType" abstract="true">
+    	<complexContent>
+            <extension base="samlp:RequestAbstractType">
+                <sequence>
+                    <element ref="saml:Subject"/>
+                </sequence>
+            </extension>
+    	</complexContent>
+    </complexType>
+    <element name="AuthnQuery" type="samlp:AuthnQueryType"/>
+    <complexType name="AuthnQueryType">
+        <complexContent>
+            <extension base="samlp:SubjectQueryAbstractType">
+                <sequence>
+                    <element ref="samlp:RequestedAuthnContext" minOccurs="0"/>
+                </sequence>
+                <attribute name="SessionIndex" type="string" use="optional"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="RequestedAuthnContext" type="samlp:RequestedAuthnContextType"/>
+    <complexType name="RequestedAuthnContextType">
+        <choice>
+            <element ref="saml:AuthnContextClassRef" maxOccurs="unbounded"/>
+            <element ref="saml:AuthnContextDeclRef" maxOccurs="unbounded"/>
+        </choice>
+        <attribute name="Comparison" type="samlp:AuthnContextComparisonType" use="optional"/>
+    </complexType>
+    <simpleType name="AuthnContextComparisonType">
+        <restriction base="string">
+            <enumeration value="exact"/>
+            <enumeration value="minimum"/>
+            <enumeration value="maximum"/>
+            <enumeration value="better"/>
+        </restriction>
+    </simpleType>
+    <element name="AttributeQuery" type="samlp:AttributeQueryType"/>
+    <complexType name="AttributeQueryType">
+        <complexContent>
+            <extension base="samlp:SubjectQueryAbstractType">
+                <sequence>
+                    <element ref="saml:Attribute" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="AuthzDecisionQuery" type="samlp:AuthzDecisionQueryType"/>
+    <complexType name="AuthzDecisionQueryType">
+        <complexContent>
+            <extension base="samlp:SubjectQueryAbstractType">
+                <sequence>
+                    <element ref="saml:Action" maxOccurs="unbounded"/>
+                    <element ref="saml:Evidence" minOccurs="0"/>
+                </sequence>
+                <attribute name="Resource" type="anyURI" use="required"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="AuthnRequest" type="samlp:AuthnRequestType"/>
+    <complexType name="AuthnRequestType">
+        <complexContent>
+            <extension base="samlp:RequestAbstractType">
+                <sequence>
+                    <element ref="saml:Subject" minOccurs="0"/>
+                    <element ref="samlp:NameIDPolicy" minOccurs="0"/>
+                    <element ref="saml:Conditions" minOccurs="0"/>
+                    <element ref="samlp:RequestedAuthnContext" minOccurs="0"/>
+                    <element ref="samlp:Scoping" minOccurs="0"/>
+                </sequence>
+                <attribute name="ForceAuthn" type="boolean" use="optional"/>
+                <attribute name="IsPassive" type="boolean" use="optional"/>
+                <attribute name="ProtocolBinding" type="anyURI" use="optional"/>
+                <attribute name="AssertionConsumerServiceIndex" type="unsignedShort" use="optional"/>
+                <attribute name="AssertionConsumerServiceURL" type="anyURI" use="optional"/>
+                <attribute name="AttributeConsumingServiceIndex" type="unsignedShort" use="optional"/>
+                <attribute name="ProviderName" type="string" use="optional"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="NameIDPolicy" type="samlp:NameIDPolicyType"/>
+    <complexType name="NameIDPolicyType">
+        <attribute name="Format" type="anyURI" use="optional"/>
+        <attribute name="SPNameQualifier" type="string" use="optional"/>
+        <attribute name="AllowCreate" type="boolean" use="optional"/>
+    </complexType>
+    <element name="Scoping" type="samlp:ScopingType"/>
+    <complexType name="ScopingType">
+        <sequence>
+            <element ref="samlp:IDPList" minOccurs="0"/>
+            <element ref="samlp:RequesterID" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+        <attribute name="ProxyCount" type="nonNegativeInteger" use="optional"/>
+    </complexType>
+    <element name="RequesterID" type="anyURI"/>
+    <element name="IDPList" type="samlp:IDPListType"/>
+    <complexType name="IDPListType">
+        <sequence>
+            <element ref="samlp:IDPEntry" maxOccurs="unbounded"/>
+            <element ref="samlp:GetComplete" minOccurs="0"/>
+        </sequence>
+    </complexType>
+    <element name="IDPEntry" type="samlp:IDPEntryType"/>
+    <complexType name="IDPEntryType">
+        <attribute name="ProviderID" type="anyURI" use="required"/>
+        <attribute name="Name" type="string" use="optional"/>
+        <attribute name="Loc" type="anyURI" use="optional"/>
+    </complexType>
+    <element name="GetComplete" type="anyURI"/>
+    <element name="Response" type="samlp:ResponseType"/>
+    <complexType name="ResponseType">
+    	<complexContent>
+            <extension base="samlp:StatusResponseType">
+                <choice minOccurs="0" maxOccurs="unbounded">
+                    <element ref="saml:Assertion"/>
+                    <element ref="saml:EncryptedAssertion"/>
+                </choice>
+            </extension>
+    	</complexContent>
+    </complexType>
+    <element name="ArtifactResolve" type="samlp:ArtifactResolveType"/>
+    <complexType name="ArtifactResolveType">
+    	<complexContent>
+            <extension base="samlp:RequestAbstractType">
+                <sequence>
+                    <element ref="samlp:Artifact"/>
+                </sequence>
+            </extension>
+    	</complexContent>
+    </complexType>
+    <element name="Artifact" type="string"/>
+    <element name="ArtifactResponse" type="samlp:ArtifactResponseType"/>
+    <complexType name="ArtifactResponseType">
+    	<complexContent>
+            <extension base="samlp:StatusResponseType">
+                <sequence>
+                    <any namespace="##any" processContents="lax" minOccurs="0"/>
+                </sequence>
+            </extension>
+    	</complexContent>
+    </complexType>
+    <element name="ManageNameIDRequest" type="samlp:ManageNameIDRequestType"/>
+    <complexType name="ManageNameIDRequestType">
+    	<complexContent>
+            <extension base="samlp:RequestAbstractType">
+                <sequence>
+                    <choice>
+                        <element ref="saml:NameID"/>
+                        <element ref="saml:EncryptedID"/>
+                    </choice>
+                    <choice>
+                        <element ref="samlp:NewID"/>
+                        <element ref="samlp:NewEncryptedID"/>
+                        <element ref="samlp:Terminate"/>
+                    </choice>
+                </sequence>
+            </extension>
+    	</complexContent>
+    </complexType>
+    <element name="NewID" type="string"/>
+    <element name="NewEncryptedID" type="saml:EncryptedElementType"/>
+    <element name="Terminate" type="samlp:TerminateType"/>
+    <complexType name="TerminateType"/>
+    <element name="ManageNameIDResponse" type="samlp:StatusResponseType"/>
+    <element name="LogoutRequest" type="samlp:LogoutRequestType"/>
+    <complexType name="LogoutRequestType">
+        <complexContent>
+            <extension base="samlp:RequestAbstractType">
+                <sequence>
+                    <choice>
+                        <element ref="saml:BaseID"/>
+                        <element ref="saml:NameID"/>
+                        <element ref="saml:EncryptedID"/>
+                    </choice>
+                    <element ref="samlp:SessionIndex" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+                <attribute name="Reason" type="string" use="optional"/>
+                <attribute name="NotOnOrAfter" type="dateTime" use="optional"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="SessionIndex" type="string"/>
+    <element name="LogoutResponse" type="samlp:StatusResponseType"/>
+    <element name="NameIDMappingRequest" type="samlp:NameIDMappingRequestType"/>
+    <complexType name="NameIDMappingRequestType">
+        <complexContent>
+            <extension base="samlp:RequestAbstractType">
+                <sequence>
+                    <choice>
+                        <element ref="saml:BaseID"/>
+                        <element ref="saml:NameID"/>
+                        <element ref="saml:EncryptedID"/>
+                    </choice>
+                    <element ref="samlp:NameIDPolicy"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="NameIDMappingResponse" type="samlp:NameIDMappingResponseType"/>
+    <complexType name="NameIDMappingResponseType">
+        <complexContent>
+            <extension base="samlp:StatusResponseType">
+                <choice>
+                    <element ref="saml:NameID"/>
+                    <element ref="saml:EncryptedID"/>
+                </choice>
+            </extension>
+        </complexContent>
+    </complexType>
+</schema>

Added: modules/security/trunk/impl/src/main/resources/schema/samlv2/xenc-schema.xsd
===================================================================
--- modules/security/trunk/impl/src/main/resources/schema/samlv2/xenc-schema.xsd	                        (rev 0)
+++ modules/security/trunk/impl/src/main/resources/schema/samlv2/xenc-schema.xsd	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd" [
+   <!ATTLIST schema
+     xmlns:xenc CDATA #FIXED 'http://www.w3.org/2001/04/xmlenc#'
+     xmlns:ds CDATA #FIXED 'http://www.w3.org/2000/09/xmldsig#'>
+   <!ENTITY xenc 'http://www.w3.org/2001/04/xmlenc#'>
+   <!ENTITY % p ''>
+   <!ENTITY % s ''>
+  ]>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" version="1.0" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" targetNamespace="http://www.w3.org/2001/04/xmlenc#" elementFormDefault="qualified">
+
+  <import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd"/>
+
+  <complexType name="EncryptedType" abstract="true">
+    <sequence>
+      <element name="EncryptionMethod" type="xenc:EncryptionMethodType" minOccurs="0"/>
+      <element ref="ds:KeyInfo" minOccurs="0"/>
+      <element ref="xenc:CipherData"/>
+      <element ref="xenc:EncryptionProperties" minOccurs="0"/>
+    </sequence>
+    <attribute name="Id" type="ID" use="optional"/>
+    <attribute name="Type" type="anyURI" use="optional"/>
+    <attribute name="MimeType" type="string" use="optional"/>
+    <attribute name="Encoding" type="anyURI" use="optional"/>
+  </complexType>
+  
+  <complexType name="EncryptionMethodType" mixed="true">
+    <sequence>
+      <element name="KeySize" minOccurs="0" type="xenc:KeySizeType"/>
+      <element name="OAEPparams" minOccurs="0" type="base64Binary"/>
+      <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
+    </sequence>
+    <attribute name="Algorithm" type="anyURI" use="required"/>
+  </complexType>
+
+    <simpleType name="KeySizeType">
+      <restriction base="integer"/>
+    </simpleType>
+
+  <element name="CipherData" type="xenc:CipherDataType"/>
+  <complexType name="CipherDataType">
+     <choice>
+       <element name="CipherValue" type="base64Binary"/>
+       <element ref="xenc:CipherReference"/>
+     </choice>
+    </complexType>
+
+   <element name="CipherReference" type="xenc:CipherReferenceType"/>
+   <complexType name="CipherReferenceType">
+       <choice>
+         <element name="Transforms" type="xenc:TransformsType" minOccurs="0"/>
+       </choice>
+       <attribute name="URI" type="anyURI" use="required"/>
+   </complexType>
+
+     <complexType name="TransformsType">
+       <sequence>
+         <element ref="ds:Transform" maxOccurs="unbounded"/>
+       </sequence>
+     </complexType>
+
+
+  <element name="EncryptedData" type="xenc:EncryptedDataType"/>
+  <complexType name="EncryptedDataType">
+    <complexContent>
+      <extension base="xenc:EncryptedType">
+       </extension>
+    </complexContent>
+  </complexType>
+
+  <!-- Children of ds:KeyInfo -->
+
+  <element name="EncryptedKey" type="xenc:EncryptedKeyType"/>
+  <complexType name="EncryptedKeyType">
+    <complexContent>
+      <extension base="xenc:EncryptedType">
+        <sequence>
+          <element ref="xenc:ReferenceList" minOccurs="0"/>
+          <element name="CarriedKeyName" type="string" minOccurs="0"/>
+        </sequence>
+        <attribute name="Recipient" type="string" use="optional"/>
+      </extension>
+    </complexContent>
+  </complexType>
+
+    <element name="AgreementMethod" type="xenc:AgreementMethodType"/>
+    <complexType name="AgreementMethodType" mixed="true">
+      <sequence>
+        <element name="KA-Nonce" minOccurs="0" type="base64Binary"/>
+        <!-- <element ref="ds:DigestMethod" minOccurs="0"/> -->
+        <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
+        <element name="OriginatorKeyInfo" minOccurs="0" type="ds:KeyInfoType"/>
+        <element name="RecipientKeyInfo" minOccurs="0" type="ds:KeyInfoType"/>
+      </sequence>
+      <attribute name="Algorithm" type="anyURI" use="required"/>
+    </complexType>
+
+  <!-- End Children of ds:KeyInfo -->
+
+  <element name="ReferenceList">
+    <complexType>
+      <choice minOccurs="1" maxOccurs="unbounded">
+        <element name="DataReference" type="xenc:ReferenceType"/>
+        <element name="KeyReference" type="xenc:ReferenceType"/>
+      </choice>
+    </complexType>
+  </element>
+
+  <complexType name="ReferenceType">
+    <sequence>
+      <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
+    </sequence>
+    <attribute name="URI" type="anyURI" use="required"/>
+  </complexType>
+
+
+  <element name="EncryptionProperties" type="xenc:EncryptionPropertiesType"/>
+  <complexType name="EncryptionPropertiesType">
+    <sequence>
+      <element ref="xenc:EncryptionProperty" maxOccurs="unbounded"/>
+    </sequence>
+    <attribute name="Id" type="ID" use="optional"/>
+  </complexType>
+
+    <element name="EncryptionProperty" type="xenc:EncryptionPropertyType"/>
+    <complexType name="EncryptionPropertyType" mixed="true">
+      <choice maxOccurs="unbounded">
+        <any namespace="##other" processContents="lax"/>
+      </choice>
+      <attribute name="Target" type="anyURI" use="optional"/>
+      <attribute name="Id" type="ID" use="optional"/>
+      <anyAttribute namespace="http://www.w3.org/XML/1998/namespace"/>
+    </complexType>
+
+</schema>
\ No newline at end of file

Added: modules/security/trunk/impl/src/main/resources/schema/samlv2/xmldsig-core-schema.xsd
===================================================================
--- modules/security/trunk/impl/src/main/resources/schema/samlv2/xmldsig-core-schema.xsd	                        (rev 0)
+++ modules/security/trunk/impl/src/main/resources/schema/samlv2/xmldsig-core-schema.xsd	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,308 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd" [
+   <!ATTLIST schema 
+     xmlns:ds CDATA #FIXED "http://www.w3.org/2000/09/xmldsig#">
+   <!ENTITY dsig 'http://www.w3.org/2000/09/xmldsig#'>
+   <!ENTITY % p ''>
+   <!ENTITY % s ''>
+  ]>
+<!-- Schema for XML Signatures
+    http://www.w3.org/2000/09/xmldsig#
+    $Revision: 1.1 $ on $Date: 2002/02/08 20:32:26 $ by $Author: reagle $
+
+    Copyright 2001 The Internet Society and W3C (Massachusetts Institute
+    of Technology, Institut National de Recherche en Informatique et en
+    Automatique, Keio University). All Rights Reserved.
+    http://www.w3.org/Consortium/Legal/
+
+    This document is governed by the W3C Software License [1] as described
+    in the FAQ [2].
+
+    [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
+    [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" targetNamespace="http://www.w3.org/2000/09/xmldsig#" version="0.1" elementFormDefault="qualified"> 
+
+<!-- Basic Types Defined for Signatures -->
+
+<simpleType name="CryptoBinary">
+  <restriction base="base64Binary">
+  </restriction>
+</simpleType>
+
+<!-- Start Signature -->
+
+<element name="Signature" type="ds:SignatureType"/>
+<complexType name="SignatureType">
+  <sequence> 
+    <element ref="ds:SignedInfo"/> 
+    <element ref="ds:SignatureValue"/> 
+    <element ref="ds:KeyInfo" minOccurs="0"/> 
+    <element ref="ds:Object" minOccurs="0" maxOccurs="unbounded"/> 
+  </sequence>  
+  <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+  <element name="SignatureValue" type="ds:SignatureValueType"/> 
+  <complexType name="SignatureValueType">
+    <simpleContent>
+      <extension base="base64Binary">
+        <attribute name="Id" type="ID" use="optional"/>
+      </extension>
+    </simpleContent>
+  </complexType>
+
+<!-- Start SignedInfo -->
+
+<element name="SignedInfo" type="ds:SignedInfoType"/>
+<complexType name="SignedInfoType">
+  <sequence> 
+    <element ref="ds:CanonicalizationMethod"/> 
+    <element ref="ds:SignatureMethod"/> 
+    <element ref="ds:Reference" maxOccurs="unbounded"/> 
+  </sequence>  
+  <attribute name="Id" type="ID" use="optional"/> 
+</complexType>
+
+  <element name="CanonicalizationMethod" type="ds:CanonicalizationMethodType"/> 
+  <complexType name="CanonicalizationMethodType" mixed="true">
+    <sequence>
+      <any namespace="##any" minOccurs="0" maxOccurs="unbounded"/>
+      <!-- (0,unbounded) elements from (1,1) namespace -->
+    </sequence>
+    <attribute name="Algorithm" type="anyURI" use="required"/> 
+  </complexType>
+
+  <element name="SignatureMethod" type="ds:SignatureMethodType"/>
+  <complexType name="SignatureMethodType" mixed="true">
+    <sequence>
+      <element name="HMACOutputLength" minOccurs="0" type="ds:HMACOutputLengthType"/>
+      <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
+      <!-- (0,unbounded) elements from (1,1) external namespace -->
+    </sequence>
+    <attribute name="Algorithm" type="anyURI" use="required"/> 
+  </complexType>
+
+<!-- Start Reference -->
+
+<element name="Reference" type="ds:ReferenceType"/>
+<complexType name="ReferenceType">
+  <sequence> 
+    <element ref="ds:Transforms" minOccurs="0"/> 
+    <element ref="ds:DigestMethod"/> 
+    <element ref="ds:DigestValue"/> 
+  </sequence>
+  <attribute name="Id" type="ID" use="optional"/> 
+  <attribute name="URI" type="anyURI" use="optional"/> 
+  <attribute name="Type" type="anyURI" use="optional"/> 
+</complexType>
+
+  <element name="Transforms" type="ds:TransformsType"/>
+  <complexType name="TransformsType">
+    <sequence>
+      <element ref="ds:Transform" maxOccurs="unbounded"/>  
+    </sequence>
+  </complexType>
+
+  <element name="Transform" type="ds:TransformType"/>
+  <complexType name="TransformType" mixed="true">
+    <choice minOccurs="0" maxOccurs="unbounded"> 
+      <any namespace="##other" processContents="lax"/>
+      <!-- (1,1) elements from (0,unbounded) namespaces -->
+      <element name="XPath" type="string"/> 
+    </choice>
+    <attribute name="Algorithm" type="anyURI" use="required"/> 
+  </complexType>
+
+<!-- End Reference -->
+
+<element name="DigestMethod" type="ds:DigestMethodType"/>
+<complexType name="DigestMethodType" mixed="true"> 
+  <sequence>
+    <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+  </sequence>    
+  <attribute name="Algorithm" type="anyURI" use="required"/> 
+</complexType>
+
+<element name="DigestValue" type="ds:DigestValueType"/>
+<simpleType name="DigestValueType">
+  <restriction base="base64Binary"/>
+</simpleType>
+
+<!-- End SignedInfo -->
+
+<!-- Start KeyInfo -->
+
+<element name="KeyInfo" type="ds:KeyInfoType"/> 
+<complexType name="KeyInfoType" mixed="true">
+  <choice maxOccurs="unbounded">     
+    <element ref="ds:KeyName"/> 
+    <element ref="ds:KeyValue"/> 
+    <element ref="ds:RetrievalMethod"/> 
+    <element ref="ds:X509Data"/> 
+    <element ref="ds:PGPData"/> 
+    <element ref="ds:SPKIData"/>
+    <element ref="ds:MgmtData"/>
+    <any processContents="lax" namespace="##other"/>
+    <!-- (1,1) elements from (0,unbounded) namespaces -->
+  </choice>
+  <attribute name="Id" type="ID" use="optional"/> 
+</complexType>
+
+  <element name="KeyName" type="string"/>
+  <element name="MgmtData" type="string"/>
+
+  <element name="KeyValue" type="ds:KeyValueType"/> 
+  <complexType name="KeyValueType" mixed="true">
+   <choice>
+     <element ref="ds:DSAKeyValue"/>
+     <element ref="ds:RSAKeyValue"/>
+     <any namespace="##other" processContents="lax"/>
+   </choice>
+  </complexType>
+
+  <element name="RetrievalMethod" type="ds:RetrievalMethodType"/> 
+  <complexType name="RetrievalMethodType">
+    <sequence>
+      <element ref="ds:Transforms" minOccurs="0"/> 
+    </sequence>  
+    <attribute name="URI" type="anyURI"/>
+    <attribute name="Type" type="anyURI" use="optional"/>
+  </complexType>
+
+<!-- Start X509Data -->
+
+<element name="X509Data" type="ds:X509DataType"/> 
+<complexType name="X509DataType">
+  <sequence maxOccurs="unbounded">
+    <choice>
+      <element name="X509IssuerSerial" type="ds:X509IssuerSerialType"/>
+      <element name="X509SKI" type="base64Binary"/>
+      <element name="X509SubjectName" type="string"/>
+      <element name="X509Certificate" type="base64Binary"/>
+      <element name="X509CRL" type="base64Binary"/>
+      <any namespace="##other" processContents="lax"/>
+    </choice>
+  </sequence>
+</complexType>
+
+<complexType name="X509IssuerSerialType"> 
+  <sequence> 
+    <element name="X509IssuerName" type="string"/> 
+    <element name="X509SerialNumber" type="integer"/> 
+  </sequence>
+</complexType>
+
+<!-- End X509Data -->
+
+<!-- Begin PGPData -->
+
+<element name="PGPData" type="ds:PGPDataType"/> 
+<complexType name="PGPDataType"> 
+  <choice>
+    <sequence>
+      <element name="PGPKeyID" type="base64Binary"/> 
+      <element name="PGPKeyPacket" type="base64Binary" minOccurs="0"/> 
+      <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+    </sequence>
+    <sequence>
+      <element name="PGPKeyPacket" type="base64Binary"/> 
+      <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+    </sequence>
+  </choice>
+</complexType>
+
+<!-- End PGPData -->
+
+<!-- Begin SPKIData -->
+
+<element name="SPKIData" type="ds:SPKIDataType"/> 
+<complexType name="SPKIDataType">
+  <sequence maxOccurs="unbounded">
+    <element name="SPKISexp" type="base64Binary"/>
+    <any namespace="##other" processContents="lax" minOccurs="0"/>
+  </sequence>
+</complexType> 
+
+<!-- End SPKIData -->
+
+<!-- End KeyInfo -->
+
+<!-- Start Object (Manifest, SignatureProperty) -->
+
+<element name="Object" type="ds:ObjectType"/> 
+<complexType name="ObjectType" mixed="true">
+  <sequence minOccurs="0" maxOccurs="unbounded">
+    <any namespace="##any" processContents="lax"/>
+  </sequence>
+  <attribute name="Id" type="ID" use="optional"/> 
+  <attribute name="MimeType" type="string" use="optional"/> <!-- add a grep facet -->
+  <attribute name="Encoding" type="anyURI" use="optional"/> 
+</complexType>
+
+<element name="Manifest" type="ds:ManifestType"/> 
+<complexType name="ManifestType">
+  <sequence>
+    <element ref="ds:Reference" maxOccurs="unbounded"/> 
+  </sequence>
+  <attribute name="Id" type="ID" use="optional"/> 
+</complexType>
+
+<element name="SignatureProperties" type="ds:SignaturePropertiesType"/> 
+<complexType name="SignaturePropertiesType">
+  <sequence>
+    <element ref="ds:SignatureProperty" maxOccurs="unbounded"/> 
+  </sequence>
+  <attribute name="Id" type="ID" use="optional"/> 
+</complexType>
+
+   <element name="SignatureProperty" type="ds:SignaturePropertyType"/> 
+   <complexType name="SignaturePropertyType" mixed="true">
+     <choice maxOccurs="unbounded">
+       <any namespace="##other" processContents="lax"/>
+       <!-- (1,1) elements from (1,unbounded) namespaces -->
+     </choice>
+     <attribute name="Target" type="anyURI" use="required"/> 
+     <attribute name="Id" type="ID" use="optional"/> 
+   </complexType>
+
+<!-- End Object (Manifest, SignatureProperty) -->
+
+<!-- Start Algorithm Parameters -->
+
+<simpleType name="HMACOutputLengthType">
+  <restriction base="integer"/>
+</simpleType>
+
+<!-- Start KeyValue Element-types -->
+
+<element name="DSAKeyValue" type="ds:DSAKeyValueType"/>
+<complexType name="DSAKeyValueType">
+  <sequence>
+    <sequence minOccurs="0">
+      <element name="P" type="ds:CryptoBinary"/>
+      <element name="Q" type="ds:CryptoBinary"/>
+    </sequence>
+    <element name="G" type="ds:CryptoBinary" minOccurs="0"/>
+    <element name="Y" type="ds:CryptoBinary"/>
+    <element name="J" type="ds:CryptoBinary" minOccurs="0"/>
+    <sequence minOccurs="0">
+      <element name="Seed" type="ds:CryptoBinary"/>
+      <element name="PgenCounter" type="ds:CryptoBinary"/>
+    </sequence>
+  </sequence>
+</complexType>
+
+<element name="RSAKeyValue" type="ds:RSAKeyValueType"/>
+<complexType name="RSAKeyValueType">
+  <sequence>
+    <element name="Modulus" type="ds:CryptoBinary"/> 
+    <element name="Exponent" type="ds:CryptoBinary"/> 
+  </sequence>
+</complexType> 
+
+<!-- End KeyValue Element-types -->
+
+<!-- End Signature -->
+
+</schema>
\ No newline at end of file

Added: modules/security/trunk/impl/src/main/resources/schema/xrds/xrd.xsd
===================================================================
--- modules/security/trunk/impl/src/main/resources/schema/xrds/xrd.xsd	                        (rev 0)
+++ modules/security/trunk/impl/src/main/resources/schema/xrds/xrd.xsd	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xrd="xri://$xrd*($v*2.0)" targetNamespace="xri://$xrd*($v*2.0)" elementFormDefault="qualified">
+	<!-- Utility patterns -->
+	<xs:attributeGroup name="otherattribute">
+		<xs:anyAttribute namespace="##other" processContents="lax"/>
+	</xs:attributeGroup>
+	<xs:group name="otherelement">
+		<xs:choice>
+			<xs:any namespace="##other" processContents="lax"/>
+			<xs:any namespace="##local" processContents="lax"/>
+		</xs:choice>
+	</xs:group>
+	<xs:attributeGroup name="priorityAttrGrp">
+		<xs:attribute name="priority" type="xs:nonNegativeInteger" use="optional"/>
+	</xs:attributeGroup>
+	<xs:attributeGroup name="codeAttrGrp">
+		<xs:attribute name="code" type="xs:int" use="required"/>
+	</xs:attributeGroup>
+	<xs:attributeGroup name="verifyAttrGrp">
+		<xs:attribute name="cid" use="optional">
+			<xs:simpleType>
+				<xs:restriction base="xs:string">
+					<xs:enumeration value="absent"/>
+					<xs:enumeration value="off"/>
+					<xs:enumeration value="verified"/>
+					<xs:enumeration value="failed"/>
+				</xs:restriction>
+			</xs:simpleType>
+		</xs:attribute>
+		<xs:attribute name="ceid" use="optional">
+			<xs:simpleType>
+				<xs:restriction base="xs:string">
+					<xs:enumeration value="absent"/>
+					<xs:enumeration value="off"/>
+					<xs:enumeration value="verified"/>
+					<xs:enumeration value="failed"/>
+				</xs:restriction>
+			</xs:simpleType>
+		</xs:attribute>
+	</xs:attributeGroup>
+	<xs:attributeGroup name="selectionAttrGrp">
+		<xs:attribute name="match" use="optional" default="default">
+			<xs:simpleType>
+				<xs:restriction base="xs:string">
+					<xs:enumeration value="default"/>
+					<xs:enumeration value="any"/>
+					<xs:enumeration value="non-null"/>
+					<xs:enumeration value="null"/>
+				</xs:restriction>
+			</xs:simpleType>
+		</xs:attribute>
+		<xs:attribute name="select" type="xs:boolean" use="optional" default="false"/>
+	</xs:attributeGroup>
+	<xs:attributeGroup name="appendAttrGrp">
+		<xs:attribute name="append" use="optional" default="none">
+			<xs:simpleType>
+				<xs:restriction base="xs:string">
+					<xs:enumeration value="none"/>
+					<xs:enumeration value="local"/>
+					<xs:enumeration value="authority"/>
+					<xs:enumeration value="path"/>
+					<xs:enumeration value="query"/>
+					<xs:enumeration value="qxri"/>
+				</xs:restriction>
+			</xs:simpleType>
+		</xs:attribute>
+	</xs:attributeGroup>
+	<xs:complexType name="URIPattern">
+		<xs:simpleContent>
+			<xs:extension base="xs:anyURI">
+				<xs:attributeGroup ref="xrd:otherattribute"/>
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+	<xs:complexType name="URIPriorityPattern">
+		<xs:simpleContent>
+			<xs:extension base="xrd:URIPattern">
+				<xs:attributeGroup ref="xrd:priorityAttrGrp"/>
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+	<xs:complexType name="URIPriorityAppendPattern">
+		<xs:simpleContent>
+			<xs:extension base="xrd:URIPriorityPattern">
+				<xs:attributeGroup ref="xrd:appendAttrGrp"/>
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+	<xs:complexType name="StringPattern">
+		<xs:simpleContent>
+			<xs:extension base="xs:string">
+				<xs:attributeGroup ref="xrd:otherattribute"/>
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+	<xs:complexType name="StringSelectionPattern">
+		<xs:simpleContent>
+			<xs:extension base="xrd:StringPattern">
+				<xs:attributeGroup ref="xrd:selectionAttrGrp"/>
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+	<!-- Patterns for elements -->
+	<xs:element name="XRD">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element ref="xrd:Query" minOccurs="0"/>
+				<xs:element ref="xrd:Status" minOccurs="0"/>
+				<xs:element ref="xrd:ServerStatus" minOccurs="0"/>
+				<xs:element ref="xrd:Expires" minOccurs="0"/>
+				<xs:element ref="xrd:ProviderID" minOccurs="0"/>
+				<xs:choice>
+					<xs:element ref="xrd:Redirect" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element ref="xrd:Ref" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:choice>
+				<xs:element ref="xrd:LocalID" minOccurs="0" maxOccurs="unbounded"/>
+				<xs:element ref="xrd:EquivID" minOccurs="0" maxOccurs="unbounded"/>
+				<xs:element ref="xrd:CanonicalID" minOccurs="0" maxOccurs="unbounded"/>
+				<xs:element ref="xrd:CanonicalEquivID" minOccurs="0" maxOccurs="unbounded"/>
+				<xs:element ref="xrd:Service" minOccurs="0" maxOccurs="unbounded"/>
+				<xs:group ref="xrd:otherelement" minOccurs="0" maxOccurs="unbounded"/>
+			</xs:sequence>
+			<xs:attribute name="idref" type="xs:IDREF" use="optional"/>
+			<xs:attribute name="version" type="xs:string" use="optional" fixed="2.0"/>
+			<xs:attributeGroup ref="xrd:otherattribute"/>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="Query" type="xrd:StringPattern"/>
+	<xs:element name="Status">
+		<xs:complexType>
+			<xs:simpleContent>
+				<xs:extension base="xrd:StringPattern">
+					<xs:attributeGroup ref="xrd:codeAttrGrp"/>
+					<xs:attributeGroup ref="xrd:verifyAttrGrp"/>
+					<xs:attributeGroup ref="xrd:otherattribute"/>
+				</xs:extension>
+			</xs:simpleContent>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="ServerStatus">
+		<xs:complexType>
+			<xs:simpleContent>
+				<xs:extension base="xrd:StringPattern">
+					<xs:attributeGroup ref="xrd:codeAttrGrp"/>
+					<xs:attributeGroup ref="xrd:otherattribute"/>
+				</xs:extension>
+			</xs:simpleContent>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="Expires">
+		<xs:complexType>
+			<xs:simpleContent>
+				<xs:extension base="xs:dateTime">
+					<xs:attributeGroup ref="xrd:otherattribute"/>
+				</xs:extension>
+			</xs:simpleContent>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="ProviderID" type="xrd:URIPattern"/>
+	<xs:element name="Redirect" type="xrd:URIPriorityAppendPattern"/>
+	<xs:element name="Ref" type="xrd:URIPriorityPattern"/>
+	<xs:element name="LocalID">
+		<xs:complexType>
+			<xs:simpleContent>
+				<xs:extension base="xrd:StringPattern">
+					<xs:attributeGroup ref="xrd:priorityAttrGrp"/>
+				</xs:extension>
+			</xs:simpleContent>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="EquivID" type="xrd:URIPriorityPattern"/>
+	<xs:element name="CanonicalID" type="xrd:URIPriorityPattern"/>
+	<xs:element name="CanonicalEquivID" type="xrd:URIPriorityPattern"/>
+	<xs:element name="Service">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element ref="xrd:ProviderID" minOccurs="0"/>
+				<xs:element ref="xrd:Type" minOccurs="0" maxOccurs="unbounded"/>
+				<xs:element ref="xrd:Path" minOccurs="0" maxOccurs="unbounded"/>
+				<xs:element ref="xrd:MediaType" minOccurs="0" maxOccurs="unbounded"/>
+				<xs:choice>
+					<xs:element ref="xrd:URI" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element ref="xrd:Redirect" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element ref="xrd:Ref" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:choice>
+				<xs:element ref="xrd:LocalID" minOccurs="0" maxOccurs="unbounded"/>
+				<xs:group ref="xrd:otherelement" minOccurs="0" maxOccurs="unbounded"/>
+			</xs:sequence>
+			<xs:attributeGroup ref="xrd:priorityAttrGrp"/>
+			<xs:attributeGroup ref="xrd:otherattribute"/>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="Type">
+		<xs:complexType>
+			<xs:simpleContent>
+				<xs:extension base="xrd:URIPattern">
+					<xs:attributeGroup ref="xrd:selectionAttrGrp"/>
+				</xs:extension>
+			</xs:simpleContent>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="Path" type="xrd:StringSelectionPattern"/>
+	<xs:element name="MediaType" type="xrd:StringSelectionPattern"/>
+	<xs:element name="URI" type="xrd:URIPriorityAppendPattern"/>
+</xs:schema>
\ No newline at end of file

Added: modules/security/trunk/impl/src/main/resources/schema/xrds/xrds.xsd
===================================================================
--- modules/security/trunk/impl/src/main/resources/schema/xrds/xrds.xsd	                        (rev 0)
+++ modules/security/trunk/impl/src/main/resources/schema/xrds/xrds.xsd	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xrds="xri://$xrds" targetNamespace="xri://$xrds" elementFormDefault="qualified">
+	<!-- Utility patterns -->
+	<xs:attributeGroup name="otherattribute">
+		<xs:anyAttribute namespace="##other" processContents="lax"/>
+	</xs:attributeGroup>
+	<xs:group name="otherelement">
+		<xs:choice>
+			<xs:any namespace="##other" processContents="lax"/>
+			<xs:any namespace="##local" processContents="lax"/>
+		</xs:choice>
+	</xs:group>
+	<!-- Patterns for elements -->
+	<xs:element name="XRDS">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:group ref="xrds:otherelement" minOccurs="0" maxOccurs="unbounded"/>
+			</xs:sequence>
+			<xs:attributeGroup ref="xrds:otherattribute"/>
+			<!--XML Schema does not currently offer a means to express that only one of the following two attributes may be used in any XRDS element, i.e., an XRDS document may describe EITHER a redirect identifier or a ref identifier but not both.-->
+			<xs:attribute name="redirect" type="xs:anyURI" use="optional"/>
+			<xs:attribute name="ref" type="xs:anyURI" use="optional"/>
+		</xs:complexType>
+	</xs:element>
+</xs:schema>
\ No newline at end of file

Added: modules/security/trunk/impl/src/main/xjb/config-bindings.xjb
===================================================================
--- modules/security/trunk/impl/src/main/xjb/config-bindings.xjb	                        (rev 0)
+++ modules/security/trunk/impl/src/main/xjb/config-bindings.xjb	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jaxb:bindings version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
+	xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+</jaxb:bindings>
\ No newline at end of file

Added: modules/security/trunk/impl/src/main/xjb/samlv2-bindings.xjb
===================================================================
--- modules/security/trunk/impl/src/main/xjb/samlv2-bindings.xjb	                        (rev 0)
+++ modules/security/trunk/impl/src/main/xjb/samlv2-bindings.xjb	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jaxb:bindings version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
+	xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+	<jaxb:bindings
+		schemaLocation="../resources/schema/samlv2/saml-schema-assertion-2.0.xsd">
+		<jaxb:bindings node="/xs:schema">
+			<jaxb:schemaBindings>
+				<jaxb:package name="org.jboss.seam.security.external_authentication.jaxb.samlv2.assertion" />
+			</jaxb:schemaBindings>
+		</jaxb:bindings>
+	</jaxb:bindings>
+
+	<jaxb:bindings
+		schemaLocation="../resources/schema/samlv2/saml-schema-protocol-2.0.xsd">
+		<jaxb:bindings node="/xs:schema">
+			<jaxb:schemaBindings>
+				<jaxb:package name="org.jboss.seam.security.external_authentication.jaxb.samlv2.protocol" />
+			</jaxb:schemaBindings>
+		</jaxb:bindings>
+	</jaxb:bindings>
+
+	<jaxb:bindings
+		schemaLocation="../resources/schema/samlv2/saml-schema-metadata-2.0.xsd">
+		<jaxb:bindings node="/xs:schema">
+			<jaxb:schemaBindings>
+				<jaxb:package name="org.jboss.seam.security.external_authentication.jaxb.samlv2.metadata" />
+			</jaxb:schemaBindings>
+		</jaxb:bindings>
+	</jaxb:bindings>
+
+	<jaxb:bindings schemaLocation="../resources/schema/samlv2/xenc-schema.xsd">
+		<jaxb:bindings node="/xs:schema">
+			<jaxb:schemaBindings>
+				<jaxb:package name="org.jboss.seam.external_authentication.jaxb.xenc" />
+			</jaxb:schemaBindings>
+		</jaxb:bindings>
+	</jaxb:bindings>
+
+	<jaxb:bindings schemaLocation="../resources/schema/samlv2/xmldsig-core-schema.xsd">
+		<jaxb:bindings node="/xs:schema">
+			<jaxb:schemaBindings>
+				<jaxb:package name="org.jboss.seam.security.external_authentication.jaxb.xmldsig" />
+			</jaxb:schemaBindings>
+		</jaxb:bindings>
+	</jaxb:bindings>
+
+</jaxb:bindings>
\ No newline at end of file

Added: modules/security/trunk/impl/src/main/xjb/xrds-bindings.xjb
===================================================================
--- modules/security/trunk/impl/src/main/xjb/xrds-bindings.xjb	                        (rev 0)
+++ modules/security/trunk/impl/src/main/xjb/xrds-bindings.xjb	2010-08-06 14:08:04 UTC (rev 13562)
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jaxb:bindings version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
+	xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+</jaxb:bindings>
\ No newline at end of file



More information about the seam-commits mailing list