diff --git a/agent/pom.xml b/agent/pom.xml index a9e65e959..2cb3746b2 100644 --- a/agent/pom.xml +++ b/agent/pom.xml @@ -2,7 +2,6 @@ org.exoplatform.gatein.sso sso-parent - ../pom.xml 6.6.x-mips-SNAPSHOT @@ -17,17 +16,13 @@ - org.exoplatform.gatein.sso + ${project.groupId} sso-auth-callback org.gatein.common common-common - - - org.apache.tomcat - tomcat-catalina - provided + provided org.exoplatform.core @@ -44,21 +39,6 @@ httpclient provided - - org.jboss.security - jboss-negotiation-spnego - provided - - - org.picketlink - picketlink-federation - provided - - - org.picketlink.distribution - picketlink-wildfly8 - provided - org.mockito mockito-core diff --git a/agent/src/main/java/org/gatein/sso/agent/GenericAgent.java b/agent/src/main/java/org/gatein/sso/agent/GenericAgent.java index 24b52a690..fda907952 100644 --- a/agent/src/main/java/org/gatein/sso/agent/GenericAgent.java +++ b/agent/src/main/java/org/gatein/sso/agent/GenericAgent.java @@ -38,7 +38,7 @@ import org.exoplatform.container.RootContainer; import org.exoplatform.services.organization.OrganizationService; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; /** * Base agent superclass used by other SSO agents (CAS, OpenAM) diff --git a/agent/src/main/java/org/gatein/sso/agent/filter/AbstractLogoutFilter.java b/agent/src/main/java/org/gatein/sso/agent/filter/AbstractLogoutFilter.java index 71dbc2b46..25402d922 100644 --- a/agent/src/main/java/org/gatein/sso/agent/filter/AbstractLogoutFilter.java +++ b/agent/src/main/java/org/gatein/sso/agent/filter/AbstractLogoutFilter.java @@ -30,13 +30,13 @@ import java.io.UnsupportedEncodingException; import java.util.Map; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; /** * @author Sohil Shah diff --git a/agent/src/main/java/org/gatein/sso/agent/filter/InitiateLoginFilter.java b/agent/src/main/java/org/gatein/sso/agent/filter/InitiateLoginFilter.java index 59103b8a1..c9548421e 100644 --- a/agent/src/main/java/org/gatein/sso/agent/filter/InitiateLoginFilter.java +++ b/agent/src/main/java/org/gatein/sso/agent/filter/InitiateLoginFilter.java @@ -5,9 +5,9 @@ import java.io.IOException; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.exoplatform.services.log.ExoLogger; diff --git a/agent/src/main/java/org/gatein/sso/agent/filter/LoginRedirectFilter.java b/agent/src/main/java/org/gatein/sso/agent/filter/LoginRedirectFilter.java index ef0563dc8..d81dd2677 100644 --- a/agent/src/main/java/org/gatein/sso/agent/filter/LoginRedirectFilter.java +++ b/agent/src/main/java/org/gatein/sso/agent/filter/LoginRedirectFilter.java @@ -27,12 +27,12 @@ import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; /** diff --git a/agent/src/main/java/org/gatein/sso/agent/filter/OpenSSOCDLoginRedirectFilter.java b/agent/src/main/java/org/gatein/sso/agent/filter/OpenSSOCDLoginRedirectFilter.java index bd2d9e380..cf4c235f2 100644 --- a/agent/src/main/java/org/gatein/sso/agent/filter/OpenSSOCDLoginRedirectFilter.java +++ b/agent/src/main/java/org/gatein/sso/agent/filter/OpenSSOCDLoginRedirectFilter.java @@ -27,7 +27,7 @@ import org.exoplatform.services.log.Log; import org.gatein.sso.agent.opensso.OpenSSOAgentImpl; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.text.SimpleDateFormat; diff --git a/agent/src/main/java/org/gatein/sso/agent/filter/OpenSSOLogoutFilter.java b/agent/src/main/java/org/gatein/sso/agent/filter/OpenSSOLogoutFilter.java index fcbb36e89..d70f70e08 100644 --- a/agent/src/main/java/org/gatein/sso/agent/filter/OpenSSOLogoutFilter.java +++ b/agent/src/main/java/org/gatein/sso/agent/filter/OpenSSOLogoutFilter.java @@ -22,7 +22,7 @@ package org.gatein.sso.agent.filter; import java.net.URLEncoder; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; //Works for GateIn Portal Logout URL = {AnyURL}?portal:componentId=UIPortal&portal:action=Logout diff --git a/agent/src/main/java/org/gatein/sso/agent/filter/PicketlinkSTSIntegrationFilter.java b/agent/src/main/java/org/gatein/sso/agent/filter/PicketlinkSTSIntegrationFilter.java deleted file mode 100644 index 73ec84271..000000000 --- a/agent/src/main/java/org/gatein/sso/agent/filter/PicketlinkSTSIntegrationFilter.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * JBoss, a division of Red Hat - * Copyright 2012, Red Hat Middleware, LLC, and individual - * contributors as indicated 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.gatein.sso.agent.filter; - -import org.exoplatform.container.web.AbstractFilter; -import org.exoplatform.services.log.ExoLogger; -import org.exoplatform.services.log.Log; -import org.exoplatform.services.security.jaas.UserPrincipal; -import org.jboss.security.SecurityContext; -import org.jboss.security.SecurityContextAssociation; -import org.jboss.security.client.SecurityClient; -import org.jboss.security.client.SecurityClientFactory; - -import javax.security.auth.Subject; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Set; -import org.picketlink.identity.federation.core.wstrust.SamlCredential; - -/** - * Filter for set {@link SamlCredential} into {@link SecurityClient}, which enables to propagate authentication from SAML2 ticket into - * underlying EJB or WS calls. - * - * @author Marek Posolda - */ -public class PicketlinkSTSIntegrationFilter extends AbstractFilter -{ - private static Log log = ExoLogger.getLogger(PicketlinkSTSIntegrationFilter.class); - - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException - { - HttpServletRequest httpRequest = (HttpServletRequest)request; - if (httpRequest.getRemoteUser() != null) - { - try - { - SamlCredential samlCredential = getSamlCredential(); - - if (log.isTraceEnabled()) - { - log.trace("Found SamlCredential inside Subject: " + samlCredential); - } - - // Now set the security context, which can be used in EJB or other calls - if (samlCredential != null) - { - SecurityClient client = SecurityClientFactory.getSecurityClient(); - // Simple login just updates the security context - client.setSimple(new UserPrincipal(httpRequest.getRemoteUser()), samlCredential); - client.login(); - - if (log.isTraceEnabled()) - { - log.trace("SecurityClient successfully updated with SAMLCredential"); - } - } - - } - catch (Exception e) - { - e.printStackTrace(); - } - } - - chain.doFilter(request, response); - } - - public void destroy() - { - } - - private SamlCredential getSamlCredential() - { - Subject subj = getCurrentSubject(); - - if (log.isTraceEnabled()) - { - log.trace("Found subject " + subj); - } - - if (subj == null) - { - return null; - } - - Set credentials = subj.getPublicCredentials(); - for (Object credential : credentials) - { - if (credential instanceof SamlCredential) - { - return (SamlCredential)credential; - } - } - - return null; - } - - /** - * JBoss specific way for obtaining a Subject. - * TODO: is JBoss specific way needed? subject should be available in ConversationState - * - * @return subject - */ - protected Subject getCurrentSubject() - { - SecurityContext securityContext = AccessController.doPrivileged(new PrivilegedAction() - { - public SecurityContext run() - { - return SecurityContextAssociation.getSecurityContext(); - } - }); - return securityContext.getSubjectInfo().getAuthenticatedSubject(); - } -} diff --git a/agent/src/main/java/org/gatein/sso/agent/filter/SPNEGOFilter.java b/agent/src/main/java/org/gatein/sso/agent/filter/SPNEGOFilter.java deleted file mode 100644 index 3616a5c66..000000000 --- a/agent/src/main/java/org/gatein/sso/agent/filter/SPNEGOFilter.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * JBoss, a division of Red Hat - * Copyright 2011, Red Hat Middleware, LLC, and individual - * contributors as indicated 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.gatein.sso.agent.filter; - -import java.io.IOException; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - -import org.exoplatform.container.web.AbstractFilter; - -/** - * Filter is needed because when fallback to FORM authentication, we don't need to redirect request to /dologin, which is secured URI, - * but we need to go directly to /initiatelogin without going again through Tomcat authenticator. - * - * TODO: Suggest removing this filter as with new GateIn (Servlet 3.0 authentication) it may not be needed anymore - * - * @author Marek Posolda - */ -public class SPNEGOFilter extends AbstractFilter -{ - - public static final String ATTR_INITIAL_URI = "SPNEGOFilter.initialURI"; - - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException - { - HttpServletRequest httpRequest = (HttpServletRequest)request; - HttpServletResponse httpResponse = (HttpServletResponse)response; - try - { - - // first save initialURI as parameter into HTTP session. We may need it later in authenticator - String initialURI = httpRequest.getParameter("initialURI"); - if (initialURI != null) - { - httpRequest.getSession().setAttribute(ATTR_INITIAL_URI, initialURI); - } - - // we need to redirect directly to initiatelogin without going through secured URL. - HttpServletResponse wrapperResponse = new IgnoreRedirectHttpResponse(httpResponse); - chain.doFilter(request, wrapperResponse); - httpResponse.sendRedirect(httpRequest.getContextPath() + "/initiatelogin"); - } - catch(Throwable t) - { - throw new RuntimeException(t); - } - } - - public void destroy() - { - } - - // Ignoring calls to response.sendRedirect, which are performed from PortalLoginController - private class IgnoreRedirectHttpResponse extends HttpServletResponseWrapper - { - - public IgnoreRedirectHttpResponse(HttpServletResponse response) - { - super(response); - } - - @Override - public void sendRedirect(String location) - { - } - - } -} diff --git a/agent/src/main/java/org/gatein/sso/agent/filter/api/AbstractSSOInterceptor.java b/agent/src/main/java/org/gatein/sso/agent/filter/api/AbstractSSOInterceptor.java index 735c93c43..304167ab8 100644 --- a/agent/src/main/java/org/gatein/sso/agent/filter/api/AbstractSSOInterceptor.java +++ b/agent/src/main/java/org/gatein/sso/agent/filter/api/AbstractSSOInterceptor.java @@ -30,8 +30,8 @@ import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; /** * Base {@link SSOInterceptor} which adds possibility to be initialized either through Servlet API or through eXo kernel diff --git a/agent/src/main/java/org/gatein/sso/agent/filter/api/SSOInterceptor.java b/agent/src/main/java/org/gatein/sso/agent/filter/api/SSOInterceptor.java index 72117cee0..0ea02e424 100644 --- a/agent/src/main/java/org/gatein/sso/agent/filter/api/SSOInterceptor.java +++ b/agent/src/main/java/org/gatein/sso/agent/filter/api/SSOInterceptor.java @@ -26,7 +26,7 @@ import org.exoplatform.container.ExoContainerContext; import org.exoplatform.container.xml.InitParams; -import javax.servlet.Filter; +import jakarta.servlet.Filter; /** * SSOInterceptor is actually filter, which can be configured through exo kernel diff --git a/agent/src/main/java/org/gatein/sso/agent/filter/api/SSOInterceptorInitializationContext.java b/agent/src/main/java/org/gatein/sso/agent/filter/api/SSOInterceptorInitializationContext.java index fce90064d..1004ecba9 100644 --- a/agent/src/main/java/org/gatein/sso/agent/filter/api/SSOInterceptorInitializationContext.java +++ b/agent/src/main/java/org/gatein/sso/agent/filter/api/SSOInterceptorInitializationContext.java @@ -29,7 +29,7 @@ import org.exoplatform.container.xml.InitParams; import org.exoplatform.container.xml.ValueParam; -import javax.servlet.FilterConfig; +import jakarta.servlet.FilterConfig; /** * Context, which encapsulates all initialization configuration about {@link SSOInterceptor} and is able to recognize diff --git a/agent/src/main/java/org/gatein/sso/agent/login/SSOLoginModule.java b/agent/src/main/java/org/gatein/sso/agent/login/SSOLoginModule.java index e8abf9982..b33e03431 100644 --- a/agent/src/main/java/org/gatein/sso/agent/login/SSOLoginModule.java +++ b/agent/src/main/java/org/gatein/sso/agent/login/SSOLoginModule.java @@ -27,7 +27,7 @@ import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.login.LoginException; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; @@ -152,7 +152,7 @@ protected HttpServletRequest getCurrentHttpServletRequest() { try { - request = (HttpServletRequest)getContextMethod.invoke(null, "javax.servlet.http.HttpServletRequest"); + request = (HttpServletRequest)getContextMethod.invoke(null, "jakarta.servlet.http.HttpServletRequest"); } catch(Throwable e) { diff --git a/agent/src/main/java/org/gatein/sso/agent/opensso/OpenSSOAgent.java b/agent/src/main/java/org/gatein/sso/agent/opensso/OpenSSOAgent.java index 8f6965857..5f4776f80 100644 --- a/agent/src/main/java/org/gatein/sso/agent/opensso/OpenSSOAgent.java +++ b/agent/src/main/java/org/gatein/sso/agent/opensso/OpenSSOAgent.java @@ -23,8 +23,8 @@ package org.gatein.sso.agent.opensso; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; /** * Contract for OpenSSO agent diff --git a/agent/src/main/java/org/gatein/sso/agent/opensso/OpenSSOAgentImpl.java b/agent/src/main/java/org/gatein/sso/agent/opensso/OpenSSOAgentImpl.java index 006223c5e..5bf9b99f4 100644 --- a/agent/src/main/java/org/gatein/sso/agent/opensso/OpenSSOAgentImpl.java +++ b/agent/src/main/java/org/gatein/sso/agent/opensso/OpenSSOAgentImpl.java @@ -35,9 +35,9 @@ import org.exoplatform.services.log.Log; import org.gatein.sso.agent.GenericAgent; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; diff --git a/agent/src/test/java/org/gatein/sso/agent/filter/InitiateLoginFilterTest.java b/agent/src/test/java/org/gatein/sso/agent/filter/InitiateLoginFilterTest.java index 0b7086a48..bb363d5c0 100644 --- a/agent/src/test/java/org/gatein/sso/agent/filter/InitiateLoginFilterTest.java +++ b/agent/src/test/java/org/gatein/sso/agent/filter/InitiateLoginFilterTest.java @@ -11,12 +11,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import org.mockito.internal.verification.VerificationModeFactory; import org.mockito.invocation.InvocationOnMock; diff --git a/auth-callback/pom.xml b/auth-callback/pom.xml index a85bda4b8..d5b4e4698 100644 --- a/auth-callback/pom.xml +++ b/auth-callback/pom.xml @@ -2,7 +2,6 @@ org.exoplatform.gatein.sso sso-parent - ../pom.xml 6.6.x-mips-SNAPSHOT @@ -15,6 +14,11 @@ + + + org.apache.tomcat + tomcat-catalina + org.exoplatform.ws exo.ws.rest.core @@ -23,7 +27,6 @@ org.exoplatform.core exo.core.component.security.core - org.exoplatform.gatein.wci wci-wci diff --git a/agent/src/main/java/org/gatein/sso/agent/tomcat/ServletAccess.java b/auth-callback/src/main/java/org/gatein/sso/agent/tomcat/ServletAccess.java similarity index 95% rename from agent/src/main/java/org/gatein/sso/agent/tomcat/ServletAccess.java rename to auth-callback/src/main/java/org/gatein/sso/agent/tomcat/ServletAccess.java index 15c909732..c21c51ffc 100644 --- a/agent/src/main/java/org/gatein/sso/agent/tomcat/ServletAccess.java +++ b/auth-callback/src/main/java/org/gatein/sso/agent/tomcat/ServletAccess.java @@ -22,8 +22,8 @@ package org.gatein.sso.agent.tomcat; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; /** * @author Marek Posolda diff --git a/agent/src/main/java/org/gatein/sso/agent/tomcat/ServletAccessValve.java b/auth-callback/src/main/java/org/gatein/sso/agent/tomcat/ServletAccessValve.java similarity index 92% rename from agent/src/main/java/org/gatein/sso/agent/tomcat/ServletAccessValve.java rename to auth-callback/src/main/java/org/gatein/sso/agent/tomcat/ServletAccessValve.java index 60c3a6157..675698c6e 100644 --- a/agent/src/main/java/org/gatein/sso/agent/tomcat/ServletAccessValve.java +++ b/auth-callback/src/main/java/org/gatein/sso/agent/tomcat/ServletAccessValve.java @@ -28,11 +28,11 @@ import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; -import javax.servlet.ServletException; +import jakarta.servlet.ServletException; import java.io.IOException; /** - * Valve for adding {@link javax.servlet.http.HttpServletRequest} and {@link javax.servlet.http.HttpServletResponse} into threadLocal + * Valve for adding {@link jakarta.servlet.http.HttpServletRequest} and {@link jakarta.servlet.http.HttpServletResponse} into threadLocal * so that it can be accessed from Login Modules during authentication. * * @author Marek Posolda diff --git a/integration/pom.xml b/integration/pom.xml index 22fbcafe7..42522f1d1 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -2,7 +2,6 @@ sso-parent org.exoplatform.gatein.sso - ../pom.xml 6.6.x-mips-SNAPSHOT 4.0.0 diff --git a/integration/src/main/java/org/gatein/sso/integration/SSODelegateFilter.java b/integration/src/main/java/org/gatein/sso/integration/SSODelegateFilter.java index 4107bab19..158980534 100644 --- a/integration/src/main/java/org/gatein/sso/integration/SSODelegateFilter.java +++ b/integration/src/main/java/org/gatein/sso/integration/SSODelegateFilter.java @@ -28,11 +28,11 @@ import org.exoplatform.services.log.Log; import org.gatein.sso.agent.filter.api.SSOInterceptor; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.Iterator; import java.util.Map; diff --git a/integration/src/main/java/org/gatein/sso/integration/SSODelegateValve.java b/integration/src/main/java/org/gatein/sso/integration/SSODelegateValve.java index 138999a33..c72eaa110 100644 --- a/integration/src/main/java/org/gatein/sso/integration/SSODelegateValve.java +++ b/integration/src/main/java/org/gatein/sso/integration/SSODelegateValve.java @@ -29,7 +29,7 @@ import javax.management.MBeanRegistration; import javax.management.MBeanServer; import javax.management.ObjectName; -import javax.servlet.ServletException; +import jakarta.servlet.ServletException; import org.apache.catalina.Contained; import org.apache.catalina.Container; @@ -47,7 +47,7 @@ * Delegates work to another valve configured through option 'delegateValveClassName'. It's possible to disable * delegation by boolean parameter 'ssoDelegationEnabled'. * - * Actually delegation will be enabled only for SSO scenario, which require integration with Tomcat valves (SAML, SPNEGO) + * Actually delegation will be enabled only for SSO scenario, which require integration with Tomcat valves (SAML) * * @author Marek Posolda */ @@ -64,7 +64,7 @@ public class SSODelegateValve implements Valve, Contained, MBeanRegistration, Li private String delegateValveClassName; // Delegate valve is not null only if we are in SSO mode and delegation is enabled - // Delegate will be either SAML or SPNEGO valve + // Delegate will be either SAML valve private Valve delegate; // This is not null only if delegation is disabled diff --git a/integration/src/main/java/org/gatein/sso/integration/SSOFilterIntegratorPlugin.java b/integration/src/main/java/org/gatein/sso/integration/SSOFilterIntegratorPlugin.java index ab02e356b..d926c0be5 100644 --- a/integration/src/main/java/org/gatein/sso/integration/SSOFilterIntegratorPlugin.java +++ b/integration/src/main/java/org/gatein/sso/integration/SSOFilterIntegratorPlugin.java @@ -37,8 +37,7 @@ * * @author Marek Posolda */ -public class SSOFilterIntegratorPlugin extends BaseComponentPlugin -{ +public class SSOFilterIntegratorPlugin extends BaseComponentPlugin { private final SSOInterceptor filter; private final boolean enabled; private final String filterMapping; diff --git a/integration/src/main/resources/conf/portal/configuration.xml b/integration/src/main/resources/conf/portal/configuration.xml deleted file mode 100644 index 7c8caa209..000000000 --- a/integration/src/main/resources/conf/portal/configuration.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - diff --git a/opensso/gatein-opensso-plugin/pom.xml b/opensso/gatein-opensso-plugin/pom.xml index 4b53cef97..434055cd8 100644 --- a/opensso/gatein-opensso-plugin/pom.xml +++ b/opensso/gatein-opensso-plugin/pom.xml @@ -2,7 +2,6 @@ org.exoplatform.gatein.sso sso-opensso-parent - ../pom.xml 6.6.x-mips-SNAPSHOT diff --git a/picketlink-saml/pom.xml b/picketlink-saml/pom.xml new file mode 100644 index 000000000..ed05211e4 --- /dev/null +++ b/picketlink-saml/pom.xml @@ -0,0 +1,383 @@ + + + sso-parent + org.exoplatform.gatein.sso + 6.6.x-mips-SNAPSHOT + + + 4.0.0 + sso-picketlink-saml + jar + GateIn SSO - Picketlink Overrides for SAML + + + 2.5.5.Final + 4.0.20.Final + 1.5.1 + 2.0.8.Final + 2.0.4 + 2.0.3.GA + + 1.0.0.Final + 1.0.1.Final + 1.0.1.Final + 2.0.3.Final + 1.0.2.Final + + true + + + + + + org.picketlink + picketlink-parent + ${org.picketlink.federation.version} + import + pom + + + org.picketlink + picketlink-jbas-common + ${org.picketlink.federation.version} + sources + + + org.picketlink + picketlink-common + sources + ${org.picketlink.federation.version} + + + * + * + + + + + org.picketlink + picketlink-config + sources + ${org.picketlink.federation.version} + + + * + * + + + + + org.picketlink + picketlink-federation + sources + ${org.picketlink.federation.version} + + + * + * + + + + + org.picketbox + picketbox + sources + ${org.picketbox.version} + + + * + * + + + + + + + org.jboss + jbossxb + ${org.jboss.jbossxb.version} + + + org.jboss.security + jbosssx + ${org.jboss.security.jbosssx.version} + + + org.jboss.security + jbossxacml + ${org.jboss.security.jbossxacml.version} + + + org.jboss.spec.javax.resource + jboss-connector-api_1.7_spec + ${org.jboss.spec.javax.resource.version} + + + org.jboss.spec.javax.security.jacc + jboss-jacc-api_1.5_spec + ${org.jboss.spec.javax.security.jacc.version} + + + org.jboss.spec.javax.servlet + jboss-servlet-api_3.1_spec + + + + + org.jboss.spec.javax.security.auth.message + jboss-jaspi-api_1.0_spec + ${org.jboss.spec.javax.security.auth.message.version} + + + org.jboss.spec.javax.xml.ws + jboss-jaxws-api_2.2_spec + ${org.jboss.spec.javax.xml.ws.version} + + + org.jboss.spec.javax.xml.soap + jboss-saaj-api_1.4_spec + ${org.jboss.spec.javax.xml.soap.version} + + + org.apache.santuario + xmlsec + ${org.apache.santuario.version} + + + javax.servlet + servlet-api + + + + + + + + + ${project.groupId} + sso-auth-callback + + + + org.apache.tomcat + tomcat-catalina + + + + org.picketlink + picketlink-common + sources + + + org.picketlink + picketlink-config + sources + + + org.picketlink + picketlink-federation + sources + + + org.picketlink + picketlink-jbas-common + sources + + + org.picketbox + picketbox + sources + + + + org.hibernate + hibernate-core + + + javax.annotation + jsr250-api + + + javax.enterprise + cdi-api + + + + org.jboss.spec.javax.resource + jboss-connector-api_1.7_spec + + + org.jboss.spec.javax.security.jacc + jboss-jacc-api_1.5_spec + + + org.jboss.spec.javax.security.auth.message + jboss-jaspi-api_1.0_spec + + + org.jboss.spec.javax.xml.ws + jboss-jaxws-api_2.2_spec + + + org.jboss.spec.javax.xml.soap + jboss-saaj-api_1.4_spec + + + + org.jboss.logging + jboss-logging + + + org.jboss + jbossxb + + + org.jboss.security + jbossxacml + + + org.jboss.security + jbosssx + + + org.apache.santuario + xmlsec + + + + org.picketlink + picketlink-idm-impl + + + + + ${project.artifactId} + + + src/main/java + + + src/main/resources + + + target/picketlink + + + + + src/test/java + + + src/test/resources + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack + generate-sources + + unpack + + + + + org.picketlink + picketlink-common + sources + false + + + org.picketlink + picketlink-config + sources + ${org.picketlink.federation.version} + false + + + org.picketlink + picketlink-federation + sources + ${org.picketlink.federation.version} + false + + + org.picketlink + picketlink-jbas-common + sources + ${org.picketlink.federation.version} + false + + + org.picketbox + picketbox + sources + ${org.picketbox.version} + false + + + ${project.build.directory}/picketlink + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + generate-sources + + add-source + + + + ${project.build.directory}/picketlink + + + + + + + org.apache.maven.plugins + maven-patch-plugin + + ${project.build.directory} + + + + java.security.acl.Group-patch + + + ${basedir}/src/main/patches/java.security.acl.Group.patch + + ${project.build.directory}/java.security.acl.Group-patches-applied.txt + skip + + process-resources + + apply + + + + javax.servlet-patch + + ${basedir}/src/main/patches/javax.servlet.patch + + ${project.build.directory}/javax.servlet-patches-applied.txt + + process-resources + + apply + + + + + + + diff --git a/picketlink-saml/src/main/java/org/jboss/security/Group.java b/picketlink-saml/src/main/java/org/jboss/security/Group.java new file mode 100644 index 000000000..d0de68131 --- /dev/null +++ b/picketlink-saml/src/main/java/org/jboss/security/Group.java @@ -0,0 +1,16 @@ +package org.jboss.security; + +import java.security.Principal; +import java.util.Enumeration; + +public interface Group extends Principal { + + public boolean addMember(Principal user); + + public boolean removeMember(Principal user); + + public boolean isMember(Principal member); + + public Enumeration members(); + +} diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/servlets/SOAPSAMLXACMLServlet.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/servlets/SOAPSAMLXACMLServlet.java new file mode 100644 index 000000000..4c4058324 --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/servlets/SOAPSAMLXACMLServlet.java @@ -0,0 +1,32 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file 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.picketlink.identity.federation.bindings.servlets; + +/** + * Servlet that can read SOAP 1.1 messages that contain an XACML query in saml payload + * + * @author Anil.Saldhana@redhat.com + * @since Jan 27, 2009 + */ +public class SOAPSAMLXACMLServlet extends org.picketlink.identity.federation.web.servlets.saml.SOAPSAMLXACMLServlet { + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/servlets/SecurityActions.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/servlets/SecurityActions.java new file mode 100644 index 000000000..615b2e1f6 --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/servlets/SecurityActions.java @@ -0,0 +1,46 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file 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.picketlink.identity.federation.bindings.servlets; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * + * @author Anil.Saldhana@redhat.com + * @since Mar 17, 2009 + */ +class SecurityActions { + static void setSystemProperty(final String key, final String value) { + if (System.getSecurityManager() != null) { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + System.setProperty(key, value); + return null; + } + }); + } else { + System.setProperty(key, value); + } + } +} \ No newline at end of file diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/stspool/STSClientPoolFactory.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/stspool/STSClientPoolFactory.java new file mode 100644 index 000000000..b255fea34 --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/stspool/STSClientPoolFactory.java @@ -0,0 +1,146 @@ +/* + * JBoss, Home of Professional Open Source + * + * Copyright 2013 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.picketlink.identity.federation.bindings.stspool; + +import org.picketlink.identity.federation.core.wstrust.STSClient; +import org.picketlink.identity.federation.core.wstrust.STSClientConfig; +import org.picketlink.identity.federation.core.wstrust.STSClientCreationCallBack; +import org.picketlink.identity.federation.core.wstrust.STSClientPool; +import org.picketlink.identity.federation.core.wstrust.STSClientFactory; + + +/** + * Simple factory for creating {@link STSClient}s. + * + * @author Peter Skopek + */ +public final class STSClientPoolFactory implements STSClientPool { + + private STSClientPoolInternal stsClientPoolInternal; + + private STSClientPoolFactory() { + stsClientPoolInternal = new STSClientPoolInternal(); + } + + private static class LazySTSClientFactory { + private static final STSClientPoolFactory INSTANCE = new STSClientPoolFactory(); + } + + /** + * Get instance of {@link STSClientPool}. + * + * @return {@link STSClientPool} instance + */ + public static STSClientPool getPoolInstance() { + STSClientPoolFactory cf = LazySTSClientFactory.INSTANCE; + STSClientFactory.setInstance(cf); + return cf; + } + + /** + * This method initializes sub pool of clients by given configuration data and returns client from that pool. + * + * When pooling is disabled it does nothing. + * + * @param config to construct the pool of clients + */ + public void createPool(final STSClientConfig config) { + createPool(STSClientPoolInternal.DEFAULT_NUM_STS_CLIENTS, config); + } + + /** + * This method initializes sub pool of clients by given configuration data and returns client from that pool. + * initialNumberOfClients is used to initialize the pool for the given number of clients. + * + * When pooling is disabled it does nothing. + * + * @param initialNumberOfClients initial number of clients in the pool + * @param config to construct the pool of clients + */ + public void createPool(int initialNumberOfClients, final STSClientConfig config) { + stsClientPoolInternal.initialize(initialNumberOfClients, config); + } + + /** + * This method initializes sub pool of clients by given configuration data. + * initialNumberOfClients is used to initialize the pool for the given number of clients. + * + * When pooling is disabled it does nothing. + * + * @param initialNumberOfClients initial number of clients in the pool + * @param callBack which provide configuration + */ + + public void createPool(int initialNumberOfClients, final STSClientCreationCallBack callBack) { + stsClientPoolInternal.initialize(initialNumberOfClients, callBack); + } + + /** + * Destroys client sub pool denoted by given config. + * + * @param config {@link STSClientConfiguration} to find client sub pool to destroy + */ + public void destroyPool(final STSClientConfig config) { + stsClientPoolInternal.destroy(config); + } + + + /** + * Destroy all the pools attached to given module name. + * + * @param moduleName module name to destroy pools or "" or null to destroy default module's pools. + */ + public void destroyPool(final String moduleName) { + stsClientPoolInternal.destroy(moduleName); + } + + /** + * Returns given {@link STSClient} back to the sub pool of clients. + * Sub pool is determined automatically from client configuration. + * + * @param {@link STSClient} to return back to the sub pool of clients + */ + public void returnClient(final STSClient stsClient) { + stsClientPoolInternal.putIn(stsClient); + } + + /** + * Get STSClient from sub pool denoted by config. + * @param config {@link STSClientConfiguration} to find client sub pool + * @return {@link STSClient} from the sub pool of clients + */ + public STSClient getClient(final STSClientConfig config) { + STSClient client = stsClientPoolInternal.takeOut(config); + if (client == null) { + // non pooled client + return new STSClient(config); + } + return client; + } + + /** + * Checks whether given config has already sub pool of clients created. + * + * @param config {@link STSClientConfiguration} to find client sub pool + * @return true if config was already used as sub pool key + */ + public boolean configExists(final STSClientConfig config) { + return stsClientPoolInternal.isConfigInitialized(config); + } + +} diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/stspool/STSClientPoolInternal.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/stspool/STSClientPoolInternal.java new file mode 100644 index 000000000..c671d23d6 --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/stspool/STSClientPoolInternal.java @@ -0,0 +1,292 @@ +/* + * JBoss, Home of Professional Open Source + * + * Copyright 2013 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.picketlink.identity.federation.bindings.stspool; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Hashtable; +import org.picketlink.common.PicketLinkLogger; +import org.picketlink.common.PicketLinkLoggerFactory; +import org.picketlink.identity.federation.bindings.util.ModuleUtils; +import org.picketlink.identity.federation.core.wstrust.STSClient; +import org.picketlink.identity.federation.core.wstrust.STSClientConfig; +import org.picketlink.identity.federation.core.wstrust.STSClientConfigKeyProvider; +import org.picketlink.identity.federation.core.wstrust.STSClientCreationCallBack; + +/** + * Simple pool of {@link STSClient} classes. + * This class is not intended to be used directly by user code. Use {@link STSClientPoolFactory} class instead. + * + * @author Peter Skopek : pskopek at (redhat.com) + * + */ +class STSClientPoolInternal { + + private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger(); + static int DEFAULT_NUM_STS_CLIENTS = 10; + + private Hashtable> free = new Hashtable>(); + private Hashtable> inUse = new Hashtable>(); + private Hashtable configs = new Hashtable(); + + STSClientPoolInternal() { + } + + void initialize(int numberOfSTSClients, STSClientConfig stsClientConfig) { + internalInitialize(numberOfSTSClients, stsClientConfig, null); + } + + void initialize(STSClientConfig stsClientConfig) { + internalInitialize(DEFAULT_NUM_STS_CLIENTS, stsClientConfig, null); + } + + + void initialize(int numberOfSTSClients, STSClientCreationCallBack clientCreationCallBack) { + internalInitialize(numberOfSTSClients, null, clientCreationCallBack); + } + + private synchronized void internalInitialize(final int numberOfSTSClients, STSClientConfig stsClientConfig, STSClientCreationCallBack clientCreationCallBack) { + + if (numberOfSTSClients <= 0) { + return; + } + + + String key = null; + if (clientCreationCallBack != null) { + key = substituteKey(clientCreationCallBack.getKey()); + } else { + key = key(stsClientConfig); + } + + if (!configs.containsKey(key)) { + ArrayList clients = new ArrayList(numberOfSTSClients); + if (clientCreationCallBack != null) { + for (int i = 0; i < numberOfSTSClients; i++) { + clients.add(clientCreationCallBack.createClient()); + } + } else { + for (int i = 0; i < numberOfSTSClients; i++) { + clients.add(new STSClient(stsClientConfig)); + } + } + STSConfigData configData = new STSConfigData(); + configData.initialNumberOfClients = numberOfSTSClients; + if (clientCreationCallBack != null) { + configData.config = null; + configData.callBack = clientCreationCallBack; + } else { + configData.config = stsClientConfig; + configData.callBack = null; + } + configs.put(key, configData); + free.put(key, clients); + inUse.put(key, new ArrayList(numberOfSTSClients)); + } else { + // free pool already contains given key: + throw logger.freePoolAlreadyContainsGivenKey(key); + } + + } + + synchronized void destroy(STSClientConfig stsClientConfig) { + String key = key(stsClientConfig); + free.remove(key); + inUse.remove(key); + configs.remove(key); + } + + synchronized void destroy(String moduleName) { + String module = moduleName; + if (moduleName == null || moduleName.isEmpty()) { + module = ModuleUtils.getCurrentModuleId(); + } + int removed = 0; + removeByPrefix(module, free); + removeByPrefix(module, inUse); + removed += removeByPrefix(module, configs); + if (removed == 0) { + // fallback to modified prefix + module = "deployment." + module; + removeByPrefix(module, free); + removeByPrefix(module, inUse); + removeByPrefix(module, configs); + } + } + + + STSClient takeOut(STSClientConfig stsClientConfig) { + String key = key(stsClientConfig); + return takeOutInternal(key); + } + + + STSClient takeOut(String key) { + String substKey = substituteKey(key); + STSClient client = takeOutInternal(substKey); + if (client == null) { + STSConfigData configData = configs.get(substKey); + if (configData == null) { + throw logger.cannotGetSTSConfigByKey(substKey); + } + if (configData.callBack != null) { + internalInitialize(DEFAULT_NUM_STS_CLIENTS, null, configData.callBack); + } + else if (configData.config != null) { + internalInitialize(DEFAULT_NUM_STS_CLIENTS, configData.config, configData.callBack); + } + client = takeOutInternal(substKey); + } + return client; + } + + boolean isConfigInitialized(STSClientConfig stsClientConfig) { + if (stsClientConfig == null) { + return false; + } + STSConfigData configData = configs.get(key(stsClientConfig)); + return (configData != null); + } + + boolean isConfigInitialized(String key) { + if (key == null) { + return false; + } + STSConfigData configData = configs.get(substituteKey(key)); + return (configData != null); + } + + void putIn(STSClientConfigKeyProvider keyProvider, STSClient client) { + putInInternal(substituteKey(keyProvider.getSTSClientConfigKey()), client); + } + + void putIn(String key, STSClient client) { + putInInternal(substituteKey(key), client); + } + + void putIn(STSClient client) { + putInInternal(substituteKey(client.getSTSClientConfigKey()), client); + } + + private synchronized STSClient takeOutInternal(String key) { + // no key substitution + ArrayList clients = free.get(key); + if (clients != null) { + int size = clients.size(); + STSClient client; + if (size > 0) { + client = clients.remove(size - 1); + } else { + addClients(key); + client = clients.remove(clients.size() -1); + } + markInUse(key, client); + return client; + } + return null; + } + + private void addClients(String key) { + // no key substitution + STSConfigData configData = configs.get(key); + if (configData != null) { + ArrayList freeClientPool = free.get(key); + if (freeClientPool != null) { + ArrayList clients = new ArrayList(configData.initialNumberOfClients); + if (configData.config != null) { + for (int i = 0; i < configData.initialNumberOfClients; i++) { + clients.add(new STSClient(configData.config)); + } + } else { + for (int i = 0; i < configData.initialNumberOfClients; i++) { + clients.add(configData.callBack.createClient()); + } + } + freeClientPool.addAll(clients); + } else { + // cannot get free client pool key: + throw logger.cannotGetFreeClientPoolKey(key); + } + } else { + // cannot get STS config by key: + throw logger.cannotGetSTSConfigByKey(key); + } + } + + private void markInUse(String key, STSClient client) { + // no key substitution + ArrayList usedClients = inUse.get(key); + if (usedClients != null) { + usedClients.add(client); + } else { + // cannot get used clients by key: + logger.cannotGetUsedClientsByKey(key); + } + } + + private synchronized void putInInternal(String key, STSClient client) { + // no key substitution + STSConfigData configData = configs.get(key); + if (configData == null) { + // attempt to return client not from pool, we can silently ignore it + return; + } + + ArrayList freeClients = free.get(key); + ArrayList usedClients = inUse.get(key); + + if (usedClients != null && !usedClients.remove(client)) { + // removing non existing client from used clients by key: + throw logger.removingNonExistingClientFromUsedClientsByKey(key); + } + + freeClients.add(client); + + } + + private String key(STSClientConfig stsClientConfig) { + return substituteKey(stsClientConfig.getSTSClientConfigKey()); + } + + private String substituteKey(String originalKey) { + if (originalKey != null && originalKey.indexOf(STSClientConfig.SUBSTITUTE_MODULE) != -1) { + return originalKey.replaceAll("\\Q" + STSClientConfig.SUBSTITUTE_MODULE + "\\E", ModuleUtils.getCurrentModuleId()); + } + return originalKey; + } + + private int removeByPrefix(String prefix, Hashtable hashTbl) { + int num = 0; + Enumeration keys = hashTbl.keys(); + while(keys.hasMoreElements()) { + String k = keys.nextElement(); + if (k.startsWith(prefix)) { + num++; + hashTbl.remove(k); + } + } + return num; + } + +} + +class STSConfigData { + STSClientConfig config; + STSClientCreationCallBack callBack; + int initialNumberOfClients = STSClientPoolInternal.DEFAULT_NUM_STS_CLIENTS; +} diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/AbstractGenericHeaderAuthenticator.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/AbstractGenericHeaderAuthenticator.java new file mode 100644 index 000000000..5f2008726 --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/AbstractGenericHeaderAuthenticator.java @@ -0,0 +1,235 @@ +/* + * JBoss, Home of Professional Open Source + * + * Copyright 2013 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.picketlink.identity.federation.bindings.tomcat; + +import java.io.IOException; +import java.security.Principal; +import java.util.StringTokenizer; + +import org.apache.catalina.Realm; +import org.apache.catalina.Session; +import org.apache.catalina.authenticator.Constants; +import org.apache.catalina.authenticator.FormAuthenticator; +import org.apache.catalina.connector.Request; +import org.apache.tomcat.util.descriptor.web.LoginConfig; +import org.picketlink.common.PicketLinkLogger; +import org.picketlink.common.PicketLinkLoggerFactory; + +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * JBAS-2283: Provide custom header based authentication support + * + * Header Authenticator that deals with userid from the request header Requires two attributes configured on the Tomcat Service + * - one for the http header denoting the authenticated identity and the other is the SESSION cookie + * + * @author Anil Saldhana + * @author Stefan Guilhen + * @version $Revision$ + * @since Sep 11, 2006 + */ +public abstract class AbstractGenericHeaderAuthenticator extends FormAuthenticator { + + protected static final PicketLinkLogger log = PicketLinkLoggerFactory.getLogger(); + + // JBAS-4804: AbstractGenericHeaderAuthenticator injection of ssoid and sessioncookie name. + private String httpHeaderForSSOAuth = null; + + private String sessionCookieForSSOAuth = null; + + /** + *

+ * Obtain the value of the httpHeaderForSSOAuth attribute. This attribute is used to indicate the request + * header ids that have to be checked in order to retrieve the SSO identity set by a third party security system. + *

+ * + * @return a String containing the value of the httpHeaderForSSOAuth attribute. + */ + public String getHttpHeaderForSSOAuth() { + return httpHeaderForSSOAuth; + } + + /** + *

+ * Set the value of the httpHeaderForSSOAuth attribute. This attribute is used to indicate the request header + * ids that have to be checked in order to retrieve the SSO identity set by a third party security system. + *

+ * + * @param httpHeaderForSSOAuth a String containing the value of the httpHeaderForSSOAuth + * attribute. + */ + public void setHttpHeaderForSSOAuth(String httpHeaderForSSOAuth) { + this.httpHeaderForSSOAuth = httpHeaderForSSOAuth; + } + + /** + *

+ * Obtain the value of the sessionCookieForSSOAuth attribute. This attribute is used to indicate the names of + * the SSO cookies that may be present in the request object. + *

+ * + * @return a String containing the names (separated by a ',') of the SSO cookies that may have + * been set by a third party security system in the request. + */ + public String getSessionCookieForSSOAuth() { + return sessionCookieForSSOAuth; + } + + /** + *

+ * Set the value of the sessionCookieForSSOAuth attribute. This attribute is used to indicate the names of the + * SSO cookies that may be present in the request object. + *

+ * + * @param sessionCookieForSSOAuth a String containing the names (separated by a ',') of the SSO + * cookies that may have been set by a third party security system in the request. + */ + public void setSessionCookieForSSOAuth(String sessionCookieForSSOAuth) { + this.sessionCookieForSSOAuth = sessionCookieForSSOAuth; + } + + /** + *

+ * Creates an instance of AbstractGenericHeaderAuthenticator. + *

+ */ + public AbstractGenericHeaderAuthenticator() { + super(); + } + + public boolean performAuthentication(Request request, HttpServletResponse response, LoginConfig config) throws IOException { + boolean trace = log.isTraceEnabled(); + if (log.isTraceEnabled()) { + log.trace("Authenticating user"); + } + + Principal principal = request.getUserPrincipal(); + if (principal != null) { + if (trace) + log.trace("Already authenticated '" + principal.getName() + "'"); + return true; + } + + Realm realm = context.getRealm(); + Session session = request.getSessionInternal(true); + + String username = getUserId(request); + String password = getSessionCookie(request); + + // Check if there is sso id as well as sessionkey + if (username == null || password == null) { + if (log.isTraceEnabled()) { + log.trace("Username is null or password(sessionkey) is null:fallback to form auth"); + } + return super.authenticate(request, response); + } + principal = realm.authenticate(username, password); + + if (principal == null) { + forwardToErrorPage(request, response, config); + return false; + } + + session.setNote(Constants.SESS_USERNAME_NOTE, username); + session.setNote(Constants.SESS_PASSWORD_NOTE, password); + request.setUserPrincipal(principal); + + register(request, response, principal, HttpServletRequest.FORM_AUTH, username, password); + return true; + } + + /** + * Get the username from the request header + * + * @param request + * @return + */ + protected String getUserId(Request request) { + String ssoid = null; + // We can have a comma-separated ids + String ids = this.httpHeaderForSSOAuth; + + if (ids == null || ids.length() == 0) + throw new IllegalStateException("Http headers configuration in tomcat service missing"); + + StringTokenizer st = new StringTokenizer(ids, ","); + while (st.hasMoreTokens()) { + ssoid = request.getHeader(st.nextToken()); + if (ssoid != null) + break; + } + if (log.isTraceEnabled()) { + log.trace("SSOID-" + ssoid); + } + return ssoid; + } + + /** + * Obtain the session cookie from the request + * + * @param request + * @return + */ + protected String getSessionCookie(Request request) { + Cookie[] cookies = request.getCookies(); + log.trace("Cookies:" + cookies); + int numCookies = cookies != null ? cookies.length : 0; + + // We can have comma-separated ids + String ids = sessionCookieForSSOAuth; + + if (ids == null || ids.length() == 0) + throw new IllegalStateException("Session cookies configuration in tomcat service missing"); + + StringTokenizer st = new StringTokenizer(ids, ","); + while (st.hasMoreTokens()) { + String cookieToken = st.nextToken(); + String val = getCookieValue(cookies, numCookies, cookieToken); + if (val != null) + return val; + } + if (log.isTraceEnabled()) { + log.trace("Session Cookie not found"); + } + return null; + } + + /** + * Get the value of a cookie if the name matches the token + * + * @param cookies array of cookies + * @param numCookies number of cookies in the array + * @param token Key + * @return value of cookie + */ + protected String getCookieValue(Cookie[] cookies, int numCookies, String token) { + for (int i = 0; i < numCookies; i++) { + Cookie cookie = cookies[i]; + log.trace("Matching cookieToken:" + token + " with cookie name=" + cookie.getName()); + if (token.equals(cookie.getName())) { + if (log.isTraceEnabled()) { + log.trace("Cookie-" + token + " value=" + cookie.getValue()); + } + return cookie.getValue(); + } + } + return null; + } +} diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/AbstractPicketLinkAuthenticator.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/AbstractPicketLinkAuthenticator.java new file mode 100644 index 000000000..48d4074a1 --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/AbstractPicketLinkAuthenticator.java @@ -0,0 +1,202 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file 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.picketlink.identity.federation.bindings.tomcat; + +import java.io.IOException; +import java.security.AccessController; +import java.security.Principal; +import java.security.PrivilegedAction; +import java.util.Set; +import java.util.UUID; + +import javax.security.auth.Subject; + +import org.apache.catalina.Realm; +import org.apache.catalina.Session; +import org.apache.catalina.authenticator.AuthenticatorBase; +import org.apache.catalina.authenticator.Constants; +import org.apache.catalina.connector.Request; +import org.apache.catalina.connector.Response; +import org.apache.tomcat.util.descriptor.web.LoginConfig; +import org.picketlink.common.PicketLinkLogger; +import org.picketlink.common.PicketLinkLoggerFactory; + +/** + *

An authenticator that delegates actual authentication to a realm, and in turn to a security manager, by presenting a + * "conventional" identity. The security manager must accept the conventional identity and generate the real identity for the + * authenticated principal.

+ *

Subclasses should override some methods to provide especific implementation according with the binding/environment.

+ * + * @author Ovidiu Feodorov + * @author Anil.Saldhana@redhat.com + * @author Pedro Silva + * + */ +public abstract class AbstractPicketLinkAuthenticator extends AuthenticatorBase { + + protected static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger(); + + /** + * This is the auth method used in the register method + */ + protected String authMethod = "SECURITY_DOMAIN"; + + /** + * The authenticator may not be aware of the user name until after the underlying security exercise is complete. The Subject + * will have the proper user name. Hence we may need to perform an additional authentication now with the user name we have + * obtained. + */ + protected boolean needSubjectPrincipalSubstitution = true; + + protected SubjectSecurityInteraction subjectInteraction = null; + + protected String subjectInteractionClassName = "org.picketlink.identity.federation.bindings.jboss.subject.PicketLinkJBossSubjectInteraction"; + + /** + * Set the auth method via WEB-INF/context.xml (JBoss AS) + * + * @param authMethod + */ + public void setAuthMethod(String authMethod) { + this.authMethod = authMethod; + } + + public void setNeedSubjectPrincipalSubstitution(String needSubjectPrincipalSubstitutionVal) { + this.needSubjectPrincipalSubstitution = Boolean.valueOf(needSubjectPrincipalSubstitutionVal); + } + + /** + * Set this if you want to override the default {@link SubjectSecurityInteraction} + * + * @param subjectRetrieverClassName + */ + public void setSubjectInteractionClassName(String subjectRetrieverClassName) { + this.subjectInteractionClassName = subjectRetrieverClassName; + } + + /** + *

Actually performs the authentication. Subclasses should call this method when implementing the AuthenticatorBase.authenticate method.

+ *

This method was created to allow different signatures for the AuthenticatorBase.authenticate method according with the catalina version.

+ * + * @param request + * @param response + * @param loginConfig + * @return + * @throws IOException + */ + protected boolean performAuthentication(Request request, Response response, LoginConfig loginConfig) throws IOException { + logger.trace("Authenticating user"); + + Principal principal = request.getUserPrincipal(); + if (principal != null) { + logger.trace("Already authenticated '" + principal.getName() + "'"); + return true; + } + + Session session = request.getSessionInternal(true); + String userName = UUID.randomUUID().toString(); + String password = userName; + Realm realm = context.getRealm(); + + principal = realm.authenticate(userName, password); + Principal originalPrincipal = principal; + + if (principal != null) { + if (needSubjectPrincipalSubstitution) { + principal = getSubjectPrincipal(); + if (principal == null) + throw new RuntimeException("Principal from subject is null"); + principal = realm.authenticate(principal.getName(), password); + } + session.setNote(Constants.SESS_USERNAME_NOTE, principal.getName()); + session.setNote(Constants.SESS_PASSWORD_NOTE, password); + request.setUserPrincipal(principal); + doRegister(request, response, principal, password); + if (originalPrincipal != null && needSubjectPrincipalSubstitution) { + subjectInteraction.cleanup(originalPrincipal); + } + return true; + } + + return false; + } + + /** + *

Subclasses should override this method to register an authenticated Principal.

+ * + * @param request + * @param response + * @param principal + * @param password + */ + protected abstract void doRegister(Request request, Response response, Principal principal, String password); + + protected Principal getSubjectPrincipal() { + if (subjectInteraction == null) { + Class clazz = loadClass(getClass(), subjectInteractionClassName); + try { + subjectInteraction = (SubjectSecurityInteraction) clazz.newInstance(); + subjectInteraction.setSecurityDomain(context.getRealm().getContainer().getName()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + Subject subject = subjectInteraction.get(); + if (subject != null) { + Set principals = subject.getPrincipals(); + if (!principals.isEmpty()) { + return subject.getPrincipals().iterator().next(); + } + } + return null; + } + + Class loadClass(final Class theClass, final String fqn) { + return AccessController.doPrivileged(new PrivilegedAction>() { + public Class run() { + ClassLoader classLoader = theClass.getClassLoader(); + + Class clazz = loadClass(classLoader, fqn); + if (clazz == null) { + classLoader = Thread.currentThread().getContextClassLoader(); + clazz = loadClass(classLoader, fqn); + } + return clazz; + } + }); + } + + Class loadClass(final ClassLoader cl, final String fqn) { + return AccessController.doPrivileged(new PrivilegedAction>() { + public Class run() { + try { + return cl.loadClass(fqn); + } catch (ClassNotFoundException e) { + } + return null; + } + }); + } + +} \ No newline at end of file diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/SSLValve.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/SSLValve.java new file mode 100644 index 000000000..863bb30e0 --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/SSLValve.java @@ -0,0 +1,103 @@ +/* + * JBoss, Home of Professional Open Source + * + * Copyright 2013 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.picketlink.identity.federation.bindings.tomcat; + +import java.io.IOException; +import java.io.ByteArrayInputStream; + +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; + +import jakarta.servlet.ServletException; + +import org.apache.catalina.valves.ValveBase; +import org.apache.catalina.connector.Request; +import org.apache.catalina.connector.Response; +import org.picketlink.common.PicketLinkLogger; +import org.picketlink.common.PicketLinkLoggerFactory; + +/** + * Valve to fill the SSL information in the request + * mod_header is used to fill the headers and the valve + * will fill the parameters of the request. + * In httpd.conf add the following: + * + * + * RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s" + * RequestHeader set SSL_CIPHER "%{SSL_CIPHER}s" + * RequestHeader set SSL_SESSION_ID "%{SSL_SESSION_ID}s" + * RequestHeader set SSL_CIPHER_USEKEYSIZE "%{SSL_CIPHER_USEKEYSIZE}s" + * + * + * Visit: https://community.jboss.org/wiki/SSLModproxyForwarding + * + * @author Jean-Frederic Clere + * @author Anil Saldhana + * @since November 07, 2013 + */ +public class SSLValve extends ValveBase{ + protected static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger(); + + @Override + public void invoke(Request request, Response response) throws IOException, ServletException { + + // mod_header converts the '\n' into ' ' so we have to rebuild the client certificate + String strcert0 = request.getHeader("ssl_client_cert"); + + if (isNotNull(strcert0)) { + + String strcert1 = strcert0.replace(' ', '\n'); + String strcert2 = strcert1.substring(28, strcert1.length()-26); + String strcert3 = new String("-----BEGIN CERTIFICATE-----\n"); + String strcert4 = strcert3.concat(strcert2); + String strcerts = strcert4.concat("\n-----END CERTIFICATE-----\n"); + + // ByteArrayInputStream bais = new ByteArrayInputStream(strcerts.getBytes("UTF-8")); + ByteArrayInputStream bais = new ByteArrayInputStream(strcerts.getBytes()); + X509Certificate jsseCerts[] = null; + try { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + X509Certificate cert = (X509Certificate) cf.generateCertificate(bais); + jsseCerts = new X509Certificate[1]; + jsseCerts[0] = cert; + } catch (CertificateException certificateException) { + logger.error("SSLValve failed :" + strcerts); + logger.error(certificateException); + } + request.setAttribute("jakarta.servlet.request.X509Certificate", jsseCerts); + } + strcert0 = request.getHeader("ssl_cipher"); + if (isNotNull(strcert0)) { + request.setAttribute("jakarta.servlet.request.cipher_suite", strcert0); + } + strcert0 = request.getHeader("ssl_session_id"); + if (isNotNull(strcert0)) { + request.setAttribute("jakarta.servlet.request.ssl_session", strcert0); + } + strcert0 = request.getHeader("ssl_cipher_usekeysize"); + if (isNotNull(strcert0)) { + request.setAttribute("jakarta.servlet.request.key_size", strcert0); + } + getNext().invoke(request, response); + } + + private boolean isNotNull(String str) { + return str != null && !"".equals(str.trim()); + } +} \ No newline at end of file diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/SecurityActions.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/SecurityActions.java new file mode 100644 index 000000000..9e5cb808d --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/SecurityActions.java @@ -0,0 +1,122 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file 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.picketlink.identity.federation.bindings.tomcat; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * + * @author Anil.Saldhana@redhat.com + * @since Dec 9, 2008 + */ +class SecurityActions { + + /** + *

+ * Loads a {@link Class} using the fullQualifiedName supplied. This method tries first to load from the + * specified {@link Class}, if not found it will try to load from using TCL. + *

+ * + * @param theClass + * @param fullQualifiedName + * @return + */ + static Class loadClass(final Class theClass, final String fullQualifiedName) { + SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + return AccessController.doPrivileged(new PrivilegedAction>() { + public Class run() { + ClassLoader classLoader = theClass.getClassLoader(); + + Class clazz = loadClass(classLoader, fullQualifiedName); + if (clazz == null) { + classLoader = Thread.currentThread().getContextClassLoader(); + clazz = loadClass(classLoader, fullQualifiedName); + } + return clazz; + } + }); + } else { + ClassLoader classLoader = theClass.getClassLoader(); + + Class clazz = loadClass(classLoader, fullQualifiedName); + if (clazz == null) { + classLoader = Thread.currentThread().getContextClassLoader(); + clazz = loadClass(classLoader, fullQualifiedName); + } + return clazz; + } + } + + /** + *

+ * Loads a class from the specified {@link ClassLoader} using the fullQualifiedName supplied. + *

+ * + * @param classLoader + * @param fullQualifiedName + * @return + */ + static Class loadClass(final ClassLoader classLoader, final String fullQualifiedName) { + SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + return AccessController.doPrivileged(new PrivilegedAction>() { + public Class run() { + try { + return classLoader.loadClass(fullQualifiedName); + } catch (ClassNotFoundException e) { + } + return null; + } + }); + } else { + try { + return classLoader.loadClass(fullQualifiedName); + } catch (ClassNotFoundException e) { + } + return null; + } + } + + /** + * Get a system property + * + * @param key the key for the property + * @param defaultValue A default value to return if the property is not set (Can be null) + * @return + */ + static String getProperty(final String key, final String defaultValue) { + if (System.getSecurityManager() != null) { + return AccessController.doPrivileged(new PrivilegedAction() { + public String run() { + return System.getProperty(key, defaultValue); + } + }); + } else { + return System.getProperty(key, defaultValue); + } + } +} \ No newline at end of file diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/SubjectSecurityInteraction.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/SubjectSecurityInteraction.java new file mode 100644 index 000000000..5cb5a26ef --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/SubjectSecurityInteraction.java @@ -0,0 +1,56 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file 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.picketlink.identity.federation.bindings.tomcat; + +import java.security.Principal; + +import javax.security.auth.Subject; + +/** + * Interface to retrieve a subject + * + * @author Anil.Saldhana@redhat.com + * @since Sep 13, 2011 + */ +public interface SubjectSecurityInteraction { + /** + * Obtain a subject based on implementation + * + * @return + */ + Subject get(); + + /** + * Clean up the {@link Principal} from the security cache + * + * @param principal + * @return + */ + boolean cleanup(Principal principal); + + /** + *

Sets the security domain name

+ * + * @param securityDomain + */ + void setSecurityDomain(String securityDomain); +} \ No newline at end of file diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/TomcatAttributeManager.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/TomcatAttributeManager.java new file mode 100644 index 000000000..00470c117 --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/TomcatAttributeManager.java @@ -0,0 +1,44 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file 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.picketlink.identity.federation.bindings.tomcat; + +import java.security.Principal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.picketlink.identity.federation.core.interfaces.AttributeManager; + +/** + * An implementation of attribute manager to get attributes of an identity + * + * @author Anil.Saldhana@redhat.com + * @since Aug 31, 2009 + */ +public class TomcatAttributeManager implements AttributeManager { + /** + * @see AttributeManager#getAttributes(Principal, List) + */ + public Map getAttributes(Principal userPrincipal, List attributeKeys) { + return new HashMap(); + } +} \ No newline at end of file diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/TomcatRoleGenerator.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/TomcatRoleGenerator.java new file mode 100644 index 000000000..112d9338f --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/TomcatRoleGenerator.java @@ -0,0 +1,73 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file 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.picketlink.identity.federation.bindings.tomcat; + +import java.security.Principal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.apache.catalina.Role; +import org.apache.catalina.User; +import org.apache.catalina.realm.GenericPrincipal; +import org.picketlink.common.PicketLinkLogger; +import org.picketlink.common.PicketLinkLoggerFactory; +import org.picketlink.identity.federation.core.interfaces.RoleGenerator; + +/** + * Generate roles from Tomcat Principal + * + * @author Anil.Saldhana@redhat.com + * @since Jan 21, 2009 + */ +public class TomcatRoleGenerator implements RoleGenerator { + + private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger(); + + /** + * @see RoleGenerator#generateRoles(Principal) + * @throws IllegalArgumentException if principal is not of type GenericPrincipal or User + */ + public List generateRoles(Principal principal) { + String className = principal.getClass().getCanonicalName(); + + if (principal instanceof GenericPrincipal == false && principal instanceof User == false) + throw logger.wrongTypeError("principal is not tomcat principal:" + className); + List userRoles = new ArrayList(); + + if (principal instanceof GenericPrincipal) { + GenericPrincipal gp = (GenericPrincipal) principal; + String[] roles = gp.getRoles(); + if (roles.length > 0) + userRoles.addAll(Arrays.asList(roles)); + } else if (principal instanceof User) { + User tomcatUser = (User) principal; + Iterator iter = tomcatUser.getRoles(); + while (iter.hasNext()) { + Role tomcatRole = (Role) iter.next(); + userRoles.add(tomcatRole.getRolename()); + } + } + return userRoles; + } +} \ No newline at end of file diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/AbstractAccountChooserValve.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/AbstractAccountChooserValve.java new file mode 100644 index 000000000..78ce6625b --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/AbstractAccountChooserValve.java @@ -0,0 +1,333 @@ +/* + * JBoss, Home of Professional Open Source + * + * Copyright 2013 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.picketlink.identity.federation.bindings.tomcat.sp; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.catalina.Context; +import org.apache.catalina.Lifecycle; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.Session; +import org.apache.catalina.connector.Request; +import org.apache.catalina.connector.Response; +import org.apache.catalina.valves.ValveBase; +import org.picketlink.common.PicketLinkLogger; +import org.picketlink.common.PicketLinkLoggerFactory; +import org.picketlink.common.constants.GeneralConstants; +import org.picketlink.common.util.StringUtil; +import org.picketlink.identity.federation.bindings.tomcat.sp.plugins.PropertiesAccountMapProvider; + +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; + +/** + * PLINK-344: Account Chooser At the Service Provider to enable redirection to + * the appropriate IDP + * + * @author Anil Saldhana + * @since January 21, 2014 + */ +public abstract class AbstractAccountChooserValve extends ValveBase implements Lifecycle { + protected static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger(); + + public static final String ACCOUNT_CHOOSER_COOKIE_NAME = "picketlink.account.name"; + + public static final String ACCOUNT_PARAMETER = "idp"; + + public static final String AUTHENTICATING = "AUTHENTICATING"; + + public static final String STATE = "STATE"; + + /** + * Domain Name to be used in the cookie that is sent out + */ + protected String domainName; + + protected String accountChooserPage = "/accountChooser.html"; + + protected ConcurrentHashMap idpMap = new ConcurrentHashMap<>(); + + private String accountIDPMapProviderName = PropertiesAccountMapProvider.class.getName(); + + protected AccountIDPMapProvider accountIDPMapProvider; + + /** + * Sets the account chooser cookie expiry. By default, we choose -1 which + * means cookie exists for the remainder of the browser session. + */ + protected int cookieExpiry = -1; + + @Override + public void initInternal() throws LifecycleException { + super.initInternal(); + try { + Class clazz = SecurityActions.loadClass(getClass(), this.accountIDPMapProviderName); + + if (clazz == null) { + throw logger.classNotLoadedError(this.accountIDPMapProviderName); + } + + accountIDPMapProvider = (AccountIDPMapProvider) clazz.newInstance(); + + Context context = (Context) getContainer(); + accountIDPMapProvider.setServletContext(context.getServletContext()); + idpMap.putAll(accountIDPMapProvider.getIDPMap()); + } catch (Exception e) { + throw new LifecycleException("Could not start " + getClass().getName() + ".", e); + } + } + + /** + * Set the domain name for the cookie to be sent to the browser There is no + * default. Setting the domain name for the cookie is optional. + * + * @param domainName + */ + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + /** + * Set the cookie expiry in seconds. Default value is -1 + * + * @param value + */ + public void setCookieExpiry(String value) { + try { + int expiry = Integer.parseInt(value); + cookieExpiry = expiry; + } catch (NumberFormatException nfe) { + logger.processingError(nfe); + } + } + + /** + * Set the fully qualified name of the implementation of + * {@link org.picketlink.identity.federation.bindings.tomcat.sp.AbstractAccountChooserValve.AccountIDPMapProvider} + * Default: + * {@link org.picketlink.identity.federation.bindings.tomcat.sp.plugins.PropertiesAccountMapProvider} + * + * @param idpMapProviderName + */ + public void setAccountIDPMapProvider(String idpMapProviderName) { + this.accountIDPMapProviderName = idpMapProviderName; + } + + /** + * Set the name of the html or jsp page that has the accounts for the user to + * choose. Default: "/accountChooser.html" is used + * + * @param pageName + */ + public void setAccountChooserPage(String pageName) { + this.accountChooserPage = pageName; + } + + @Override + public void invoke(Request request, Response response) throws IOException, ServletException { + Session session = request.getSessionInternal(); + + if (idpMap.isEmpty()) { + idpMap.putAll(accountIDPMapProvider.getIDPMap()); + } + + String sessionState = (String) session.getNote(STATE); + + String idpChosenKey = request.getParameter(ACCOUNT_PARAMETER); + String cookieValue = cookieValue(request); + if (cookieValue != null || AUTHENTICATING.equals(sessionState)) { + if (idpChosenKey != null) { + String chosenIDP = idpMap.get(idpChosenKey); + request.setAttribute(org.picketlink.identity.federation.web.constants.GeneralConstants.DESIRED_IDP, chosenIDP); + } + + // Case when user is directed to IDP and wants to change the IDP. So he + // enters the URL again + if (AUTHENTICATING.equals(sessionState) && request.getParameter(GeneralConstants.SAML_RESPONSE_KEY) == null) { + session.removeNote(STATE); + redirectToChosenPage(accountChooserPage, request, response); + return; + } + proceedToAuthentication(request, response, cookieValue); + } else { + if (idpChosenKey != null) { + String chosenIDP = idpMap.get(idpChosenKey); + if (chosenIDP != null) { + request.setAttribute(org.picketlink.identity.federation.web.constants.GeneralConstants.DESIRED_IDP, chosenIDP); + session.setNote(STATE, AUTHENTICATING); + proceedToAuthentication(request, response, idpChosenKey); + } else { + logger.configurationFileMissing(":IDP Mapping"); + throw new ServletException(); + } + } else { + // redirect to provided html + // saveRequest(request, request.getSessionInternal()); + redirectToChosenPage(accountChooserPage, request, response); + return; + } + } + } + + /** + * Proceed to the Service Provider Authentication Mechanism + * + * @param request + * @param response + * @param cookieValue + * @throws IOException + * @throws ServletException + */ + protected void proceedToAuthentication(Request request, Response response, String cookieValue) throws IOException, + ServletException { + Session session = request.getSessionInternal(false); + try { + /* + * String sessionState = (String) session.getNote(STATE); // Case when + * user is directed to IDP and wants to change the IDP. So he enters the + * URL again if (AUTHENTICATING.equals(sessionState) && + * request.getParameter(GeneralConstants.SAML_RESPONSE_KEY) == null) { + * session.removeNote(STATE); + * redirectToChosenPage(accountConfirmationPage, request, response); + * return; } + */ + getNext().invoke(request, response); + } finally { + String state = session != null ? (String) session.getNote(STATE) : null; + + // If we are authenticated and registered at the service provider + if (request.getUserPrincipal() != null && StringUtil.isNotNull(state)) { + session.removeNote(STATE); + // Send back a cookie + Context context = (Context) getContainer(); + String contextpath = context.getPath(); + + if (cookieValue == null) { + cookieValue = request.getParameter(AbstractAccountChooserValve.ACCOUNT_PARAMETER); + } + + Cookie cookie = new Cookie(ACCOUNT_CHOOSER_COOKIE_NAME, cookieValue); + cookie.setPath(contextpath); + cookie.setMaxAge(cookieExpiry); + if (domainName != null) { + cookie.setDomain(domainName); + } + response.addCookie(cookie); + } + } + } + + /** + * Redirect user to a page + * + * @param page + * @param request + * @param response + * @throws ServletException + * @throws IOException + */ + protected void redirectToChosenPage(String page, Request request, Response response) throws ServletException, IOException { + Context context = (Context) getContainer(); + RequestDispatcher requestDispatcher = context.getServletContext().getRequestDispatcher(page); + if (requestDispatcher != null) { + requestDispatcher.forward(request.getRequest(), response); + } + } + + protected String cookieValue(Request request) { + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + String cookieName = cookie.getName(); + String cookieDomain = cookie.getDomain(); + if (cookieDomain != null && cookieDomain.equalsIgnoreCase(domainName)) { + // Found a cookie with the same domain name + if (ACCOUNT_CHOOSER_COOKIE_NAME.equals(cookieName)) { + // Found cookie + String cookieValue = cookie.getValue(); + String chosenIDP = idpMap.get(cookieValue); + if (chosenIDP != null) { + request.setAttribute(org.picketlink.identity.federation.web.constants.GeneralConstants.DESIRED_IDP, chosenIDP); + return cookieValue; + } + } + } else { + if (ACCOUNT_CHOOSER_COOKIE_NAME.equals(cookieName)) { + // Found cookie + String cookieValue = cookie.getValue(); + String chosenIDP = idpMap.get(cookieValue); + if (chosenIDP != null) { + request.setAttribute(org.picketlink.identity.federation.web.constants.GeneralConstants.DESIRED_IDP, chosenIDP); + return cookieValue; + } + } + } + } + } + return null; + } + + /** + * Save the original request information into our session. + * + * @param request The request to be saved + * @param session The session to contain the saved information + * @throws IOException + */ + protected abstract void saveRequest(Request request, Session session) throws IOException; + + /** + * Restore the original request from information stored in our session. If the + * original request is no longer present (because the session timed out), + * return false; otherwise, return true. + * + * @param request The request to be restored + * @param session The session containing the saved information + */ + protected abstract boolean restoreRequest(Request request, Session session) throws IOException; + + /** + * Interface for obtaining the Identity Provider Mapping + */ + public interface AccountIDPMapProvider { + /** + * Set the servlet context for resources on web classpath + * + * @param servletContext + */ + void setServletContext(ServletContext servletContext); + + /** + * Set a {@link java.lang.ClassLoader} for the Provider + * + * @param classLoader + */ + void setClassLoader(ClassLoader classLoader); + + /** + * Get a map of AccountName versus IDP URLs + * + * @return + */ + Map getIDPMap() throws IOException; + } +} diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/AbstractSAML11SPRedirectFormAuthenticator.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/AbstractSAML11SPRedirectFormAuthenticator.java new file mode 100644 index 000000000..a5f7497ac --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/AbstractSAML11SPRedirectFormAuthenticator.java @@ -0,0 +1,134 @@ +package org.picketlink.identity.federation.bindings.tomcat.sp; + +import org.apache.catalina.LifecycleException; +import org.apache.catalina.Session; +import org.apache.catalina.authenticator.Constants; +import org.apache.catalina.connector.Request; +import org.apache.catalina.connector.Response; +import org.apache.tomcat.util.descriptor.web.LoginConfig; +import org.picketlink.common.ErrorCodes; +import org.picketlink.common.constants.GeneralConstants; +import org.picketlink.identity.federation.bindings.tomcat.sp.holder.ServiceProviderSAMLContext; +import org.picketlink.identity.federation.core.parsers.saml.SAMLParser; +import org.picketlink.identity.federation.core.saml.v2.util.AssertionUtil; +import org.picketlink.identity.federation.saml.v1.assertion.SAML11AssertionType; +import org.picketlink.identity.federation.saml.v1.assertion.SAML11AuthenticationStatementType; +import org.picketlink.identity.federation.saml.v1.assertion.SAML11StatementAbstractType; +import org.picketlink.identity.federation.saml.v1.assertion.SAML11SubjectType; +import org.picketlink.identity.federation.saml.v1.protocol.SAML11ResponseType; +import org.picketlink.identity.federation.web.util.RedirectBindingUtil; +import org.picketlink.identity.federation.web.util.ServerDetector; + +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.io.InputStream; +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; + +import static org.picketlink.common.util.StringUtil.isNotNull; + +/** + * Authenticator for SAML 1.1 processing at the Service Provider + * @author anil saldhana + * @since Jul 7, 2011 + */ +public abstract class AbstractSAML11SPRedirectFormAuthenticator extends AbstractSPFormAuthenticator { + + @Override + public boolean authenticate(Request request, HttpServletResponse response) throws IOException { + if (handleSAML11UnsolicitedResponse(request, response, this)) { + return true; + } + + logger.trace("Falling back on local Form Authentication if available"); + // fallback + return super.authenticate(request, response); + } + + public static boolean handleSAML11UnsolicitedResponse(Request request, HttpServletResponse response, AbstractSPFormAuthenticator formAuthenticator) throws IOException { + String samlResponse = request.getParameter(GeneralConstants.SAML_RESPONSE_KEY); + + Principal principal = request.getUserPrincipal(); + + // If we have already authenticated the user and there is no request from IDP or logout from user + if (principal != null) + return true; + + Session session = request.getSessionInternal(true); + + // See if we got a response from IDP + if (isNotNull(samlResponse)) { + boolean isValid = false; + try { + isValid = formAuthenticator.validate(request); + } catch (Exception e) { + logger.samlSPHandleRequestError(e); + throw new IOException(); + } + if (!isValid) + throw new IOException(ErrorCodes.VALIDATION_CHECK_FAILED); + + try { + InputStream base64DecodedResponse = RedirectBindingUtil.base64DeflateDecode(samlResponse); + SAMLParser parser = new SAMLParser(); + SAML11ResponseType saml11Response = (SAML11ResponseType) parser.parse(base64DecodedResponse); + + List assertions = saml11Response.get(); + if (assertions.size() > 1) { + logger.trace("More than one assertion from IDP. Considering the first one."); + } + String username = null; + List roles = new ArrayList(); + SAML11AssertionType assertion = assertions.get(0); + if (assertion != null) { + // Get the subject + List statements = assertion.getStatements(); + for (SAML11StatementAbstractType statement : statements) { + if (statement instanceof SAML11AuthenticationStatementType) { + SAML11AuthenticationStatementType subStat = (SAML11AuthenticationStatementType) statement; + SAML11SubjectType subject = subStat.getSubject(); + username = subject.getChoice().getNameID().getValue(); + } + } + roles = AssertionUtil.getRoles(assertion, null); + } + + String password = ServiceProviderSAMLContext.EMPTY_PASSWORD; + + // Map to JBoss specific principal + if ((new ServerDetector()).isJboss() || formAuthenticator.jbossEnv) { + // Push a context + ServiceProviderSAMLContext.push(username, roles); + principal = formAuthenticator.getContext().getRealm().authenticate(username, password); + ServiceProviderSAMLContext.clear(); + } else { + // tomcat env + SPUtil spUtil = new SPUtil(); + principal = spUtil.createGenericPrincipal(request, username, roles); + } + + session.setNote(Constants.SESS_USERNAME_NOTE, username); + session.setNote(Constants.SESS_PASSWORD_NOTE, password); + request.setUserPrincipal(principal); + + if (formAuthenticator.saveRestoreRequest) { + formAuthenticator.restoreRequest(request, session); + } + formAuthenticator.register(request, response, principal, FORM_METHOD, username, password); + + return true; + } catch (Exception e) { + logger.samlSPHandleRequestError(e); + } + } + + return false; + } + + protected void startPicketLink() throws LifecycleException{ + super.startPicketLink(); + this.spConfiguration.setBindingType("REDIRECT"); + } +} \ No newline at end of file diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/AbstractSPFormAuthenticator.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/AbstractSPFormAuthenticator.java new file mode 100644 index 000000000..6154aa660 --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/AbstractSPFormAuthenticator.java @@ -0,0 +1,812 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file 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.picketlink.identity.federation.bindings.tomcat.sp; + +import static org.picketlink.common.util.StringUtil.isNotNull; +import static org.picketlink.common.util.StringUtil.isNullOrEmpty; +import static org.picketlink.identity.federation.bindings.tomcat.sp.AbstractSAML11SPRedirectFormAuthenticator.handleSAML11UnsolicitedResponse; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.security.Principal; +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +import org.apache.catalina.Context; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.Session; +import org.apache.catalina.authenticator.Constants; +import org.apache.catalina.connector.Request; +import org.apache.catalina.connector.Response; +import org.apache.tomcat.util.descriptor.web.LoginConfig; +import org.jboss.security.audit.AuditLevel; +import org.picketlink.common.ErrorCodes; +import org.picketlink.common.constants.GeneralConstants; +import org.picketlink.common.constants.JBossSAMLConstants; +import org.picketlink.common.exceptions.ConfigurationException; +import org.picketlink.common.exceptions.ParsingException; +import org.picketlink.common.exceptions.ProcessingException; +import org.picketlink.common.exceptions.TrustKeyProcessingException; +import org.picketlink.common.exceptions.fed.AssertionExpiredException; +import org.picketlink.common.util.DocumentUtil; +import org.picketlink.common.util.StringUtil; +import org.picketlink.config.federation.AuthPropertyType; +import org.picketlink.config.federation.KeyProviderType; +import org.picketlink.identity.federation.bindings.tomcat.sp.holder.ServiceProviderSAMLContext; +import org.picketlink.identity.federation.core.audit.PicketLinkAuditEvent; +import org.picketlink.identity.federation.core.audit.PicketLinkAuditEventType; +import org.picketlink.identity.federation.core.interfaces.TrustKeyManager; +import org.picketlink.identity.federation.core.saml.v2.holders.DestinationInfoHolder; +import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2Handler; +import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2HandlerResponse; +import org.picketlink.identity.federation.core.util.CoreConfigUtil; +import org.picketlink.identity.federation.web.core.HTTPContext; +import org.picketlink.identity.federation.web.process.ServiceProviderBaseProcessor; +import org.picketlink.identity.federation.web.process.ServiceProviderSAMLRequestProcessor; +import org.picketlink.identity.federation.web.process.ServiceProviderSAMLResponseProcessor; +import org.picketlink.identity.federation.web.util.HTTPRedirectUtil; +import org.picketlink.identity.federation.web.util.PostBindingUtil; +import org.picketlink.identity.federation.web.util.RedirectBindingUtil; +import org.picketlink.identity.federation.web.util.RedirectBindingUtil.RedirectBindingUtilDestHolder; +import org.picketlink.identity.federation.web.util.ServerDetector; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; + +/** + *

+ * Abstract class to be extended by Service Provider valves to handle SAML + * requests and responses. + *

+ * + * @author Anil Saldhana + * @author Pedro Silva + */ +public abstract class AbstractSPFormAuthenticator extends BaseFormAuthenticator { + + /** + * The previously authenticated principal (if caching is disabled). + */ + public static final String FORM_PRINCIPAL_NOTE = "org.apache.catalina.authenticator.PRINCIPAL"; + + public static final String FORM_METHOD = "FORM"; + + protected boolean jbossEnv = false; + + AbstractSPFormAuthenticator() { + super(); + ServerDetector detector = new ServerDetector(); + jbossEnv = detector.isJboss(); + } + + /* + * (non-Javadoc) + * @see + * org.picketlink.identity.federation.bindings.tomcat.sp.BaseFormAuthenticator + * #processStart() + */ + @Override + protected void startPicketLink() throws LifecycleException { + super.startPicketLink(); + initKeyProvider(context); + } + + /** + *

+ * Send the request to the IDP. Subclasses should override this method to + * implement how requests must be sent to the IDP. + *

+ * + * @param destination idp url + * @param samlDocument request or response document + * @param relayState + * @param response + * @param request + * @param willSendRequest are we sending Request or Response to IDP + * @param destinationQueryStringWithSignature used only with Redirect binding + * and with signature enabled. + * @throws ProcessingException + * @throws ConfigurationException + * @throws IOException + */ + protected void sendRequestToIDP(String destination, + Document samlDocument, + String relayState, + Request request, + HttpServletResponse response, + boolean willSendRequest, + String destinationQueryStringWithSignature) throws ProcessingException, + ConfigurationException, + IOException { + + if (isAjaxRequest(request) && request.getUserPrincipal() == null) { + response.sendError(Response.SC_FORBIDDEN); + } else { + if (isHttpPostBinding()) { + sendHttpPostBindingRequest(destination, samlDocument, relayState, response, willSendRequest); + } else { + sendHttpRedirectRequest(destination, + samlDocument, + relayState, + response, + willSendRequest, + destinationQueryStringWithSignature); + } + } + } + + /** + *

+ * Sends a HTTP Redirect request to the IDP. + *

+ * + * @param destination + * @param relayState + * @param response + * @param willSendRequest + * @param destinationQueryStringWithSignature + * @throws IOException + * @throws UnsupportedEncodingException + * @throws ConfigurationException + * @throws ProcessingException + */ + protected void sendHttpRedirectRequest(String destination, + Document samlDocument, + String relayState, + HttpServletResponse response, + boolean willSendRequest, + String destinationQueryStringWithSignature) throws IOException, + ProcessingException, + ConfigurationException { + String destinationQueryString = null; + + // We already have queryString with signature from + // SAML2SignatureGenerationHandler + if (destinationQueryStringWithSignature != null) { + destinationQueryString = destinationQueryStringWithSignature; + } else { + String samlMessage = DocumentUtil.getDocumentAsString(samlDocument); + String base64Request = RedirectBindingUtil.deflateBase64URLEncode(samlMessage.getBytes("UTF-8")); + destinationQueryString = RedirectBindingUtil.getDestinationQueryString(base64Request, relayState, willSendRequest); + } + + RedirectBindingUtilDestHolder holder = new RedirectBindingUtilDestHolder(); + + holder.setDestination(destination).setDestinationQueryString(destinationQueryString); + + HTTPRedirectUtil.sendRedirectForRequestor(RedirectBindingUtil.getDestinationURL(holder), response); + } + + /** + *

+ * Sends a HTTP POST request to the IDP. + *

+ * + * @param destination + * @param samlDocument + * @param relayState + * @param response + * @param willSendRequest + * @throws TrustKeyProcessingException + * @throws ProcessingException + * @throws IOException + * @throws ConfigurationException + */ + protected void sendHttpPostBindingRequest(String destination, + Document samlDocument, + String relayState, + HttpServletResponse response, + boolean willSendRequest) throws ProcessingException, + IOException, + ConfigurationException { + String samlMessage = PostBindingUtil.base64Encode(DocumentUtil.getDocumentAsString(samlDocument)); + + DestinationInfoHolder destinationHolder = new DestinationInfoHolder(destination, samlMessage, relayState); + + PostBindingUtil.sendPost(destinationHolder, response, willSendRequest); + } + + /** + *

+ * Initialize the KeyProvider configurations. This configurations are to be + * used during signing and validation of SAML assertions. + *

+ * + * @param context + * @throws LifecycleException + */ + protected void initKeyProvider(Context context) throws LifecycleException { + if (!doSupportSignature()) { + return; + } + + KeyProviderType keyProvider = this.spConfiguration.getKeyProvider(); + + if (keyProvider == null && doSupportSignature()) + throw new LifecycleException(ErrorCodes.NULL_VALUE + "KeyProvider is null for context=" + context.getName()); + + try { + String keyManagerClassName = keyProvider.getClassName(); + if (keyManagerClassName == null) + throw new RuntimeException(ErrorCodes.NULL_VALUE + "KeyManager class name"); + + Class clazz = SecurityActions.loadClass(getClass(), keyManagerClassName); + + if (clazz == null) + throw new ClassNotFoundException(ErrorCodes.CLASS_NOT_LOADED + keyManagerClassName); + this.keyManager = (TrustKeyManager) clazz.newInstance(); + + List authProperties = CoreConfigUtil.getKeyProviderProperties(keyProvider); + + keyManager.setAuthProperties(authProperties); + keyManager.setValidatingAlias(keyProvider.getValidatingAlias()); + + String identityURL = this.spConfiguration.getIdentityURL(); + + // Special case when you need X509Data in SignedInfo + if (authProperties != null) { + for (AuthPropertyType authPropertyType : authProperties) { + String key = authPropertyType.getKey(); + if (GeneralConstants.X509CERTIFICATE.equals(key)) { + // we need X509Certificate in SignedInfo. The value is the alias + // name + keyManager.addAdditionalOption(GeneralConstants.X509CERTIFICATE, authPropertyType.getValue()); + break; + } + } + } + keyManager.addAdditionalOption(ServiceProviderBaseProcessor.IDP_KEY, new URL(identityURL).getHost()); + } catch (Exception e) { + logger.trustKeyManagerCreationError(e); + throw new LifecycleException(e.getLocalizedMessage()); + } + + logger.trace("Key Provider=" + keyProvider.getClassName()); + } + + /** + * Authenticate the request + * + * @param request + * @param response + * @param config + * @return + * @throws IOException + * @throws {@link RuntimeException} when the response is not of type catalina + * response object + */ + public boolean authenticate(Request request, HttpServletResponse response) throws IOException { + return doAuthenticate(request, response); + } + + /* + * (non-Javadoc) + * @see + * org.apache.catalina.authenticator.FormAuthenticator#authenticate(org.apache + * .catalina.connector.Request, org.apache.catalina.connector.Response, + * org.apache.tomcat.util.descriptor.web.LoginConfig) + */ + @Override + protected boolean doAuthenticate(Request request, HttpServletResponse response) throws IOException { + try { + // needs to be done first, *before* accessing any parameters. + // super.authenticate(..) gets called to late + String characterEncoding = getCharacterEncoding(); + if (characterEncoding != null) { + request.setCharacterEncoding(characterEncoding); + } + + Session session = request.getSessionInternal(true); + + // check if this call is resulting from the redirect after successful + // authentication. + // if so, make the authentication successful and continue the original + // request + if (saveRestoreRequest && matchRequest(request)) { + logger.trace("Restoring request from session '" + session.getIdInternal() + "'"); + Principal savedPrincipal = (Principal) session.getNote(FORM_PRINCIPAL_NOTE); + register(request, + response, + savedPrincipal, + FORM_METHOD, + (String) session.getNote(Constants.SESS_USERNAME_NOTE), + (String) session.getNote(Constants.SESS_PASSWORD_NOTE)); + + // try to restore the original request (including post data, etc...) + if (restoreRequest(request, session)) { + // success! user is authenticated; continue processing original + // request + logger.trace("Continuing with restored request."); + return true; + } else { + // no saved request found... + logger.trace("Restore of original request failed!"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST); + return false; + } + } + + // Eagerly look for Local LogOut + boolean localLogout = isLocalLogout(request); + + if (localLogout) { + try { + sendToLogoutPage(request, response, session); + } catch (ServletException e) { + logger.samlLogoutError(e); + throw new IOException(e); + } + return false; + } + + String samlRequest = request.getParameter(GeneralConstants.SAML_REQUEST_KEY); + String samlResponse = request.getParameter(GeneralConstants.SAML_RESPONSE_KEY); + + Principal principal = request.getUserPrincipal(); + + // If we have already authenticated the user and there is no request from + // IDP or logout from user + if (principal != null && !(isGlobalLogout(request) || isNotNull(samlRequest) || isNotNull(samlResponse))) + return true; + + // General User Request + if (!isNotNull(samlRequest) && !isNotNull(samlResponse)) { + return generalUserRequest(request, response); + } + + // Handle a SAML Response from IDP + if (isNotNull(samlResponse)) { + return handleSAMLResponse(request, response); + } + + // Handle SAML Requests from IDP + if (isNotNull(samlRequest)) { + return handleSAMLRequest(request, response); + } // end if + + return localAuthentication(request, response); + } catch (IOException e) { + if (StringUtil.isNotNull(spConfiguration.getErrorPage())) { + try { + request.getRequestDispatcher(spConfiguration.getErrorPage()).forward(request.getRequest(), response); + } catch (ServletException e1) { + logger.samlErrorPageForwardError(spConfiguration.getErrorPage(), e1); + } + return false; + } else { + throw e; + } + } + } + + /** + *

+ * Indicates if the current request is a GlobalLogout request. + *

+ * + * @param request + * @return + */ + private boolean isGlobalLogout(Request request) { + String gloStr = request.getParameter(GeneralConstants.GLOBAL_LOGOUT); + return isNotNull(gloStr) && "true".equalsIgnoreCase(gloStr); + } + + /** + *

+ * Indicates if the current request is a LocalLogout request. + *

+ * + * @param request + * @return + */ + private boolean isLocalLogout(Request request) { + String lloStr = request.getParameter(GeneralConstants.LOCAL_LOGOUT); + return isNotNull(lloStr) && "true".equalsIgnoreCase(lloStr); + } + + /** + * Handle the IDP Request + * + * @param request + * @param response + * @param loginConfig + * @return + * @throws IOException + */ + private boolean handleSAMLRequest(Request request, HttpServletResponse response) throws IOException { + String samlRequest = request.getParameter(GeneralConstants.SAML_REQUEST_KEY); + HTTPContext httpContext = new HTTPContext(request, response, context.getServletContext()); + Set handlers = chain.handlers(); + + try { + ServiceProviderSAMLRequestProcessor requestProcessor = new ServiceProviderSAMLRequestProcessor( + request.getMethod() + .equals("POST"), + this.serviceURL, + this.picketLinkConfiguration); + requestProcessor.setTrustKeyManager(keyManager); + boolean result = requestProcessor.process(samlRequest, httpContext, handlers, chainLock); + + if (enableAudit) { + PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent(AuditLevel.INFO); + auditEvent.setType(PicketLinkAuditEventType.REQUEST_FROM_IDP); + auditEvent.setWhoIsAuditing(getContextPath()); + auditHelper.audit(auditEvent); + } + + // If response is already commited, we need to stop with processing of + // HTTP request + if (response.isCommitted() || response.isCommitted()) + return false; + + if (result) + return result; + } catch (Exception e) { + logger.samlSPHandleRequestError(e); + throw logger.samlSPProcessingExceptionError(e); + } + + return localAuthentication(request, response); + } + + private Document toSAMLResponseDocument(String samlResponse, boolean isPostBinding) throws ParsingException { + InputStream dataStream = null; + + if (isPostBinding) { + // deal with SAML response from IDP + dataStream = PostBindingUtil.base64DecodeAsStream(samlResponse); + } else { + // deal with SAML response from IDP + dataStream = RedirectBindingUtil.base64DeflateDecode(samlResponse); + } + + try { + return DocumentUtil.getDocument(dataStream); + } catch (Exception e) { + logger.samlResponseFromIDPParsingFailed(); + throw new ParsingException("", e); + } + } + + /** + * Handle IDP Response + * + * @param request + * @param response + * @param loginConfig + * @return + * @throws IOException + */ + private boolean handleSAMLResponse(Request request, HttpServletResponse response) throws IOException { + if (!super.validate(request)) { + throw new IOException(ErrorCodes.VALIDATION_CHECK_FAILED); + } + + String samlVersion = getSAMLVersion(request); + + if (!JBossSAMLConstants.VERSION_2_0.get().equals(samlVersion)) { + return handleSAML11UnsolicitedResponse(request, response, this); + } + + return handleSAML2Response(request, response); + } + + private boolean handleSAML2Response(Request request, HttpServletResponse response) throws IOException { + Session session = request.getSessionInternal(true); + String samlResponse = request.getParameter(GeneralConstants.SAML_RESPONSE_KEY); + HTTPContext httpContext = new HTTPContext(request, response, context.getServletContext()); + Set handlers = chain.handlers(); + + Principal principal = request.getUserPrincipal(); + + boolean willSendRequest;// deal with SAML response from IDP + + try { + ServiceProviderSAMLResponseProcessor responseProcessor = + new ServiceProviderSAMLResponseProcessor(request.getMethod() + .equals("POST"), + serviceURL, + this.picketLinkConfiguration); + if (auditHelper != null) { + responseProcessor.setAuditHelper(auditHelper); + } + + responseProcessor.setTrustKeyManager(keyManager); + + SAML2HandlerResponse saml2HandlerResponse = responseProcessor.process(samlResponse, + httpContext, + handlers, + chainLock); + + Document samlResponseDocument = saml2HandlerResponse.getResultingDocument(); + String relayState = saml2HandlerResponse.getRelayState(); + + String destination = saml2HandlerResponse.getDestination(); + + willSendRequest = saml2HandlerResponse.getSendRequest(); + + String destinationQueryStringWithSignature = saml2HandlerResponse.getDestinationQueryStringWithSignature(); + + if (destination != null && samlResponseDocument != null) { + sendRequestToIDP(destination, + samlResponseDocument, + relayState, + request, + response, + willSendRequest, + destinationQueryStringWithSignature); + } else { + // See if the session has been invalidated + + boolean sessionValidity = session.isValid(); + + if (!sessionValidity) { + sendToLogoutPage(request, response, session); + return false; + } + + // We got a response with the principal + List roles = saml2HandlerResponse.getRoles(); + if (principal == null) + principal = (Principal) session.getSession().getAttribute(GeneralConstants.PRINCIPAL_ID); + + String username = principal.getName(); + String password = ServiceProviderSAMLContext.EMPTY_PASSWORD; + + if (logger.isTraceEnabled()) { + logger.trace("Roles determined for username=" + username + "=" + Arrays.toString(roles.toArray())); + } + + // Map to JBoss specific principal + if ((new ServerDetector()).isJboss() || jbossEnv) { + // Push a context + ServiceProviderSAMLContext.push(username, roles); + principal = context.getRealm().authenticate(username, password); + ServiceProviderSAMLContext.clear(); + } else { + // tomcat env + principal = getGenericPrincipal(request, username, roles); + } + + session.setNote(Constants.SESS_USERNAME_NOTE, username); + session.setNote(Constants.SESS_PASSWORD_NOTE, password); + request.setUserPrincipal(principal); + + if (enableAudit) { + PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent(AuditLevel.INFO); + auditEvent.setType(PicketLinkAuditEventType.RESPONSE_FROM_IDP); + auditEvent.setSubjectName(username); + auditEvent.setWhoIsAuditing(getContextPath()); + auditHelper.audit(auditEvent); + } + + // Redirect the user to the originally requested URL + if (saveRestoreRequest) { + // Store the authenticated principal in the session. + session.setNote(FORM_PRINCIPAL_NOTE, principal); + + // Redirect to the original URL. Note that this will trigger the + // authenticator again, but on resubmission we will look in the + // session notes to retrieve the authenticated principal and + // prevent reauthentication + String requestURI = savedRequestURL(session); + + if (requestURI != null) { + logger.trace("Redirecting back to original Request URI: " + requestURI); + response.sendRedirect(response.encodeRedirectURL(requestURI)); + } + } + + register(request, response, principal, FORM_METHOD, username, password); + return true; + } + } catch (ProcessingException pe) { + Throwable t = pe.getCause(); + if (t != null && t instanceof AssertionExpiredException) { + logger.error("Assertion has expired. Asking IDP for reissue"); + if (enableAudit) { + PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent(AuditLevel.INFO); + auditEvent.setType(PicketLinkAuditEventType.EXPIRED_ASSERTION); + auditEvent.setAssertionID(((AssertionExpiredException) t).getId()); + auditHelper.audit(auditEvent); + } + // Just issue a fresh request back to IDP + return generalUserRequest(request, response); + } + logger.samlSPHandleRequestError(pe); + throw logger.samlSPProcessingExceptionError(pe); + } catch (Exception e) { + logger.samlSPHandleRequestError(e); + throw logger.samlSPProcessingExceptionError(e); + } + + return localAuthentication(request, response); + } + + private String getSAMLVersion(Request request) { + String samlResponse = request.getParameter(GeneralConstants.SAML_RESPONSE_KEY); + String version; + + try { + Document samlDocument = toSAMLResponseDocument(samlResponse, "POST".equalsIgnoreCase(request.getMethod())); + Element element = samlDocument.getDocumentElement(); + + // let's try SAML 2.0 Version attribute first + version = element.getAttribute("Version"); + + if (isNullOrEmpty(version)) { + // fallback to SAML 1.1 Minor and Major attributes + String minorVersion = element.getAttribute("MinorVersion"); + String majorVersion = element.getAttribute("MajorVersion"); + + version = minorVersion + "." + majorVersion; + } + } catch (Exception e) { + throw new RuntimeException("Could not extract version from SAML Response.", e); + } + + return version; + } + + protected boolean isPOSTBindingResponse() { + return spConfiguration.isIdpUsesPostBinding(); + } + + /* + * (non-Javadoc) + * @see + * org.picketlink.identity.federation.bindings.tomcat.sp.BaseFormAuthenticator + * #getBinding() + */ + @Override + protected String getBinding() { + return spConfiguration.getBindingType(); + } + + /** + * Handle the user invocation for the first time + * + * @param request + * @param response + * @param loginConfig + * @return + * @throws IOException + */ + private boolean generalUserRequest(Request request, HttpServletResponse response) throws IOException { + Session session = request.getSessionInternal(true); + boolean willSendRequest = false; + HTTPContext httpContext = new HTTPContext(request, response, context.getServletContext()); + Set handlers = chain.handlers(); + + boolean postBinding = spConfiguration.getBindingType().equals("POST"); + + // Neither saml request nor response from IDP + // So this is a user request + SAML2HandlerResponse saml2HandlerResponse = null; + try { + ServiceProviderBaseProcessor baseProcessor = new ServiceProviderBaseProcessor(postBinding, + serviceURL, + this.picketLinkConfiguration); + if (issuerID != null) + baseProcessor.setIssuer(issuerID); + + // If the user has a different desired idp + String idp = (String) request.getAttribute(org.picketlink.identity.federation.web.constants.GeneralConstants.DESIRED_IDP); + if (StringUtil.isNotNull(idp)) { + baseProcessor.setIdentityURL(idp); + } else { + baseProcessor.setIdentityURL(identityURL); + } + baseProcessor.setAuditHelper(auditHelper); + + saml2HandlerResponse = baseProcessor.process(httpContext, handlers, chainLock); + } catch (ProcessingException pe) { + logger.samlSPHandleRequestError(pe); + throw new RuntimeException(pe); + } catch (ParsingException pe) { + logger.samlSPHandleRequestError(pe); + throw new RuntimeException(pe); + } catch (ConfigurationException pe) { + logger.samlSPHandleRequestError(pe); + throw new RuntimeException(pe); + } + + willSendRequest = saml2HandlerResponse.getSendRequest(); + + Document samlResponseDocument = saml2HandlerResponse.getResultingDocument(); + String relayState = saml2HandlerResponse.getRelayState(); + + String destination = saml2HandlerResponse.getDestination(); + String destinationQueryStringWithSignature = saml2HandlerResponse.getDestinationQueryStringWithSignature(); + + if (destination != null && samlResponseDocument != null) { + try { + if (saveRestoreRequest && !isGlobalLogout(request)) { + this.saveRequest(request, session); + } + if (enableAudit) { + PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent(AuditLevel.INFO); + auditEvent.setType(PicketLinkAuditEventType.REQUEST_TO_IDP); + auditEvent.setWhoIsAuditing(getContextPath()); + auditHelper.audit(auditEvent); + } + sendRequestToIDP(destination, + samlResponseDocument, + relayState, + request, + response, + willSendRequest, + destinationQueryStringWithSignature); + return false; + } catch (Exception e) { + logger.samlSPHandleRequestError(e); + throw logger.samlSPProcessingExceptionError(e); + } + } + + return localAuthentication(request, response); + } + + /** + *

+ * Indicates if the SP is configure with HTTP POST Binding. + *

+ * + * @return + */ + protected boolean isHttpPostBinding() { + return getBinding().equalsIgnoreCase("POST"); + } + + public Context getContext() { + return (Context) getContainer(); + } + + @Override + public boolean restoreRequest(Request request, Session session) throws IOException { + return super.restoreRequest(request, session); + } + + /** + * Subclasses need to return the context path based on the capability of their + * servlet api + * + * @return + */ + protected abstract String getContextPath(); + + protected Principal getGenericPrincipal(Request request, String username, List roles) { + return (new SPUtil()).createGenericPrincipal(request, username, roles); + } + + private boolean isAjaxRequest(Request request) { + String requestedWithHeader = request.getHeader(GeneralConstants.HTTP_HEADER_X_REQUESTED_WITH); + return requestedWithHeader != null && "XMLHttpRequest".equalsIgnoreCase(requestedWithHeader); + } +} diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/BaseFormAuthenticator.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/BaseFormAuthenticator.java new file mode 100644 index 000000000..1d38fbf7e --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/BaseFormAuthenticator.java @@ -0,0 +1,717 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file 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.picketlink.identity.federation.bindings.tomcat.sp; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.security.GeneralSecurityException; +import java.security.Principal; +import java.security.cert.X509Certificate; +import java.util.*; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import javax.xml.crypto.dsig.CanonicalizationMethod; + +import org.apache.catalina.Context; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.Session; +import org.apache.catalina.authenticator.AuthenticatorBase; +import org.apache.catalina.authenticator.FormAuthenticator; +import org.apache.catalina.connector.Request; +import org.apache.catalina.connector.Response; +import org.apache.tomcat.util.descriptor.web.LoginConfig; +import org.picketlink.common.ErrorCodes; +import org.picketlink.common.PicketLinkLogger; +import org.picketlink.common.PicketLinkLoggerFactory; +import org.picketlink.common.constants.GeneralConstants; +import org.picketlink.common.constants.JBossSAMLURIConstants; +import org.picketlink.common.exceptions.ConfigurationException; +import org.picketlink.common.exceptions.ParsingException; +import org.picketlink.common.exceptions.ProcessingException; +import org.picketlink.common.util.DocumentUtil; +import org.picketlink.common.util.StringUtil; +import org.picketlink.common.util.SystemPropertiesUtil; +import org.picketlink.config.federation.PicketLinkType; +import org.picketlink.config.federation.SPType; +import org.picketlink.config.federation.handler.Handlers; +import org.picketlink.identity.federation.api.saml.v2.metadata.MetaDataExtractor; +import org.picketlink.identity.federation.core.audit.PicketLinkAuditHelper; +import org.picketlink.identity.federation.core.interfaces.TrustKeyManager; +import org.picketlink.identity.federation.core.parsers.saml.SAMLParser; +import org.picketlink.identity.federation.core.saml.v2.factories.SAML2HandlerChainFactory; +import org.picketlink.identity.federation.core.saml.v2.impl.DefaultSAML2HandlerChainConfig; +import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2Handler; +import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2HandlerChain; +import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2HandlerChainConfig; +import org.picketlink.identity.federation.core.saml.v2.util.HandlerUtil; +import org.picketlink.identity.federation.core.util.CoreConfigUtil; +import org.picketlink.identity.federation.core.util.XMLSignatureUtil; +import org.picketlink.identity.federation.saml.v2.metadata.EndpointType; +import org.picketlink.identity.federation.saml.v2.metadata.EntitiesDescriptorType; +import org.picketlink.identity.federation.saml.v2.metadata.EntityDescriptorType; +import org.picketlink.identity.federation.saml.v2.metadata.IDPSSODescriptorType; +import org.picketlink.identity.federation.saml.v2.metadata.KeyDescriptorType; +import org.picketlink.identity.federation.web.config.AbstractSAMLConfigurationProvider; +import org.picketlink.identity.federation.web.util.ConfigurationUtil; +import org.picketlink.identity.federation.web.util.SAMLConfigurationProvider; +import org.w3c.dom.Document; + +import static org.picketlink.common.constants.GeneralConstants.CONFIG_FILE_LOCATION; +import static org.picketlink.common.util.StringUtil.isNullOrEmpty; + +/** + * Base Class for Service Provider Form Authenticators + * + * @author Anil.Saldhana@redhat.com + * @since Jun 9, 2009 + */ +public abstract class BaseFormAuthenticator extends FormAuthenticator { + protected static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger(); + + protected boolean enableAudit = false; + + protected PicketLinkAuditHelper auditHelper = null; + + protected TrustKeyManager keyManager; + + protected SPType spConfiguration = null; + + protected PicketLinkType picketLinkConfiguration = null; + + protected String serviceURL = null; + + protected String identityURL = null; + + protected String issuerID = null; + + protected String configFile; + + /** + * If the service provider is configured with an IDP metadata file, then this + * certificate can be picked up from the metadata + */ + protected transient X509Certificate idpCertificate = null; + + protected transient SAML2HandlerChain chain = null; + + protected transient String samlHandlerChainClass = null; + + protected Map chainConfigOptions = new HashMap<>(); + + // Whether the authenticator has to to save and restore request + protected boolean saveRestoreRequest = true; + + /** + * A Lock for Handler operations in the chain + */ + protected Lock chainLock = new ReentrantLock(); + + protected String canonicalizationMethod = CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS; + + /** + * The user can inject a fully qualified name of a + * {@link SAMLConfigurationProvider} + */ + protected SAMLConfigurationProvider configProvider = null; + + /** + * Servlet3 related changes forced Tomcat to change the authenticate method + * signature in the FormAuthenticator. For now, we use reflection for forward + * compatibility. This has to be changed in future. + */ + private Method theSuperRegisterMethod = null; + + /** + * If it is determined that we are running in a Tomcat6/JBAS5 environment, + * there is no need to seek the super.register method that conforms to the + * servlet3 spec changes + */ + private boolean seekSuperRegisterMethod = true; + + protected int timerInterval = -1; + + protected Timer timer = null; + + public BaseFormAuthenticator() { + super(); + } + + protected String idpAddress = null; + + /** + * If the request.getRemoteAddr is not exactly the IDP address that you have + * keyed in your deployment descriptor for keystore alias, you can set it here + * explicitly + */ + public void setIdpAddress(String idpAddress) { + this.idpAddress = idpAddress; + } + + /** + * Get the name of the configuration file + * + * @return + */ + public String getConfigFile() { + return configFile; + } + + /** + * Set the name of the configuration file + * + * @param configFile + */ + public void setConfigFile(String configFile) { + this.configFile = configFile; + } + + /** + * Set the SAML Handler Chain Class fqn + * + * @param samlHandlerChainClass + */ + public void setSamlHandlerChainClass(String samlHandlerChainClass) { + this.samlHandlerChainClass = samlHandlerChainClass; + } + + /** + * Set the service URL + * + * @param serviceURL + */ + public void setServiceURL(String serviceURL) { + this.serviceURL = serviceURL; + } + + /** + * Set whether the authenticator saves/restores the request during form + * authentication + * + * @param saveRestoreRequest + */ + public void setSaveRestoreRequest(boolean saveRestoreRequest) { + this.saveRestoreRequest = saveRestoreRequest; + } + + /** + * Set the {@link SAMLConfigurationProvider} fqn + * + * @param cp fqn of a {@link SAMLConfigurationProvider} + */ + public void setConfigProvider(String cp) { + if (cp == null) + throw new IllegalStateException(ErrorCodes.NULL_ARGUMENT + cp); + Class clazz = SecurityActions.loadClass(getClass(), cp); + if (clazz == null) + throw new RuntimeException(ErrorCodes.CLASS_NOT_LOADED + cp); + try { + configProvider = (SAMLConfigurationProvider) clazz.newInstance(); + } catch (Exception e) { + throw new RuntimeException(ErrorCodes.CANNOT_CREATE_INSTANCE + cp + ":" + e.getMessage()); + } + } + + /** + * Set an instance of the {@link SAMLConfigurationProvider} + * + * @param configProvider + */ + public void setConfigProvider(SAMLConfigurationProvider configProvider) { + this.configProvider = configProvider; + } + + /** + * Get the {@link SPType} + * + * @return + */ + public SPType getConfiguration() { + return spConfiguration; + } + + /** + * Set a separate issuer id + * + * @param issuerID + */ + public void setIssuerID(String issuerID) { + this.issuerID = issuerID; + } + + /** + * Set the logout page + * + * @param logOutPage + */ + public void setLogOutPage(String logOutPage) { + logger.warn("Option logOutPage is now configured with the PicketLinkSP element."); + + } + + /** + * Set the Timer Value to reload the configuration + * + * @param value an integer value that represents timer value (in miliseconds) + */ + public void setTimerInterval(String value) { + if (StringUtil.isNotNull(value)) { + timerInterval = Integer.parseInt(value); + } + } + + /** + * Perform validation os the request object + * + * @param request + * @return + * @throws IOException + * @throws GeneralSecurityException + */ + protected boolean validate(Request request) { + return request.getParameter("SAMLResponse") != null; + } + + /** + * Get the Identity URL + * + * @return + */ + public String getIdentityURL() { + return identityURL; + } + + /** + * Get the {@link X509Certificate} of the IDP if provided via the IDP metadata + * file + * + * @return {@link X509Certificate} or null + */ + public X509Certificate getIdpCertificate() { + return idpCertificate; + } + + /** + * This method is a hack!!! Tomcat on account of Servlet3 changed their + * authenticator method signatures We utilize Java Reflection to identify the + * super register method on the first call and save it. Subsquent invocations + * utilize the saved {@link Method} + * + * @see org.apache.catalina.authenticator.AuthenticatorBase#register(org.apache.catalina.connector.Request, + * org.apache.catalina.connector.Response, java.security.Principal, + * java.lang.String, java.lang.String, java.lang.String) + */ + @Override + public void register(Request request, + HttpServletResponse response, + Principal principal, + String arg3, + String arg4, + String arg5) { + // Try the JBossAS6 version + if (theSuperRegisterMethod == null && seekSuperRegisterMethod) { + Class[] args = new Class[] { Request.class, HttpServletResponse.class, Principal.class, String.class, + String.class, String.class }; + Class superClass = getAuthenticatorBaseClass(); + theSuperRegisterMethod = SecurityActions.getMethod(superClass, "register", args); + } + try { + if (theSuperRegisterMethod != null) { + Object[] callArgs = new Object[] { request, response, principal, arg3, arg4, arg5 }; + theSuperRegisterMethod.invoke(this, callArgs); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + + // Try the older version + if (theSuperRegisterMethod == null) { + seekSuperRegisterMethod = false; // Don't try to seek super register + // method on next invocation + super.register(request, response, principal, arg3, arg4, arg5); + return; + } + } + + /** + * Fall back on local authentication at the service provider side + * + * @param request + * @param response + * @param loginConfig + * @return + * @throws IOException + */ + protected boolean localAuthentication(Request request, HttpServletResponse response) throws IOException { + if (request.getUserPrincipal() == null) { + logger.samlSPFallingBackToLocalFormAuthentication();// fallback + return super.authenticate(request, response); + } else + return true; + } + + /** + * Return the SAML Binding that this authenticator supports + * + * @see {@link JBossSAMLURIConstants#SAML_HTTP_POST_BINDING} + * @see {@link JBossSAMLURIConstants#SAML_HTTP_REDIRECT_BINDING} + * @return + */ + protected abstract String getBinding(); + + /** + * Attempt to process a metadata file available locally + */ + protected void processIDPMetadataFile(String idpMetadataFile) { + ServletContext servletContext = context.getServletContext(); + InputStream is = servletContext.getResourceAsStream(idpMetadataFile); + if (is == null) + return; + + Object metadata = null; + try { + Document samlDocument = DocumentUtil.getDocument(is); + SAMLParser parser = new SAMLParser(); + metadata = parser.parse(DocumentUtil.getNodeAsStream(samlDocument)); + } catch (Exception e) { + throw new RuntimeException(e); + } + IDPSSODescriptorType idpSSO = null; + if (metadata instanceof EntitiesDescriptorType) { + EntitiesDescriptorType entities = (EntitiesDescriptorType) metadata; + idpSSO = handleMetadata(entities); + } else { + idpSSO = handleMetadata((EntityDescriptorType) metadata); + } + if (idpSSO == null) { + logger.samlSPUnableToGetIDPDescriptorFromMetadata(); + return; + } + List endpoints = idpSSO.getSingleSignOnService(); + for (EndpointType endpoint : endpoints) { + String endpointBinding = endpoint.getBinding().toString(); + if (endpointBinding.contains("HTTP-POST")) + endpointBinding = "POST"; + else if (endpointBinding.contains("HTTP-Redirect")) + endpointBinding = "REDIRECT"; + if (getBinding().equals(endpointBinding)) { + identityURL = endpoint.getLocation().toString(); + break; + } + } + List keyDescriptors = idpSSO.getKeyDescriptor(); + if (keyDescriptors.size() > 0) { + this.idpCertificate = MetaDataExtractor.getCertificate(keyDescriptors.get(0)); + } + } + + /** + * Process the configuration from the configuration file + */ + @SuppressWarnings("deprecation") + protected void processConfiguration() { + ServletContext servletContext = context.getServletContext(); + InputStream is = null; + + if (isNullOrEmpty(this.configFile)) { + this.configFile = CONFIG_FILE_LOCATION; + is = servletContext.getResourceAsStream(this.configFile); + } else { + try { + is = new FileInputStream(this.configFile); + } catch (FileNotFoundException e) { + throw logger.samlIDPConfigurationError(e); + } + } + + try { + // Work on the IDP Configuration + if (configProvider != null) { + try { + if (is == null) { + // Try the older version + is = servletContext.getResourceAsStream(GeneralConstants.DEPRECATED_CONFIG_FILE_LOCATION); + + // Additionally parse the deprecated config file + if (is != null && configProvider instanceof AbstractSAMLConfigurationProvider) { + ((AbstractSAMLConfigurationProvider) configProvider).setConfigFile(is); + } + } else { + // Additionally parse the consolidated config file + if (is != null && configProvider instanceof AbstractSAMLConfigurationProvider) { + ((AbstractSAMLConfigurationProvider) configProvider).setConsolidatedConfigFile(is); + } + } + + picketLinkConfiguration = configProvider.getPicketLinkConfiguration(); + spConfiguration = configProvider.getSPConfiguration(); + } catch (ProcessingException e) { + throw logger.samlSPConfigurationError(e); + } catch (ParsingException e) { + throw logger.samlSPConfigurationError(e); + } + } else { + if (is != null) { + try { + picketLinkConfiguration = ConfigurationUtil.getConfiguration(is); + spConfiguration = (SPType) picketLinkConfiguration.getIdpOrSP(); + } catch (ParsingException e) { + logger.trace(e); + throw logger.samlSPConfigurationError(e); + } + } else { + is = servletContext.getResourceAsStream(GeneralConstants.DEPRECATED_CONFIG_FILE_LOCATION); + if (is == null) + throw logger.configurationFileMissing(configFile); + spConfiguration = ConfigurationUtil.getSPConfiguration(is); + } + } + + if (this.picketLinkConfiguration != null) { + enableAudit = picketLinkConfiguration.isEnableAudit(); + + // See if we have the system property enabled + if (!enableAudit) { + String sysProp = SecurityActions.getSystemProperty(GeneralConstants.AUDIT_ENABLE, "NULL"); + if (!"NULL".equals(sysProp)) { + enableAudit = Boolean.parseBoolean(sysProp); + } + } + + if (enableAudit) { + if (auditHelper == null) { + String securityDomainName = PicketLinkAuditHelper.getSecurityDomainName(servletContext); + + auditHelper = new PicketLinkAuditHelper(securityDomainName); + } + } + } + + if (StringUtil.isNotNull(spConfiguration.getIdpMetadataFile())) { + processIDPMetadataFile(spConfiguration.getIdpMetadataFile()); + } else { + this.identityURL = spConfiguration.getIdentityURL(); + } + this.serviceURL = spConfiguration.getServiceURL(); + this.canonicalizationMethod = spConfiguration.getCanonicalizationMethod(); + + logger.samlSPSettingCanonicalizationMethod(canonicalizationMethod); + XMLSignatureUtil.setCanonicalizationMethodType(canonicalizationMethod); + + logger.trace("Identity Provider URL=" + this.identityURL); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + protected IDPSSODescriptorType handleMetadata(EntitiesDescriptorType entities) { + IDPSSODescriptorType idpSSO = null; + + List entityDescs = entities.getEntityDescriptor(); + for (Object entityDescriptor : entityDescs) { + if (entityDescriptor instanceof EntitiesDescriptorType) { + idpSSO = getIDPSSODescriptor(entities); + } else + idpSSO = handleMetadata((EntityDescriptorType) entityDescriptor); + if (idpSSO != null) + break; + } + return idpSSO; + } + + protected IDPSSODescriptorType handleMetadata(EntityDescriptorType entityDescriptor) { + return CoreConfigUtil.getIDPDescriptor(entityDescriptor); + } + + protected IDPSSODescriptorType getIDPSSODescriptor(EntitiesDescriptorType entities) { + List entityDescs = entities.getEntityDescriptor(); + for (Object entityDescriptor : entityDescs) { + + if (entityDescriptor instanceof EntitiesDescriptorType) { + return getIDPSSODescriptor((EntitiesDescriptorType) entityDescriptor); + } + return CoreConfigUtil.getIDPDescriptor((EntityDescriptorType) entityDescriptor); + } + return null; + } + + protected void initializeHandlerChain() throws ConfigurationException, ProcessingException { + populateChainConfig(); + SAML2HandlerChainConfig handlerChainConfig = new DefaultSAML2HandlerChainConfig(chainConfigOptions); + + Set samlHandlers = chain.handlers(); + + for (SAML2Handler handler : samlHandlers) { + handler.initChainConfig(handlerChainConfig); + } + } + + protected void populateChainConfig() throws ConfigurationException, ProcessingException { + chainConfigOptions.put(GeneralConstants.CONFIGURATION, spConfiguration); + chainConfigOptions.put(GeneralConstants.ROLE_VALIDATOR_IGNORE, "false"); // No + // validator + // as + // tomcat + // realm + // does + // validn + + if (doSupportSignature()) { + chainConfigOptions.put(GeneralConstants.KEYPAIR, keyManager.getSigningKeyPair()); + // If there is a need for X509Data in signedinfo + String certificateAlias = (String) keyManager.getAdditionalOption(GeneralConstants.X509CERTIFICATE); + if (certificateAlias != null) { + chainConfigOptions.put(GeneralConstants.X509CERTIFICATE, keyManager.getCertificate(certificateAlias)); + } + } + } + + protected void sendToLogoutPage(Request request, HttpServletResponse response, Session session) throws IOException, + ServletException { + // we are invalidated. + RequestDispatcher dispatch = context.getServletContext().getRequestDispatcher(this.getConfiguration().getLogOutPage()); + if (dispatch == null) + logger.samlSPCouldNotDispatchToLogoutPage(this.getConfiguration().getLogOutPage()); + else { + logger.trace("Forwarding request to logOutPage: " + this.getConfiguration().getLogOutPage()); + session.expire(); + try { + dispatch.forward(request, response); + } catch (Exception e) { + // JBAS5.1 and 6 quirkiness + dispatch.forward(request.getRequest(), response); + } + } + } + + // Mock test purpose + public void testStart() throws LifecycleException { + this.saveRestoreRequest = false; + if (context == null) + throw new RuntimeException("Catalina Context not set up"); + startPicketLink(); + } + + protected void startPicketLink() throws LifecycleException { + SystemPropertiesUtil.ensure(); + Handlers handlers = null; + + // Introduce a timer to reload configuration if desired + if (timerInterval > 0) { + if (timer == null) { + timer = new Timer(); + } + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + // Clear the configuration + picketLinkConfiguration = null; + spConfiguration = null; + + processConfiguration(); + try { + initKeyProvider(context); + } catch (LifecycleException e) { + logger.trace(e.getMessage()); + } + } + }, timerInterval, timerInterval); + } + + // Get the chain from config + if (StringUtil.isNullOrEmpty(samlHandlerChainClass)) { + chain = SAML2HandlerChainFactory.createChain(); + } else { + try { + chain = SAML2HandlerChainFactory.createChain(this.samlHandlerChainClass); + } catch (ProcessingException e1) { + throw new LifecycleException(e1); + } + } + + ServletContext servletContext = context.getServletContext(); + + this.processConfiguration(); + + try { + if (picketLinkConfiguration != null) { + handlers = picketLinkConfiguration.getHandlers(); + } else { + // Get the handlers + String handlerConfigFileName = GeneralConstants.HANDLER_CONFIG_FILE_LOCATION; + handlers = ConfigurationUtil.getHandlers(servletContext.getResourceAsStream(handlerConfigFileName)); + } + + chain.addAll(HandlerUtil.getHandlers(handlers)); + + this.initKeyProvider(context); + this.populateChainConfig(); + this.initializeHandlerChain(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + if (this.picketLinkConfiguration == null) { + this.picketLinkConfiguration = new PicketLinkType(); + + this.picketLinkConfiguration.setIdpOrSP(getConfiguration()); + this.picketLinkConfiguration.setHandlers(handlers); + } + } + + /** + *

+ * Indicates if digital signatures/validation of SAML assertions are enabled. + * Subclasses that supports signature should override this method. + *

+ * + * @return + */ + protected boolean doSupportSignature() { + if (spConfiguration != null) { + return spConfiguration.isSupportsSignature(); + } + return false; + } + + private Class getAuthenticatorBaseClass() { + Class myClass = getClass(); + do { + myClass = myClass.getSuperclass(); + } while (myClass != AuthenticatorBase.class); + return myClass; + } + + protected abstract void initKeyProvider(Context context) throws LifecycleException; + + public void setAuditHelper(PicketLinkAuditHelper auditHelper) { + this.auditHelper = auditHelper; + } +} diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/SPUtil.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/SPUtil.java new file mode 100644 index 000000000..ea180f0a7 --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/SPUtil.java @@ -0,0 +1,77 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file 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.picketlink.identity.federation.bindings.tomcat.sp; + +import java.security.Principal; +import java.util.List; + +import org.apache.catalina.Context; +import org.apache.catalina.connector.Request; +import org.apache.catalina.realm.GenericPrincipal; +import org.picketlink.common.PicketLinkLogger; +import org.picketlink.common.PicketLinkLoggerFactory; +import org.picketlink.common.exceptions.ConfigurationException; +import org.picketlink.identity.federation.api.saml.v2.request.SAML2Request; +import org.picketlink.identity.federation.core.saml.v2.common.IDGenerator; +import org.picketlink.identity.federation.saml.v2.protocol.AuthnRequestType; + +/** + * Common code useful for a SP + * + * @author Anil.Saldhana@redhat.com + * @since Jan 9, 2009 + */ +public class SPUtil { + + private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger(); + + /** + * Create a SAML2 auth request + * + * @param serviceURL URL of the service + * @param identityURL URL of the identity provider + * @return + * @throws ConfigurationException + */ + public AuthnRequestType createSAMLRequest(String serviceURL, String identityURL) throws ConfigurationException { + if (serviceURL == null) + throw logger.nullArgumentError("serviceURL"); + if (identityURL == null) + throw logger.nullArgumentError("identityURL"); + + SAML2Request saml2Request = new SAML2Request(); + String id = IDGenerator.create("ID_"); + return saml2Request.createAuthnRequestType(id, serviceURL, identityURL, serviceURL); + } + + /** + * Create an instance of the {@link GenericPrincipal} + * @param request + * @param username + * @param roles + * @return + */ + public Principal createGenericPrincipal(Request request, String username, List roles) { + Context ctx = request.getContext(); + return new GenericPrincipal(username, roles); + } +} \ No newline at end of file diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/SecurityActions.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/SecurityActions.java new file mode 100644 index 000000000..263907781 --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/SecurityActions.java @@ -0,0 +1,156 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file 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.picketlink.identity.federation.bindings.tomcat.sp; + +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * + * @author Anil.Saldhana@redhat.com + * @since Dec 9, 2008 + */ +class SecurityActions { + + /** + *

+ * Loads a {@link Class} using the fullQualifiedName supplied. This method tries first to load from the + * specified {@link Class}, if not found it will try to load from using TCL. + *

+ * + * @param theClass + * @param fullQualifiedName + * @return + */ + static Class loadClass(final Class theClass, final String fullQualifiedName) { + SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + return AccessController.doPrivileged(new PrivilegedAction>() { + public Class run() { + ClassLoader classLoader = theClass.getClassLoader(); + + Class clazz = loadClass(classLoader, fullQualifiedName); + if (clazz == null) { + classLoader = Thread.currentThread().getContextClassLoader(); + clazz = loadClass(classLoader, fullQualifiedName); + } + return clazz; + } + }); + } else { + ClassLoader classLoader = theClass.getClassLoader(); + + Class clazz = loadClass(classLoader, fullQualifiedName); + if (clazz == null) { + classLoader = Thread.currentThread().getContextClassLoader(); + clazz = loadClass(classLoader, fullQualifiedName); + } + return clazz; + } + } + + /** + *

+ * Loads a class from the specified {@link ClassLoader} using the fullQualifiedName supplied. + *

+ * + * @param classLoader + * @param fullQualifiedName + * @return + */ + static Class loadClass(final ClassLoader classLoader, final String fullQualifiedName) { + SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + return AccessController.doPrivileged(new PrivilegedAction>() { + public Class run() { + try { + return classLoader.loadClass(fullQualifiedName); + } catch (ClassNotFoundException e) { + } + return null; + } + }); + } else { + try { + return classLoader.loadClass(fullQualifiedName); + } catch (ClassNotFoundException e) { + } + return null; + } + } + + /** + *

Returns a system property value using the specified key. If not found the defaultValue will be returned.

+ * + * @param key + * @param defaultValue + * @return + */ + static String getSystemProperty(final String key, final String defaultValue) { + SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + return AccessController.doPrivileged(new PrivilegedAction() { + public String run() { + return System.getProperty(key, defaultValue); + } + }); + } else { + return System.getProperty(key, defaultValue); + } + } + + /** + * Use reflection to get the {@link Method} on a {@link Class} with the given parameter types + * + * @param clazz + * @param methodName + * @param parameterTypes + * @return + */ + static Method getMethod(final Class clazz, final String methodName, final Class[] parameterTypes) { + SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + return AccessController.doPrivileged(new PrivilegedAction() { + public Method run() { + try { + return clazz.getDeclaredMethod(methodName, parameterTypes); + } catch (Exception e) { + return null; + } + } + }); + } else { + try { + return clazz.getDeclaredMethod(methodName, parameterTypes); + } catch (Exception e) { + return null; + } + } + } + +} \ No newline at end of file diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/holder/ServiceProviderSAMLContext.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/holder/ServiceProviderSAMLContext.java new file mode 100644 index 000000000..63afb104b --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/holder/ServiceProviderSAMLContext.java @@ -0,0 +1,65 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file 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.picketlink.identity.federation.bindings.tomcat.sp.holder; + +import org.picketlink.identity.federation.core.constants.PicketLinkFederationConstants; + +import java.util.List; + +/** + * A context of username/roles to be used by login modules + * + * @author Anil.Saldhana@redhat.com + * @since Feb 13, 2009 + */ +public class ServiceProviderSAMLContext { + public static final String EMPTY_PASSWORD = "EMPTY_STR"; + + private static ThreadLocal username = new ThreadLocal(); + private static ThreadLocal> userRoles = new ThreadLocal>(); + + public static void push(String user, List roles) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(PicketLinkFederationConstants.RUNTIME_PERMISSION_CORE); + } + username.set(user); + userRoles.set(roles); + } + + public static void clear() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(PicketLinkFederationConstants.RUNTIME_PERMISSION_CORE); + } + username.remove(); + userRoles.remove(); + } + + public static String getUserName() { + return username.get(); + } + + public static List getRoles() { + return userRoles.get(); + } +} \ No newline at end of file diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/plugins/PropertiesAccountMapProvider.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/plugins/PropertiesAccountMapProvider.java new file mode 100644 index 000000000..e8dcc533d --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/tomcat/sp/plugins/PropertiesAccountMapProvider.java @@ -0,0 +1,86 @@ +/* + * JBoss, Home of Professional Open Source + * + * Copyright 2013 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.picketlink.identity.federation.bindings.tomcat.sp.plugins; + +import org.picketlink.identity.federation.bindings.tomcat.sp.AbstractAccountChooserValve; + +import jakarta.servlet.ServletContext; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +/** + * Implementation of + * {@link org.picketlink.identity.federation.bindings.tomcat.sp.AbstractAccountChooserValve.AccountIDPMapProvider} using a + * properties file + * + * @author Anil Saldhana + * @since January 23, 2014 + */ +public class PropertiesAccountMapProvider implements AbstractAccountChooserValve.AccountIDPMapProvider { + private ClassLoader classLoader = null; + + private ServletContext servletContext = null; + + public static final String PROP_FILE_NAME = "idpmap.properties"; + + public static final String WEB_INF_PROP_FILE_NAME = "/WEB-INF/idpmap.properties"; + + @Override + public void setClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + public void setServletContext(ServletContext servletContext){ + this.servletContext = servletContext; + } + + @Override + public Map getIDPMap() throws IOException { + Map idpmap = new HashMap(); + + InputStream inputStream = null; + + Properties properties = new Properties(); + if (classLoader != null) { + inputStream = classLoader.getResourceAsStream(PROP_FILE_NAME); + } + if (inputStream == null && servletContext != null) { + inputStream = servletContext.getResourceAsStream(PROP_FILE_NAME); + } + if (inputStream == null && servletContext != null) { + inputStream = servletContext.getResourceAsStream(WEB_INF_PROP_FILE_NAME); + } + if(inputStream == null){ + inputStream = getClass().getResourceAsStream(PROP_FILE_NAME); + } + if (inputStream != null) { + properties.load(inputStream); + if (properties != null) { + Set keyset = properties.keySet(); + for (Object key : keyset) { + idpmap.put((String) key, (String) properties.get(key)); + } + } + } + return idpmap; + } +} \ No newline at end of file diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/util/ModuleUtils.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/util/ModuleUtils.java new file mode 100644 index 000000000..911fe4272 --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/util/ModuleUtils.java @@ -0,0 +1,35 @@ +/* + * JBoss, Home of Professional Open Source + * + * Copyright 2013 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.picketlink.identity.federation.bindings.util; + +import org.picketlink.identity.federation.core.wstrust.STSClientConfig; + +/** + * Placeholder for utility class to work with modules. + * + * @author Peter Skopek + * + */ +public class ModuleUtils { + + public static String getCurrentModuleId() { + return STSClientConfig.NO_MODULE; + } + +} diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/util/SecurityActions.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/util/SecurityActions.java new file mode 100644 index 000000000..94c322eed --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/util/SecurityActions.java @@ -0,0 +1,54 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file 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.picketlink.identity.federation.bindings.util; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * + * @author Anil.Saldhana@redhat.com + * @since Dec 9, 2008 + */ +class SecurityActions { + /** + *

Returns a system property value using the specified key. If not found the defaultValue will be returned.

+ * + * @param key + * @param defaultValue + * @return + */ + static String getSystemProperty(final String key, final String defaultValue) { + SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + return AccessController.doPrivileged(new PrivilegedAction() { + public String run() { + return System.getProperty(key, defaultValue); + } + }); + } else { + return System.getProperty(key, defaultValue); + } + } +} \ No newline at end of file diff --git a/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/util/ValveUtil.java b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/util/ValveUtil.java new file mode 100644 index 000000000..cf0546409 --- /dev/null +++ b/picketlink-saml/src/main/java/org/picketlink/identity/federation/bindings/util/ValveUtil.java @@ -0,0 +1,46 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file 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.picketlink.identity.federation.bindings.util; + +import java.io.IOException; +import java.net.URL; + +/** + * Util for tomcat valves + * + * @author Anil.Saldhana@redhat.com + * @since Jan 22, 2009 + */ +public class ValveUtil { + + /** + * Given a SP or IDP issuer from the assertion, return the host + * + * @param domainURL + * @return + * @throws IOException + */ + public static String getDomain(String domainURL) throws IOException { + URL url = new URL(domainURL); + return url.getHost(); + } +} \ No newline at end of file diff --git a/picketlink-saml/src/main/patches/java.security.acl.Group.patch b/picketlink-saml/src/main/patches/java.security.acl.Group.patch new file mode 100644 index 000000000..1bf4857ef --- /dev/null +++ b/picketlink-saml/src/main/patches/java.security.acl.Group.patch @@ -0,0 +1,793 @@ +diff -uNr picketlink-orig/org/jboss/security/auth/spi/AbstractServerLoginModule.java picketlink/org/jboss/security/auth/spi/AbstractServerLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/AbstractServerLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/AbstractServerLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -31,7 +31,7 @@ + import javax.security.auth.spi.LoginModule; + import java.lang.reflect.Constructor; + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.*; + + /** +@@ -209,7 +209,7 @@ + to the subject getPrincipals() Set. + + @see javax.security.auth.Subject; +- @see java.security.acl.Group; ++ @see org.jboss.security.Group; + @return true always. + */ + public boolean commit() throws LoginException +diff -uNr picketlink-orig/org/jboss/security/auth/spi/AnonLoginModule.java picketlink/org/jboss/security/auth/spi/AnonLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/AnonLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/AnonLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -21,7 +21,7 @@ + */ + package org.jboss.security.auth.spi; + +-import java.security.acl.Group; ++import org.jboss.security.Group; + + import javax.security.auth.login.LoginException; + +diff -uNr picketlink-orig/org/jboss/security/auth/spi/BaseCertLoginModule.java picketlink/org/jboss/security/auth/spi/BaseCertLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/BaseCertLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/BaseCertLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -25,7 +25,7 @@ + import java.security.KeyStore; + import java.security.KeyStoreException; + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.security.cert.X509Certificate; + import java.util.ArrayList; + import java.util.Enumeration; +diff -uNr picketlink-orig/org/jboss/security/auth/spi/CertRolesLoginModule.java picketlink/org/jboss/security/auth/spi/CertRolesLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/CertRolesLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/CertRolesLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.auth.spi; + + import java.io.IOException; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + import java.util.Properties; + +diff -uNr picketlink-orig/org/jboss/security/auth/spi/DatabaseCertLoginModule.java picketlink/org/jboss/security/auth/spi/DatabaseCertLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/DatabaseCertLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/DatabaseCertLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -21,7 +21,7 @@ + */ + package org.jboss.security.auth.spi; + +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + + import javax.security.auth.Subject; +diff -uNr picketlink-orig/org/jboss/security/auth/spi/DatabaseServerLoginModule.java picketlink/org/jboss/security/auth/spi/DatabaseServerLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/DatabaseServerLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/DatabaseServerLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -21,7 +21,7 @@ + */ + package org.jboss.security.auth.spi; + +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.sql.Connection; + import java.sql.PreparedStatement; + import java.sql.ResultSet; +diff -uNr picketlink-orig/org/jboss/security/auth/spi/DbUtil.java picketlink/org/jboss/security/auth/spi/DbUtil.java +--- picketlink-orig/org/jboss/security/auth/spi/DbUtil.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/DbUtil.java 2023-12-17 08:04:43.364951947 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.auth.spi; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.sql.Connection; + import java.sql.PreparedStatement; + import java.sql.ResultSet; +diff -uNr picketlink-orig/org/jboss/security/auth/spi/IdentityLoginModule.java picketlink/org/jboss/security/auth/spi/IdentityLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/IdentityLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/IdentityLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.auth.spi; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + import java.util.StringTokenizer; + +diff -uNr picketlink-orig/org/jboss/security/auth/spi/LdapExtLoginModule.java picketlink/org/jboss/security/auth/spi/LdapExtLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/LdapExtLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/LdapExtLoginModule.java 2023-12-17 08:04:43.368951953 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.auth.spi; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Iterator; + import java.util.Map; + import java.util.Properties; +diff -uNr picketlink-orig/org/jboss/security/auth/spi/LdapLoginModule.java picketlink/org/jboss/security/auth/spi/LdapLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/LdapLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/LdapLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.auth.spi; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Arrays; + import java.util.Iterator; + import java.util.Properties; +diff -uNr picketlink-orig/org/jboss/security/auth/spi/LdapUsersLoginModule.java picketlink/org/jboss/security/auth/spi/LdapUsersLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/LdapUsersLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/LdapUsersLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -21,7 +21,7 @@ + */ + package org.jboss.security.auth.spi; + +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Iterator; + import java.util.Map; + import java.util.Map.Entry; +diff -uNr picketlink-orig/org/jboss/security/auth/spi/otp/JBossTimeBasedOTPLoginModule.java picketlink/org/jboss/security/auth/spi/otp/JBossTimeBasedOTPLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/otp/JBossTimeBasedOTPLoginModule.java 2023-12-17 08:04:11.748905792 +0100 ++++ picketlink/org/jboss/security/auth/spi/otp/JBossTimeBasedOTPLoginModule.java 2023-12-17 08:04:43.368951953 +0100 +@@ -24,7 +24,7 @@ + import java.io.IOException; + import java.io.InputStream; + import java.security.GeneralSecurityException; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Arrays; + import java.util.HashMap; + import java.util.HashSet; +diff -uNr picketlink-orig/org/jboss/security/auth/spi/PropertiesUsersLoginModule.java picketlink/org/jboss/security/auth/spi/PropertiesUsersLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/PropertiesUsersLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/PropertiesUsersLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.auth.spi; + + import java.io.IOException; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + import java.util.Properties; + +diff -uNr picketlink-orig/org/jboss/security/auth/spi/RemoteHostTrustLoginModule.java picketlink/org/jboss/security/auth/spi/RemoteHostTrustLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/RemoteHostTrustLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/RemoteHostTrustLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -21,7 +21,7 @@ + */ + package org.jboss.security.auth.spi; + +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Arrays; + import java.util.List; + import java.util.Map; +diff -uNr picketlink-orig/org/jboss/security/auth/spi/RoleMappingLoginModule.java picketlink/org/jboss/security/auth/spi/RoleMappingLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/RoleMappingLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/RoleMappingLoginModule.java 2023-12-17 08:04:43.368951953 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.auth.spi; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Enumeration; + import java.util.Iterator; + import java.util.Map; +diff -uNr picketlink-orig/org/jboss/security/auth/spi/SimpleServerLoginModule.java picketlink/org/jboss/security/auth/spi/SimpleServerLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/SimpleServerLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/SimpleServerLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.auth.spi; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + + import javax.security.auth.login.LoginException; + +diff -uNr picketlink-orig/org/jboss/security/auth/spi/Users.java picketlink/org/jboss/security/auth/spi/Users.java +--- picketlink-orig/org/jboss/security/auth/spi/Users.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/Users.java 2023-12-17 08:04:43.364951947 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.auth.spi; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.ArrayList; + import java.util.Enumeration; + import java.util.HashMap; +diff -uNr picketlink-orig/org/jboss/security/auth/spi/UsersLoginModule.java picketlink/org/jboss/security/auth/spi/UsersLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/UsersLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/UsersLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -26,7 +26,7 @@ + import java.io.IOException; + import java.io.InputStream; + import java.net.URL; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + import java.util.Properties; + +diff -uNr picketlink-orig/org/jboss/security/auth/spi/UsersRolesLoginModule.java picketlink/org/jboss/security/auth/spi/UsersRolesLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/UsersRolesLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/UsersRolesLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.auth.spi; + + import java.io.IOException; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + import java.util.Properties; + +diff -uNr picketlink-orig/org/jboss/security/auth/spi/Util.java picketlink/org/jboss/security/auth/spi/Util.java +--- picketlink-orig/org/jboss/security/auth/spi/Util.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/Util.java 2023-12-17 08:04:43.364951947 +0100 +@@ -31,7 +31,7 @@ + import java.security.MessageDigest; + import java.security.Principal; + import java.security.PrivilegedActionException; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.ArrayList; + import java.util.Enumeration; + import java.util.Properties; +diff -uNr picketlink-orig/org/jboss/security/auth/spi/XMLLoginModule.java picketlink/org/jboss/security/auth/spi/XMLLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/XMLLoginModule.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/auth/spi/XMLLoginModule.java 2023-12-17 08:04:43.364951947 +0100 +@@ -21,7 +21,7 @@ + */ + package org.jboss.security.auth.spi; + +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + + import javax.security.auth.Subject; +diff -uNr picketlink-orig/org/jboss/security/AuthorizationManager.java picketlink/org/jboss/security/AuthorizationManager.java +--- picketlink-orig/org/jboss/security/AuthorizationManager.java 2023-12-17 08:04:11.736905774 +0100 ++++ picketlink/org/jboss/security/AuthorizationManager.java 2023-12-17 08:04:43.356951936 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + import java.util.Set; + +diff -uNr picketlink-orig/org/jboss/security/identity/extensions/CertificateIdentityFactory.java picketlink/org/jboss/security/identity/extensions/CertificateIdentityFactory.java +--- picketlink-orig/org/jboss/security/identity/extensions/CertificateIdentityFactory.java 2023-12-17 08:04:11.740905781 +0100 ++++ picketlink/org/jboss/security/identity/extensions/CertificateIdentityFactory.java 2023-12-17 08:04:43.356951936 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.identity.extensions; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.security.cert.X509Certificate; + + import org.jboss.security.identity.IdentityFactory; +diff -uNr picketlink-orig/org/jboss/security/identity/extensions/CredentialIdentityFactory.java picketlink/org/jboss/security/identity/extensions/CredentialIdentityFactory.java +--- picketlink-orig/org/jboss/security/identity/extensions/CredentialIdentityFactory.java 2023-12-17 08:04:11.740905781 +0100 ++++ picketlink/org/jboss/security/identity/extensions/CredentialIdentityFactory.java 2023-12-17 08:04:43.356951936 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.identity.extensions; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + + import org.jboss.security.identity.IdentityFactory; + import org.jboss.security.identity.Role; +diff -uNr picketlink-orig/org/jboss/security/identity/Identity.java picketlink/org/jboss/security/identity/Identity.java +--- picketlink-orig/org/jboss/security/identity/Identity.java 2023-12-17 08:04:11.736905774 +0100 ++++ picketlink/org/jboss/security/identity/Identity.java 2023-12-17 08:04:43.356951936 +0100 +@@ -23,7 +23,7 @@ + + import java.io.Serializable; + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + + //$Id$ + +diff -uNr picketlink-orig/org/jboss/security/identity/plugins/IdentityFactory.java picketlink/org/jboss/security/identity/plugins/IdentityFactory.java +--- picketlink-orig/org/jboss/security/identity/plugins/IdentityFactory.java 2023-12-17 08:04:11.740905781 +0100 ++++ picketlink/org/jboss/security/identity/plugins/IdentityFactory.java 2023-12-17 08:04:43.356951936 +0100 +@@ -23,7 +23,7 @@ + + import java.lang.reflect.Constructor; + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + + import org.jboss.security.identity.Identity; + import org.jboss.security.identity.Role; +diff -uNr picketlink-orig/org/jboss/security/identity/plugins/SimpleIdentity.java picketlink/org/jboss/security/identity/plugins/SimpleIdentity.java +--- picketlink-orig/org/jboss/security/identity/plugins/SimpleIdentity.java 2023-12-17 08:04:11.740905781 +0100 ++++ picketlink/org/jboss/security/identity/plugins/SimpleIdentity.java 2023-12-17 08:04:43.356951936 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.identity.plugins; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + + import org.jboss.security.identity.Identity; + import org.jboss.security.identity.Role; +diff -uNr picketlink-orig/org/jboss/security/identity/plugins/SimpleRoleGroup.java picketlink/org/jboss/security/identity/plugins/SimpleRoleGroup.java +--- picketlink-orig/org/jboss/security/identity/plugins/SimpleRoleGroup.java 2023-12-17 08:04:11.740905781 +0100 ++++ picketlink/org/jboss/security/identity/plugins/SimpleRoleGroup.java 2023-12-17 08:04:43.356951936 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.identity.plugins; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.ArrayList; + import java.util.Collections; + import java.util.Enumeration; +diff -uNr picketlink-orig/org/jboss/security/jacc/ContextPolicy.java picketlink/org/jboss/security/jacc/ContextPolicy.java +--- picketlink-orig/org/jboss/security/jacc/ContextPolicy.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/jacc/ContextPolicy.java 2023-12-17 08:04:43.364951947 +0100 +@@ -26,7 +26,7 @@ + import java.security.Permissions; + import java.security.Principal; + import java.security.ProtectionDomain; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.ArrayList; + import java.util.Enumeration; + import java.util.HashMap; +diff -uNr picketlink-orig/org/jboss/security/mapping/providers/DeploymentRolesMappingProvider.java picketlink/org/jboss/security/mapping/providers/DeploymentRolesMappingProvider.java +--- picketlink-orig/org/jboss/security/mapping/providers/DeploymentRolesMappingProvider.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/mapping/providers/DeploymentRolesMappingProvider.java 2023-12-17 08:04:43.364951947 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.mapping.providers; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + import java.util.Set; + +diff -uNr picketlink-orig/org/jboss/security/mapping/providers/MappingProviderUtil.java picketlink/org/jboss/security/mapping/providers/MappingProviderUtil.java +--- picketlink-orig/org/jboss/security/mapping/providers/MappingProviderUtil.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/mapping/providers/MappingProviderUtil.java 2023-12-17 08:04:43.364951947 +0100 +@@ -23,7 +23,7 @@ + + import java.lang.reflect.Constructor; + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Enumeration; + import java.util.HashSet; + import java.util.StringTokenizer; +diff -uNr picketlink-orig/org/jboss/security/mapping/providers/principal/AbstractPrincipalMappingProvider.java picketlink/org/jboss/security/mapping/providers/principal/AbstractPrincipalMappingProvider.java +--- picketlink-orig/org/jboss/security/mapping/providers/principal/AbstractPrincipalMappingProvider.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/mapping/providers/principal/AbstractPrincipalMappingProvider.java 2023-12-17 08:04:43.364951947 +0100 +@@ -22,13 +22,13 @@ + package org.jboss.security.mapping.providers.principal; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + + import org.jboss.security.mapping.MappingProvider; + + /** + * Abstract class for Principal mapping providers +- * Group Principal (java.security.acl.Group) is not supported. ++ * Group Principal (org.jboss.security.Group) is not supported. + * @author Anil.Saldhana@redhat.com + */ + public abstract class AbstractPrincipalMappingProvider implements MappingProvider +diff -uNr picketlink-orig/org/jboss/security/mapping/providers/role/AbstractRolesMappingProvider.java picketlink/org/jboss/security/mapping/providers/role/AbstractRolesMappingProvider.java +--- picketlink-orig/org/jboss/security/mapping/providers/role/AbstractRolesMappingProvider.java 2023-12-17 08:04:11.744905786 +0100 ++++ picketlink/org/jboss/security/mapping/providers/role/AbstractRolesMappingProvider.java 2023-12-17 08:04:43.364951947 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security.mapping.providers.role; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Enumeration; + import java.util.Map; + import java.util.Set; +diff -uNr picketlink-orig/org/jboss/security/NestableGroup.java picketlink/org/jboss/security/NestableGroup.java +--- picketlink-orig/org/jboss/security/NestableGroup.java 2023-12-17 08:04:11.736905774 +0100 ++++ picketlink/org/jboss/security/NestableGroup.java 2023-12-17 08:04:43.356951936 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Enumeration; + import java.util.LinkedList; + +diff -uNr picketlink-orig/org/jboss/security/NestablePrincipal.java picketlink/org/jboss/security/NestablePrincipal.java +--- picketlink-orig/org/jboss/security/NestablePrincipal.java 2023-12-17 08:04:11.736905774 +0100 ++++ picketlink/org/jboss/security/NestablePrincipal.java 2023-12-17 08:04:43.356951936 +0100 +@@ -22,7 +22,7 @@ + package org.jboss.security; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Enumeration; + import java.util.LinkedList; + +diff -uNr picketlink-orig/org/jboss/security/plugins/auth/JaasSecurityManagerBase.java picketlink/org/jboss/security/plugins/auth/JaasSecurityManagerBase.java +--- picketlink-orig/org/jboss/security/plugins/auth/JaasSecurityManagerBase.java 2023-12-17 08:04:11.748905792 +0100 ++++ picketlink/org/jboss/security/plugins/auth/JaasSecurityManagerBase.java 2023-12-17 08:04:43.368951953 +0100 +@@ -228,7 +228,7 @@ + the active user and assigned user roles. + @param rolePrincipals - a Set of Principals for the roles to check. + +- @see java.security.acl.Group; ++ @see org.jboss.security.Group; + @see Subject#getPrincipals() + */ + public boolean doesUserHaveRole(Principal principal, Set rolePrincipals) +diff -uNr picketlink-orig/org/jboss/security/plugins/JBossAuthorizationManager.java picketlink/org/jboss/security/plugins/JBossAuthorizationManager.java +--- picketlink-orig/org/jboss/security/plugins/JBossAuthorizationManager.java 2023-12-17 08:04:11.748905792 +0100 ++++ picketlink/org/jboss/security/plugins/JBossAuthorizationManager.java 2023-12-17 08:04:43.368951953 +0100 +@@ -24,7 +24,7 @@ + import static org.jboss.security.SecurityConstants.ROLES_IDENTIFIER; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Enumeration; + import java.util.HashMap; + import java.util.HashSet; +@@ -139,7 +139,7 @@ + the active user and assigned user roles. + @param rolePrincipals - a Set of Principals for the roles to check. + +- @see java.security.acl.Group; ++ @see org.jboss.security.Group; + @see Subject#getPrincipals() + */ + public boolean doesUserHaveRole(Principal principal, Set rolePrincipals) +diff -uNr picketlink-orig/org/jboss/security/plugins/JBossSecurityContext.java picketlink/org/jboss/security/plugins/JBossSecurityContext.java +--- picketlink-orig/org/jboss/security/plugins/JBossSecurityContext.java 2023-12-17 08:04:11.748905792 +0100 ++++ picketlink/org/jboss/security/plugins/JBossSecurityContext.java 2023-12-17 08:04:43.368951953 +0100 +@@ -9,7 +9,7 @@ + import static org.jboss.security.SecurityConstants.ROLES_IDENTIFIER; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Enumeration; + import java.util.HashMap; + import java.util.Map; +diff -uNr picketlink-orig/org/jboss/security/plugins/JBossSecurityContextUtil.java picketlink/org/jboss/security/plugins/JBossSecurityContextUtil.java +--- picketlink-orig/org/jboss/security/plugins/JBossSecurityContextUtil.java 2023-12-17 08:04:11.748905792 +0100 ++++ picketlink/org/jboss/security/plugins/JBossSecurityContextUtil.java 2023-12-17 08:04:43.368951953 +0100 +@@ -26,7 +26,7 @@ + import static org.jboss.security.SecurityConstants.RUNAS_IDENTITY_IDENTIFIER; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + + import javax.security.auth.Subject; +diff -uNr picketlink-orig/org/jboss/security/SecurityUtil.java picketlink/org/jboss/security/SecurityUtil.java +--- picketlink-orig/org/jboss/security/SecurityUtil.java 2023-12-17 08:04:11.736905774 +0100 ++++ picketlink/org/jboss/security/SecurityUtil.java 2023-12-17 08:04:43.356951936 +0100 +@@ -21,7 +21,7 @@ + */ + package org.jboss.security; + +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Iterator; + import java.util.Set; + +diff -uNr picketlink-orig/org/jboss/security/SimpleGroup.java picketlink/org/jboss/security/SimpleGroup.java +--- picketlink-orig/org/jboss/security/SimpleGroup.java 2023-12-17 08:04:11.736905774 +0100 ++++ picketlink/org/jboss/security/SimpleGroup.java 2023-12-17 08:04:43.356951936 +0100 +@@ -24,7 +24,7 @@ + import java.security.AccessController; + import java.security.Principal; + import java.security.PrivilegedAction; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Collection; + import java.util.Collections; + import java.util.Enumeration; +diff -uNr picketlink-orig/org/picketbox/datasource/security/CallerIdentityLoginModule.java picketlink/org/picketbox/datasource/security/CallerIdentityLoginModule.java +--- picketlink-orig/org/picketbox/datasource/security/CallerIdentityLoginModule.java 2023-12-17 08:04:11.736905774 +0100 ++++ picketlink/org/picketbox/datasource/security/CallerIdentityLoginModule.java 2023-12-17 08:04:43.356951936 +0100 +@@ -22,7 +22,7 @@ + package org.picketbox.datasource.security; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + import java.util.Set; + +diff -uNr picketlink-orig/org/picketbox/datasource/security/ConfiguredIdentityLoginModule.java picketlink/org/picketbox/datasource/security/ConfiguredIdentityLoginModule.java +--- picketlink-orig/org/picketbox/datasource/security/ConfiguredIdentityLoginModule.java 2023-12-17 08:04:11.736905774 +0100 ++++ picketlink/org/picketbox/datasource/security/ConfiguredIdentityLoginModule.java 2023-12-17 08:04:43.356951936 +0100 +@@ -23,7 +23,7 @@ + + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + + import javax.resource.spi.security.PasswordCredential; +diff -uNr picketlink-orig/org/picketbox/datasource/security/JaasSecurityDomainIdentityLoginModule.java picketlink/org/picketbox/datasource/security/JaasSecurityDomainIdentityLoginModule.java +--- picketlink-orig/org/picketbox/datasource/security/JaasSecurityDomainIdentityLoginModule.java 2023-12-17 08:04:11.736905774 +0100 ++++ picketlink/org/picketbox/datasource/security/JaasSecurityDomainIdentityLoginModule.java 2023-12-17 08:04:43.356951936 +0100 +@@ -25,7 +25,7 @@ + import java.security.Principal; + import java.security.PrivilegedActionException; + import java.security.PrivilegedExceptionAction; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + + import javax.management.MBeanServer; +diff -uNr picketlink-orig/org/picketbox/datasource/security/PBEIdentityLoginModule.java picketlink/org/picketbox/datasource/security/PBEIdentityLoginModule.java +--- picketlink-orig/org/picketbox/datasource/security/PBEIdentityLoginModule.java 2023-12-17 08:04:11.736905774 +0100 ++++ picketlink/org/picketbox/datasource/security/PBEIdentityLoginModule.java 2023-12-17 08:04:43.356951936 +0100 +@@ -22,7 +22,7 @@ + package org.picketbox.datasource.security; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + + import javax.crypto.Cipher; +diff -uNr picketlink-orig/org/picketbox/datasource/security/SecureIdentityLoginModule.java picketlink/org/picketbox/datasource/security/SecureIdentityLoginModule.java +--- picketlink-orig/org/picketbox/datasource/security/SecureIdentityLoginModule.java 2023-12-17 08:04:11.736905774 +0100 ++++ picketlink/org/picketbox/datasource/security/SecureIdentityLoginModule.java 2023-12-17 08:04:43.356951936 +0100 +@@ -25,7 +25,7 @@ + import java.security.InvalidKeyException; + import java.security.NoSuchAlgorithmException; + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + + import javax.crypto.BadPaddingException; +diff -uNr picketlink-orig/org/picketbox/datasource/security/SubjectActions.java picketlink/org/picketbox/datasource/security/SubjectActions.java +--- picketlink-orig/org/picketbox/datasource/security/SubjectActions.java 2023-12-17 08:04:11.736905774 +0100 ++++ picketlink/org/picketbox/datasource/security/SubjectActions.java 2023-12-17 08:04:43.356951936 +0100 +@@ -24,7 +24,7 @@ + import java.security.AccessController; + import java.security.Principal; + import java.security.PrivilegedAction; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Iterator; + import java.util.Set; + +diff -uNr picketlink-orig/org/picketbox/plugins/authorization/PicketBoxAuthorizationModule.java picketlink/org/picketbox/plugins/authorization/PicketBoxAuthorizationModule.java +--- picketlink-orig/org/picketbox/plugins/authorization/PicketBoxAuthorizationModule.java 2023-12-17 08:04:11.736905774 +0100 ++++ picketlink/org/picketbox/plugins/authorization/PicketBoxAuthorizationModule.java 2023-12-17 08:04:43.352951930 +0100 +@@ -22,7 +22,7 @@ + package org.picketbox.plugins.authorization; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Enumeration; + import java.util.HashSet; + import java.util.Map; +diff -uNr picketlink-orig/org/picketbox/util/PicketBoxUtil.java picketlink/org/picketbox/util/PicketBoxUtil.java +--- picketlink-orig/org/picketbox/util/PicketBoxUtil.java 2023-12-17 08:04:11.736905774 +0100 ++++ picketlink/org/picketbox/util/PicketBoxUtil.java 2023-12-17 08:04:43.352951930 +0100 +@@ -22,7 +22,7 @@ + package org.picketbox.util; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Set; + + import javax.security.auth.Subject; +diff -uNr picketlink-orig/org/picketlink/identity/federation/bindings/jboss/auth/RegExUserNameLoginModule.java picketlink/org/picketlink/identity/federation/bindings/jboss/auth/RegExUserNameLoginModule.java +--- picketlink-orig/org/picketlink/identity/federation/bindings/jboss/auth/RegExUserNameLoginModule.java 2023-12-17 08:04:11.732905768 +0100 ++++ picketlink/org/picketlink/identity/federation/bindings/jboss/auth/RegExUserNameLoginModule.java 2023-12-17 08:04:43.352951930 +0100 +@@ -18,7 +18,7 @@ + package org.picketlink.identity.federation.bindings.jboss.auth; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Map; + import java.util.regex.Matcher; + import java.util.regex.Pattern; +diff -uNr picketlink-orig/org/picketlink/identity/federation/bindings/jboss/auth/SAML20CommonTokenRoleAttributeProvider.java picketlink/org/picketlink/identity/federation/bindings/jboss/auth/SAML20CommonTokenRoleAttributeProvider.java +--- picketlink-orig/org/picketlink/identity/federation/bindings/jboss/auth/SAML20CommonTokenRoleAttributeProvider.java 2023-12-17 08:04:11.732905768 +0100 ++++ picketlink/org/picketlink/identity/federation/bindings/jboss/auth/SAML20CommonTokenRoleAttributeProvider.java 2023-12-17 08:04:43.352951930 +0100 +@@ -1,7 +1,7 @@ + package org.picketlink.identity.federation.bindings.jboss.auth; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Enumeration; + import java.util.Map; + +diff -uNr picketlink-orig/org/picketlink/identity/federation/bindings/jboss/auth/SAML2CommonLoginModule.java picketlink/org/picketlink/identity/federation/bindings/jboss/auth/SAML2CommonLoginModule.java +--- picketlink-orig/org/picketlink/identity/federation/bindings/jboss/auth/SAML2CommonLoginModule.java 2023-12-17 08:04:11.732905768 +0100 ++++ picketlink/org/picketlink/identity/federation/bindings/jboss/auth/SAML2CommonLoginModule.java 2023-12-17 08:04:43.352951930 +0100 +@@ -22,7 +22,7 @@ + package org.picketlink.identity.federation.bindings.jboss.auth; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.List; + import java.util.Map; + +diff -uNr picketlink-orig/org/picketlink/identity/federation/bindings/jboss/auth/SAML2STSCommonLoginModule.java picketlink/org/picketlink/identity/federation/bindings/jboss/auth/SAML2STSCommonLoginModule.java +--- picketlink-orig/org/picketlink/identity/federation/bindings/jboss/auth/SAML2STSCommonLoginModule.java 2023-12-17 08:04:11.732905768 +0100 ++++ picketlink/org/picketlink/identity/federation/bindings/jboss/auth/SAML2STSCommonLoginModule.java 2023-12-17 08:04:43.352951930 +0100 +@@ -22,7 +22,7 @@ + package org.picketlink.identity.federation.bindings.jboss.auth; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.ArrayList; + import java.util.Date; + import java.util.HashMap; +diff -uNr picketlink-orig/org/picketlink/identity/federation/bindings/jboss/auth/SAMLTokenCertValidatingCommonLoginModule.java picketlink/org/picketlink/identity/federation/bindings/jboss/auth/SAMLTokenCertValidatingCommonLoginModule.java +--- picketlink-orig/org/picketlink/identity/federation/bindings/jboss/auth/SAMLTokenCertValidatingCommonLoginModule.java 2023-12-17 08:04:11.732905768 +0100 ++++ picketlink/org/picketlink/identity/federation/bindings/jboss/auth/SAMLTokenCertValidatingCommonLoginModule.java 2023-12-17 08:04:43.352951930 +0100 +@@ -24,7 +24,7 @@ + + import java.security.KeyStore; + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.security.cert.CertPath; + import java.security.cert.CertPathValidator; + import java.security.cert.CertPathValidatorResult; +diff -uNr picketlink-orig/org/picketlink/identity/federation/bindings/jboss/subject/PicketLinkGroup.java picketlink/org/picketlink/identity/federation/bindings/jboss/subject/PicketLinkGroup.java +--- picketlink-orig/org/picketlink/identity/federation/bindings/jboss/subject/PicketLinkGroup.java 2023-12-17 08:04:11.732905768 +0100 ++++ picketlink/org/picketlink/identity/federation/bindings/jboss/subject/PicketLinkGroup.java 2023-12-17 08:04:43.352951930 +0100 +@@ -22,7 +22,7 @@ + package org.picketlink.identity.federation.bindings.jboss.subject; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.Collections; + import java.util.Enumeration; + import java.util.HashSet; +@@ -46,7 +46,7 @@ + /** + * Add a role principal to group + * +- * @see java.security.acl.Group#addMember(java.security.Principal) ++ * @see org.jboss.security.Group#addMember(java.security.Principal) + */ + public boolean addMember(Principal role) { + return roles.add(role); +@@ -55,7 +55,7 @@ + /** + * Check if the role is a member of the group + * +- * @see java.security.acl.Group#isMember(java.security.Principal) ++ * @see org.jboss.security.Group#isMember(java.security.Principal) + */ + public boolean isMember(Principal role) { + return roles.contains(role); +@@ -64,7 +64,7 @@ + /** + * Get the group members + * +- * @see java.security.acl.Group#members() ++ * @see org.jboss.security.Group#members() + */ + public Enumeration members() { + Set readOnly = Collections.unmodifiableSet(roles); +@@ -74,7 +74,7 @@ + /** + * Remove role from groups + * +- * @see java.security.acl.Group#removeMember(java.security.Principal) ++ * @see org.jboss.security.Group#removeMember(java.security.Principal) + */ + public boolean removeMember(Principal user) { + return roles.remove(user); +diff -uNr picketlink-orig/org/picketlink/identity/federation/core/wstrust/auth/AbstractSTSLoginModule.java picketlink/org/picketlink/identity/federation/core/wstrust/auth/AbstractSTSLoginModule.java +--- picketlink-orig/org/picketlink/identity/federation/core/wstrust/auth/AbstractSTSLoginModule.java 2023-12-17 08:04:11.728905762 +0100 ++++ picketlink/org/picketlink/identity/federation/core/wstrust/auth/AbstractSTSLoginModule.java 2023-12-17 08:04:43.348951924 +0100 +@@ -57,7 +57,7 @@ + + import java.io.IOException; + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.ArrayList; + import java.util.HashMap; + import java.util.List; +diff -uNr picketlink-orig/org/picketlink/trust/jbossws/handler/AbstractSAML2Handler.java picketlink/org/picketlink/trust/jbossws/handler/AbstractSAML2Handler.java +--- picketlink-orig/org/picketlink/trust/jbossws/handler/AbstractSAML2Handler.java 2023-12-17 08:04:11.732905768 +0100 ++++ picketlink/org/picketlink/trust/jbossws/handler/AbstractSAML2Handler.java 2023-12-17 08:04:43.352951930 +0100 +@@ -22,7 +22,7 @@ + package org.picketlink.trust.jbossws.handler; + + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.ArrayList; + import java.util.List; + +diff -uNr picketlink-orig/org/picketlink/trust/jbossws/handler/SecurityActions.java picketlink/org/picketlink/trust/jbossws/handler/SecurityActions.java +--- picketlink-orig/org/picketlink/trust/jbossws/handler/SecurityActions.java 2023-12-17 08:04:11.732905768 +0100 ++++ picketlink/org/picketlink/trust/jbossws/handler/SecurityActions.java 2023-12-17 08:04:43.352951930 +0100 +@@ -24,7 +24,7 @@ + import java.security.AccessController; + import java.security.Principal; + import java.security.PrivilegedAction; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.List; + + import javax.security.auth.Subject; +diff -uNr picketlink-orig/org/picketlink/trust/jbossws/jaas/SAMLBearerTokenLoginModule.java picketlink/org/picketlink/trust/jbossws/jaas/SAMLBearerTokenLoginModule.java +--- picketlink-orig/org/picketlink/trust/jbossws/jaas/SAMLBearerTokenLoginModule.java 2023-12-17 08:04:11.732905768 +0100 ++++ picketlink/org/picketlink/trust/jbossws/jaas/SAMLBearerTokenLoginModule.java 2023-12-17 08:04:43.352951930 +0100 +@@ -22,7 +22,7 @@ + import java.io.InputStream; + import java.net.URI; + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.HashSet; + import java.util.List; + import java.util.Map; +diff -uNr picketlink-orig/org/picketlink/trust/jbossws/jaas/SAMLRoleLoginModule.java picketlink/org/picketlink/trust/jbossws/jaas/SAMLRoleLoginModule.java +--- picketlink-orig/org/picketlink/trust/jbossws/jaas/SAMLRoleLoginModule.java 2023-12-17 08:04:11.732905768 +0100 ++++ picketlink/org/picketlink/trust/jbossws/jaas/SAMLRoleLoginModule.java 2023-12-17 08:04:43.352951930 +0100 +@@ -23,7 +23,7 @@ + + import java.io.ByteArrayInputStream; + import java.security.Principal; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.List; + import java.util.Set; + +diff -uNr picketlink-orig/org/picketlink/trust/jbossws/util/SecurityActions.java picketlink/org/picketlink/trust/jbossws/util/SecurityActions.java +--- picketlink-orig/org/picketlink/trust/jbossws/util/SecurityActions.java 2023-12-17 08:04:11.732905768 +0100 ++++ picketlink/org/picketlink/trust/jbossws/util/SecurityActions.java 2023-12-17 08:04:43.352951930 +0100 +@@ -24,7 +24,7 @@ + import java.security.AccessController; + import java.security.Principal; + import java.security.PrivilegedAction; +-import java.security.acl.Group; ++import org.jboss.security.Group; + import java.util.List; + + import javax.security.auth.Subject; diff --git a/picketlink-saml/src/main/patches/javax.servlet.patch b/picketlink-saml/src/main/patches/javax.servlet.patch new file mode 100644 index 000000000..7b5d590fd --- /dev/null +++ b/picketlink-saml/src/main/patches/javax.servlet.patch @@ -0,0 +1,813 @@ +diff -uNr picketlink-orig/org/jboss/security/auth/container/modules/HttpServletServerAuthModule.java picketlink/org/jboss/security/auth/container/modules/HttpServletServerAuthModule.java +--- picketlink-orig/org/jboss/security/auth/container/modules/HttpServletServerAuthModule.java 2023-12-17 08:04:43.420952029 +0100 ++++ picketlink/org/jboss/security/auth/container/modules/HttpServletServerAuthModule.java 2023-12-17 08:05:07.608987531 +0100 +@@ -27,8 +27,8 @@ + import javax.security.auth.message.AuthException; + import javax.security.auth.message.AuthStatus; + import javax.security.auth.message.MessageInfo; +-import javax.servlet.http.HttpServletRequest; +-import javax.servlet.http.HttpServletResponse; ++import jakarta.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletResponse; + + import org.jboss.security.PicketBoxMessages; + import org.jboss.security.SimplePrincipal; +diff -uNr picketlink-orig/org/jboss/security/auth/spi/otp/JBossTimeBasedOTPLoginModule.java picketlink/org/jboss/security/auth/spi/otp/JBossTimeBasedOTPLoginModule.java +--- picketlink-orig/org/jboss/security/auth/spi/otp/JBossTimeBasedOTPLoginModule.java 2023-12-17 08:04:43.420952029 +0100 ++++ picketlink/org/jboss/security/auth/spi/otp/JBossTimeBasedOTPLoginModule.java 2023-12-17 08:05:07.608987531 +0100 +@@ -41,7 +41,7 @@ + import javax.security.auth.spi.LoginModule; + import javax.security.jacc.PolicyContext; + import javax.security.jacc.PolicyContextException; +-import javax.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletRequest; + + import org.jboss.security.PicketBoxLogger; + import org.jboss.security.PicketBoxMessages; +@@ -310,7 +310,7 @@ + String totp = null; + + //This is JBoss AS specific mechanism +- String WEB_REQUEST_KEY = "javax.servlet.http.HttpServletRequest"; ++ String WEB_REQUEST_KEY = "jakarta.servlet.http.HttpServletRequest"; + + try + { +diff -uNr picketlink-orig/org/jboss/security/authorization/modules/web/WebJACCPolicyModuleDelegate.java picketlink/org/jboss/security/authorization/modules/web/WebJACCPolicyModuleDelegate.java +--- picketlink-orig/org/jboss/security/authorization/modules/web/WebJACCPolicyModuleDelegate.java 2023-12-17 08:04:43.412952017 +0100 ++++ picketlink/org/jboss/security/authorization/modules/web/WebJACCPolicyModuleDelegate.java 2023-12-17 08:05:07.600987519 +0100 +@@ -34,7 +34,7 @@ + import javax.security.jacc.WebResourcePermission; + import javax.security.jacc.WebRoleRefPermission; + import javax.security.jacc.WebUserDataPermission; +-import javax.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletRequest; + + import org.jboss.security.PicketBoxLogger; + import org.jboss.security.PicketBoxMessages; +diff -uNr picketlink-orig/org/jboss/security/authorization/modules/web/WebXACMLPolicyModuleDelegate.java picketlink/org/jboss/security/authorization/modules/web/WebXACMLPolicyModuleDelegate.java +--- picketlink-orig/org/jboss/security/authorization/modules/web/WebXACMLPolicyModuleDelegate.java 2023-12-17 08:04:43.412952017 +0100 ++++ picketlink/org/jboss/security/authorization/modules/web/WebXACMLPolicyModuleDelegate.java 2023-12-17 08:05:07.600987519 +0100 +@@ -26,7 +26,7 @@ + + import javax.security.auth.Subject; + import javax.security.jacc.PolicyContext; +-import javax.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletRequest; + + import org.jboss.security.PicketBoxLogger; + import org.jboss.security.PicketBoxMessages; +diff -uNr picketlink-orig/org/jboss/security/authorization/modules/web/WebXACMLUtil.java picketlink/org/jboss/security/authorization/modules/web/WebXACMLUtil.java +--- picketlink-orig/org/jboss/security/authorization/modules/web/WebXACMLUtil.java 2023-12-17 08:04:43.412952017 +0100 ++++ picketlink/org/jboss/security/authorization/modules/web/WebXACMLUtil.java 2023-12-17 08:05:07.600987519 +0100 +@@ -29,7 +29,7 @@ + import java.util.Enumeration; + import java.util.List; + +-import javax.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletRequest; + + import org.jboss.security.PicketBoxLogger; + import org.jboss.security.PicketBoxMessages; +diff -uNr picketlink-orig/org/jboss/security/authorization/resources/WebResource.java picketlink/org/jboss/security/authorization/resources/WebResource.java +--- picketlink-orig/org/jboss/security/authorization/resources/WebResource.java 2023-12-17 08:04:43.412952017 +0100 ++++ picketlink/org/jboss/security/authorization/resources/WebResource.java 2023-12-17 08:05:07.600987519 +0100 +@@ -25,9 +25,9 @@ + import java.util.Enumeration; + import java.util.Map; + +-import javax.servlet.ServletRequest; +-import javax.servlet.ServletResponse; +-import javax.servlet.http.HttpServletRequest; ++import jakarta.servlet.ServletRequest; ++import jakarta.servlet.ServletResponse; ++import jakarta.servlet.http.HttpServletRequest; + + import org.jboss.security.authorization.Resource; + import org.jboss.security.authorization.ResourceType; +diff -uNr picketlink-orig/org/jboss/security/javaee/AbstractWebAuthorizationHelper.java picketlink/org/jboss/security/javaee/AbstractWebAuthorizationHelper.java +--- picketlink-orig/org/jboss/security/javaee/AbstractWebAuthorizationHelper.java 2023-12-17 08:04:43.416952023 +0100 ++++ picketlink/org/jboss/security/javaee/AbstractWebAuthorizationHelper.java 2023-12-17 08:05:07.604987525 +0100 +@@ -27,8 +27,8 @@ + import java.util.Set; + + import javax.security.auth.Subject; +-import javax.servlet.ServletRequest; +-import javax.servlet.ServletResponse; ++import jakarta.servlet.ServletRequest; ++import jakarta.servlet.ServletResponse; + + /** + * Abstract Web Authorization Helper +diff -uNr picketlink-orig/org/jboss/security/plugins/javaee/WebAuthorizationHelper.java picketlink/org/jboss/security/plugins/javaee/WebAuthorizationHelper.java +--- picketlink-orig/org/jboss/security/plugins/javaee/WebAuthorizationHelper.java 2023-12-17 08:04:43.424952035 +0100 ++++ picketlink/org/jboss/security/plugins/javaee/WebAuthorizationHelper.java 2023-12-17 08:05:07.612987537 +0100 +@@ -29,8 +29,8 @@ + import java.util.Set; + + import javax.security.auth.Subject; +-import javax.servlet.ServletRequest; +-import javax.servlet.ServletResponse; ++import jakarta.servlet.ServletRequest; ++import jakarta.servlet.ServletResponse; + + import org.jboss.security.AuthorizationManager; + import org.jboss.security.PicketBoxLogger; +diff -uNr picketlink-orig/org/jboss/security/SecurityConstants.java picketlink/org/jboss/security/SecurityConstants.java +--- picketlink-orig/org/jboss/security/SecurityConstants.java 2023-12-17 08:04:43.408952012 +0100 ++++ picketlink/org/jboss/security/SecurityConstants.java 2023-12-17 08:05:07.596987514 +0100 +@@ -100,7 +100,7 @@ + + /** Policy Context Constants **/ + String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container"; +- String WEB_REQUEST_KEY = "javax.servlet.http.HttpServletRequest"; ++ String WEB_REQUEST_KEY = "jakarta.servlet.http.HttpServletRequest"; + String CALLBACK_HANDLER_KEY = "org.jboss.security.auth.spi.CallbackHandler"; + + /** +diff -uNr picketlink-orig/org/picketlink/identity/federation/bindings/jboss/auth/SAMLTokenFromHttpRequestAbstractLoginModule.java picketlink/org/picketlink/identity/federation/bindings/jboss/auth/SAMLTokenFromHttpRequestAbstractLoginModule.java +--- picketlink-orig/org/picketlink/identity/federation/bindings/jboss/auth/SAMLTokenFromHttpRequestAbstractLoginModule.java 2023-12-17 08:04:43.404952006 +0100 ++++ picketlink/org/picketlink/identity/federation/bindings/jboss/auth/SAMLTokenFromHttpRequestAbstractLoginModule.java 2023-12-17 08:05:07.592987508 +0100 +@@ -29,7 +29,7 @@ + import javax.security.auth.Subject; + import javax.security.auth.callback.CallbackHandler; + import javax.security.jacc.PolicyContext; +-import javax.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletRequest; + + import org.jboss.security.auth.spi.AbstractServerLoginModule; + import org.picketlink.common.PicketLinkLogger; +@@ -98,7 +98,7 @@ + */ + public static final String BASE64_TOKEN_ENCODING = "base64"; + +- public static final String WEB_REQUEST_KEY = "javax.servlet.http.HttpServletRequest"; ++ public static final String WEB_REQUEST_KEY = "jakarta.servlet.http.HttpServletRequest"; + public static final String REG_EX_PATTERN_KEY = "samlTokenHttpHeaderRegEx"; + public static final String REG_EX_GROUP_KEY = "samlTokenHttpHeaderRegExGroup"; + public static final String SAML_TOKEN_HTTP_HEADER_KEY = "samlTokenHttpHeader"; +diff -uNr picketlink-orig/org/picketlink/identity/federation/bindings/jboss/roles/JBossWebRoleGenerator.java picketlink/org/picketlink/identity/federation/bindings/jboss/roles/JBossWebRoleGenerator.java +--- picketlink-orig/org/picketlink/identity/federation/bindings/jboss/roles/JBossWebRoleGenerator.java 2023-12-17 08:04:43.404952006 +0100 ++++ picketlink/org/picketlink/identity/federation/bindings/jboss/roles/JBossWebRoleGenerator.java 2023-12-17 08:05:07.592987508 +0100 +@@ -23,7 +23,7 @@ + + import javax.security.jacc.PolicyContext; + import javax.security.jacc.PolicyContextException; +-import javax.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletRequest; + import java.security.Principal; + import java.util.List; + +@@ -39,7 +39,7 @@ + //Use JACC to get the request + try { + HttpServletRequest request = +- (HttpServletRequest) PolicyContext.getContext("javax.servlet.http.HttpServletRequest"); ++ (HttpServletRequest) PolicyContext.getContext("jakarta.servlet.http.HttpServletRequest"); + if(request instanceof Request){ + Request catalinaRequest = (Request) request; + return super.generateRoles(catalinaRequest.getPrincipal()); +diff -uNr picketlink-orig/org/picketlink/identity/federation/core/audit/PicketLinkAuditHelper.java picketlink/org/picketlink/identity/federation/core/audit/PicketLinkAuditHelper.java +--- picketlink-orig/org/picketlink/identity/federation/core/audit/PicketLinkAuditHelper.java 2023-12-17 08:04:43.396951994 +0100 ++++ picketlink/org/picketlink/identity/federation/core/audit/PicketLinkAuditHelper.java 2023-12-17 08:05:07.584987496 +0100 +@@ -35,7 +35,7 @@ + import javax.naming.Context; + import javax.naming.InitialContext; + import javax.naming.NamingException; +-import javax.servlet.ServletContext; ++import jakarta.servlet.ServletContext; + import java.io.InputStream; + + /** +diff -uNr picketlink-orig/org/picketlink/identity/federation/core/saml/workflow/ServiceProviderSAMLWorkflow.java picketlink/org/picketlink/identity/federation/core/saml/workflow/ServiceProviderSAMLWorkflow.java +--- picketlink-orig/org/picketlink/identity/federation/core/saml/workflow/ServiceProviderSAMLWorkflow.java 2023-12-17 08:04:43.400952000 +0100 ++++ picketlink/org/picketlink/identity/federation/core/saml/workflow/ServiceProviderSAMLWorkflow.java 2023-12-17 08:05:07.588987502 +0100 +@@ -29,12 +29,12 @@ + import org.picketlink.identity.federation.web.util.RedirectBindingUtil; + import org.w3c.dom.Document; + +-import javax.servlet.RequestDispatcher; +-import javax.servlet.ServletContext; +-import javax.servlet.ServletException; +-import javax.servlet.http.HttpServletRequest; +-import javax.servlet.http.HttpServletResponse; +-import javax.servlet.http.HttpSession; ++import jakarta.servlet.RequestDispatcher; ++import jakarta.servlet.ServletContext; ++import jakarta.servlet.ServletException; ++import jakarta.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletResponse; ++import jakarta.servlet.http.HttpSession; + + import java.io.IOException; + +@@ -215,7 +215,7 @@ + /** + * Send the payload via HTTP/POST + * @param destinationHolder {@link org.picketlink.identity.federation.core.saml.v2.holders.DestinationInfoHolder} holds info on the destination +- * @param response {@link javax.servlet.http.HttpServletResponse} ++ * @param response {@link jakarta.servlet.http.HttpServletResponse} + * @param willSendRequest whether it is a SAML request or response so that the page title can be set + * @throws IOException + */ +@@ -226,7 +226,7 @@ + /** + * Send the payload via HTTP/REDIRECT + * @param url the redirect url +- * @param response {@link javax.servlet.http.HttpServletResponse} ++ * @param response {@link jakarta.servlet.http.HttpServletResponse} + * @throws IOException + */ + public void sendRedirectForRequestor(String url, HttpServletResponse response) throws IOException { +@@ -236,7 +236,7 @@ + /** + * Send the payload via HTTP/REDIRECT + * @param destination the destination url +- * @param response {@link javax.servlet.http.HttpServletResponse} ++ * @param response {@link jakarta.servlet.http.HttpServletResponse} + * @throws IOException + */ + public void sendRedirectForResponder(String destination, HttpServletResponse response) throws IOException { +diff -uNr picketlink-orig/org/picketlink/identity/federation/core/util/CoreConfigUtil.java picketlink/org/picketlink/identity/federation/core/util/CoreConfigUtil.java +--- picketlink-orig/org/picketlink/identity/federation/core/util/CoreConfigUtil.java 2023-12-17 08:04:43.396951994 +0100 ++++ picketlink/org/picketlink/identity/federation/core/util/CoreConfigUtil.java 2023-12-17 08:05:07.580987490 +0100 +@@ -49,7 +49,7 @@ + import javax.crypto.SecretKeyFactory; + import javax.crypto.spec.PBEKeySpec; + import javax.crypto.spec.PBEParameterSpec; +-import javax.servlet.ServletContext; ++import jakarta.servlet.ServletContext; + import java.io.UnsupportedEncodingException; + import java.security.GeneralSecurityException; + import java.security.PublicKey; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/config/IdentityURLConfigurationProvider.java picketlink/org/picketlink/identity/federation/web/config/IdentityURLConfigurationProvider.java +--- picketlink-orig/org/picketlink/identity/federation/web/config/IdentityURLConfigurationProvider.java 2023-12-17 08:04:43.388951982 +0100 ++++ picketlink/org/picketlink/identity/federation/web/config/IdentityURLConfigurationProvider.java 2023-12-17 08:05:07.572987479 +0100 +@@ -1,6 +1,6 @@ + package org.picketlink.identity.federation.web.config; + +-import javax.servlet.ServletContext; ++import jakarta.servlet.ServletContext; + import java.io.IOException; + import java.util.Map; + +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/config/PropertiesIdentityURLProvider.java picketlink/org/picketlink/identity/federation/web/config/PropertiesIdentityURLProvider.java +--- picketlink-orig/org/picketlink/identity/federation/web/config/PropertiesIdentityURLProvider.java 2023-12-17 08:04:43.388951982 +0100 ++++ picketlink/org/picketlink/identity/federation/web/config/PropertiesIdentityURLProvider.java 2023-12-17 08:05:07.572987479 +0100 +@@ -17,7 +17,7 @@ + */ + package org.picketlink.identity.federation.web.config; + +-import javax.servlet.ServletContext; ++import jakarta.servlet.ServletContext; + import java.io.IOException; + import java.io.InputStream; + import java.util.HashMap; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/core/HTTPContext.java picketlink/org/picketlink/identity/federation/web/core/HTTPContext.java +--- picketlink-orig/org/picketlink/identity/federation/web/core/HTTPContext.java 2023-12-17 08:04:43.388951982 +0100 ++++ picketlink/org/picketlink/identity/federation/web/core/HTTPContext.java 2023-12-17 08:05:07.572987479 +0100 +@@ -20,9 +20,9 @@ + import org.picketlink.identity.federation.core.interfaces.ProtocolContext; + import org.picketlink.identity.federation.core.interfaces.SecurityTokenProvider; + +-import javax.servlet.ServletContext; +-import javax.servlet.http.HttpServletRequest; +-import javax.servlet.http.HttpServletResponse; ++import jakarta.servlet.ServletContext; ++import jakarta.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletResponse; + import javax.xml.namespace.QName; + + /** +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/core/IdentityServer.java picketlink/org/picketlink/identity/federation/web/core/IdentityServer.java +--- picketlink-orig/org/picketlink/identity/federation/web/core/IdentityServer.java 2023-12-17 08:04:43.388951982 +0100 ++++ picketlink/org/picketlink/identity/federation/web/core/IdentityServer.java 2023-12-17 08:05:07.572987479 +0100 +@@ -21,10 +21,10 @@ + import org.picketlink.common.PicketLinkLoggerFactory; + import org.picketlink.common.constants.GeneralConstants; + +-import javax.servlet.ServletContext; +-import javax.servlet.http.HttpSession; +-import javax.servlet.http.HttpSessionEvent; +-import javax.servlet.http.HttpSessionListener; ++import jakarta.servlet.ServletContext; ++import jakarta.servlet.http.HttpSession; ++import jakarta.servlet.http.HttpSessionEvent; ++import jakarta.servlet.http.HttpSessionListener; + import java.security.AccessController; + import java.security.PrivilegedAction; + import java.util.HashSet; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/filters/IDPFilter.java picketlink/org/picketlink/identity/federation/web/filters/IDPFilter.java +--- picketlink-orig/org/picketlink/identity/federation/web/filters/IDPFilter.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/filters/IDPFilter.java 2023-12-17 08:05:07.572987479 +0100 +@@ -112,18 +112,18 @@ + import org.picketlink.identity.federation.web.util.SAMLConfigurationProvider; + import org.w3c.dom.Document; + +-import javax.servlet.Filter; +-import javax.servlet.FilterChain; +-import javax.servlet.FilterConfig; +-import javax.servlet.RequestDispatcher; +-import javax.servlet.ServletContext; +-import javax.servlet.ServletException; +-import javax.servlet.ServletRequest; +-import javax.servlet.ServletResponse; +-import javax.servlet.http.HttpServletRequest; +-import javax.servlet.http.HttpServletRequestWrapper; +-import javax.servlet.http.HttpServletResponse; +-import javax.servlet.http.HttpSession; ++import jakarta.servlet.Filter; ++import jakarta.servlet.FilterChain; ++import jakarta.servlet.FilterConfig; ++import jakarta.servlet.RequestDispatcher; ++import jakarta.servlet.ServletContext; ++import jakarta.servlet.ServletException; ++import jakarta.servlet.ServletRequest; ++import jakarta.servlet.ServletResponse; ++import jakarta.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletRequestWrapper; ++import jakarta.servlet.http.HttpServletResponse; ++import jakarta.servlet.http.HttpSession; + + import static org.picketlink.common.constants.GeneralConstants.AUDIT_HELPER; + import static org.picketlink.common.constants.GeneralConstants.CONFIGURATION; +@@ -134,7 +134,7 @@ + import static org.picketlink.common.util.StringUtil.isNullOrEmpty; + + /** +- * A {@link javax.servlet.Filter} that can be configured to convert a ++ * A {@link jakarta.servlet.Filter} that can be configured to convert a + * JavaEE Web Application to an IDP + * + * @author Anil Saldhana +@@ -1385,7 +1385,7 @@ + } + + /** +- *

Checks if the given {@link javax.servlet.http.HttpServletRequest} containes a SAML11 Target parameter. Usually this indicates that the given request is ++ *

Checks if the given {@link jakarta.servlet.http.HttpServletRequest} containes a SAML11 Target parameter. Usually this indicates that the given request is + * a SAML11 request.

+ * + * @param request +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/filters/SPFilter.java picketlink/org/picketlink/identity/federation/web/filters/SPFilter.java +--- picketlink-orig/org/picketlink/identity/federation/web/filters/SPFilter.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/filters/SPFilter.java 2023-12-17 08:05:07.572987479 +0100 +@@ -81,17 +81,17 @@ + import org.w3c.dom.Node; + import org.xml.sax.SAXException; + +-import javax.servlet.Filter; +-import javax.servlet.FilterChain; +-import javax.servlet.FilterConfig; +-import javax.servlet.RequestDispatcher; +-import javax.servlet.ServletContext; +-import javax.servlet.ServletException; +-import javax.servlet.ServletRequest; +-import javax.servlet.ServletResponse; +-import javax.servlet.http.HttpServletRequest; +-import javax.servlet.http.HttpServletResponse; +-import javax.servlet.http.HttpSession; ++import jakarta.servlet.Filter; ++import jakarta.servlet.FilterChain; ++import jakarta.servlet.FilterConfig; ++import jakarta.servlet.RequestDispatcher; ++import jakarta.servlet.ServletContext; ++import jakarta.servlet.ServletException; ++import jakarta.servlet.ServletRequest; ++import jakarta.servlet.ServletResponse; ++import jakarta.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletResponse; ++import jakarta.servlet.http.HttpSession; + import javax.xml.crypto.MarshalException; + import javax.xml.crypto.dsig.CanonicalizationMethod; + import javax.xml.crypto.dsig.XMLSignatureException; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/handlers/saml2/BaseSAML2Handler.java picketlink/org/picketlink/identity/federation/web/handlers/saml2/BaseSAML2Handler.java +--- picketlink-orig/org/picketlink/identity/federation/web/handlers/saml2/BaseSAML2Handler.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/handlers/saml2/BaseSAML2Handler.java 2023-12-17 08:05:07.572987479 +0100 +@@ -32,8 +32,8 @@ + import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2HandlerResponse; + import org.picketlink.identity.federation.web.core.HTTPContext; + +-import javax.servlet.http.HttpServletRequest; +-import javax.servlet.http.HttpSession; ++import jakarta.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpSession; + import java.net.URI; + + /** +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/handlers/saml2/RolesGenerationHandler.java picketlink/org/picketlink/identity/federation/web/handlers/saml2/RolesGenerationHandler.java +--- picketlink-orig/org/picketlink/identity/federation/web/handlers/saml2/RolesGenerationHandler.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/handlers/saml2/RolesGenerationHandler.java 2023-12-17 08:05:07.572987479 +0100 +@@ -34,7 +34,7 @@ + import org.picketlink.identity.federation.saml.v2.protocol.LogoutRequestType; + import org.picketlink.identity.federation.web.core.HTTPContext; + +-import javax.servlet.http.HttpSession; ++import jakarta.servlet.http.HttpSession; + import java.security.Principal; + import java.util.Arrays; + import java.util.List; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/handlers/saml2/SAML2AttributeHandler.java picketlink/org/picketlink/identity/federation/web/handlers/saml2/SAML2AttributeHandler.java +--- picketlink-orig/org/picketlink/identity/federation/web/handlers/saml2/SAML2AttributeHandler.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/handlers/saml2/SAML2AttributeHandler.java 2023-12-17 08:05:07.572987479 +0100 +@@ -37,7 +37,7 @@ + import org.picketlink.identity.federation.saml.v2.protocol.ResponseType; + import org.picketlink.identity.federation.web.core.HTTPContext; + +-import javax.servlet.http.HttpSession; ++import jakarta.servlet.http.HttpSession; + import java.security.Principal; + import java.util.ArrayList; + import java.util.HashMap; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/handlers/saml2/SAML2AuthenticationHandler.java picketlink/org/picketlink/identity/federation/web/handlers/saml2/SAML2AuthenticationHandler.java +--- picketlink-orig/org/picketlink/identity/federation/web/handlers/saml2/SAML2AuthenticationHandler.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/handlers/saml2/SAML2AuthenticationHandler.java 2023-12-17 08:05:07.572987479 +0100 +@@ -78,8 +78,8 @@ + import org.w3c.dom.Element; + import org.w3c.dom.Node; + +-import javax.servlet.ServletContext; +-import javax.servlet.http.HttpSession; ++import jakarta.servlet.ServletContext; ++import jakarta.servlet.http.HttpSession; + import javax.xml.namespace.QName; + import java.net.URI; + import java.security.Principal; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/handlers/saml2/SAML2InResponseToVerificationHandler.java picketlink/org/picketlink/identity/federation/web/handlers/saml2/SAML2InResponseToVerificationHandler.java +--- picketlink-orig/org/picketlink/identity/federation/web/handlers/saml2/SAML2InResponseToVerificationHandler.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/handlers/saml2/SAML2InResponseToVerificationHandler.java 2023-12-17 08:05:07.572987479 +0100 +@@ -24,7 +24,7 @@ + import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2HandlerResponse; + import org.picketlink.identity.federation.saml.v2.protocol.ResponseType; + +-import javax.servlet.http.HttpSession; ++import jakarta.servlet.http.HttpSession; + + /** + * Handler is useful on SP side. It's used for verification that InResponseId from SAML Authentication Response is same +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/handlers/saml2/SAML2LogOutHandler.java picketlink/org/picketlink/identity/federation/web/handlers/saml2/SAML2LogOutHandler.java +--- picketlink-orig/org/picketlink/identity/federation/web/handlers/saml2/SAML2LogOutHandler.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/handlers/saml2/SAML2LogOutHandler.java 2023-12-17 08:05:07.572987479 +0100 +@@ -48,9 +48,9 @@ + import org.picketlink.identity.federation.web.core.IdentityServer; + import org.picketlink.identity.federation.web.util.RedirectBindingUtil; + +-import javax.servlet.ServletContext; +-import javax.servlet.http.HttpServletRequest; +-import javax.servlet.http.HttpSession; ++import jakarta.servlet.ServletContext; ++import jakarta.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpSession; + import javax.xml.parsers.ParserConfigurationException; + import java.io.IOException; + import java.net.URI; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/handlers/saml2/SAML2SignatureValidationHandler.java picketlink/org/picketlink/identity/federation/web/handlers/saml2/SAML2SignatureValidationHandler.java +--- picketlink-orig/org/picketlink/identity/federation/web/handlers/saml2/SAML2SignatureValidationHandler.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/handlers/saml2/SAML2SignatureValidationHandler.java 2023-12-17 08:05:07.572987479 +0100 +@@ -32,7 +32,7 @@ + import org.picketlink.identity.federation.web.util.RedirectBindingSignatureUtil; + import org.w3c.dom.Document; + +-import javax.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletRequest; + import java.security.PublicKey; + import java.util.Map; + +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/listeners/IDPHttpSessionListener.java picketlink/org/picketlink/identity/federation/web/listeners/IDPHttpSessionListener.java +--- picketlink-orig/org/picketlink/identity/federation/web/listeners/IDPHttpSessionListener.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/listeners/IDPHttpSessionListener.java 2023-12-17 08:05:07.572987479 +0100 +@@ -25,9 +25,9 @@ + import org.picketlink.identity.federation.core.sts.PicketLinkCoreSTS; + import org.picketlink.identity.federation.saml.v2.assertion.AssertionType; + +-import javax.servlet.http.HttpSession; +-import javax.servlet.http.HttpSessionEvent; +-import javax.servlet.http.HttpSessionListener; ++import jakarta.servlet.http.HttpSession; ++import jakarta.servlet.http.HttpSessionEvent; ++import jakarta.servlet.http.HttpSessionListener; + + /** + * An instance of {@link HttpSessionListener} at the IDP that performs actions when an {@link HttpSession} is created +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/process/ServiceProviderBaseProcessor.java picketlink/org/picketlink/identity/federation/web/process/ServiceProviderBaseProcessor.java +--- picketlink-orig/org/picketlink/identity/federation/web/process/ServiceProviderBaseProcessor.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/process/ServiceProviderBaseProcessor.java 2023-12-17 08:05:07.572987479 +0100 +@@ -44,7 +44,7 @@ + import org.picketlink.identity.federation.saml.v2.metadata.IDPSSODescriptorType; + import org.picketlink.identity.federation.web.core.HTTPContext; + +-import javax.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletRequest; + import java.io.IOException; + import java.net.URL; + import java.security.PublicKey; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/process/ServiceProviderSAMLRequestProcessor.java picketlink/org/picketlink/identity/federation/web/process/ServiceProviderSAMLRequestProcessor.java +--- picketlink-orig/org/picketlink/identity/federation/web/process/ServiceProviderSAMLRequestProcessor.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/process/ServiceProviderSAMLRequestProcessor.java 2023-12-17 08:05:07.572987479 +0100 +@@ -38,7 +38,7 @@ + import org.picketlink.identity.federation.web.util.RedirectBindingUtil.RedirectBindingUtilDestHolder; + import org.w3c.dom.Document; + +-import javax.servlet.http.HttpServletResponse; ++import jakarta.servlet.http.HttpServletResponse; + import java.io.IOException; + import java.io.InputStream; + import java.util.Set; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/servlets/IDPLoginServlet.java picketlink/org/picketlink/identity/federation/web/servlets/IDPLoginServlet.java +--- picketlink-orig/org/picketlink/identity/federation/web/servlets/IDPLoginServlet.java 2023-12-17 08:04:43.388951982 +0100 ++++ picketlink/org/picketlink/identity/federation/web/servlets/IDPLoginServlet.java 2023-12-17 08:05:07.572987479 +0100 +@@ -23,14 +23,14 @@ + import org.picketlink.identity.federation.web.interfaces.ILoginHandler; + + import javax.security.auth.login.LoginException; +-import javax.servlet.RequestDispatcher; +-import javax.servlet.ServletConfig; +-import javax.servlet.ServletContext; +-import javax.servlet.ServletException; +-import javax.servlet.http.HttpServlet; +-import javax.servlet.http.HttpServletRequest; +-import javax.servlet.http.HttpServletResponse; +-import javax.servlet.http.HttpSession; ++import jakarta.servlet.RequestDispatcher; ++import jakarta.servlet.ServletConfig; ++import jakarta.servlet.ServletContext; ++import jakarta.servlet.ServletException; ++import jakarta.servlet.http.HttpServlet; ++import jakarta.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletResponse; ++import jakarta.servlet.http.HttpSession; + import java.io.IOException; + import java.security.Principal; + +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/servlets/IDPServlet.java picketlink/org/picketlink/identity/federation/web/servlets/IDPServlet.java +--- picketlink-orig/org/picketlink/identity/federation/web/servlets/IDPServlet.java 2023-12-17 08:04:43.388951982 +0100 ++++ picketlink/org/picketlink/identity/federation/web/servlets/IDPServlet.java 2023-12-17 08:05:07.572987479 +0100 +@@ -68,13 +68,13 @@ + import org.picketlink.identity.federation.web.util.SAMLConfigurationProvider; + import org.w3c.dom.Document; + +-import javax.servlet.ServletConfig; +-import javax.servlet.ServletContext; +-import javax.servlet.ServletException; +-import javax.servlet.http.HttpServlet; +-import javax.servlet.http.HttpServletRequest; +-import javax.servlet.http.HttpServletResponse; +-import javax.servlet.http.HttpSession; ++import jakarta.servlet.ServletConfig; ++import jakarta.servlet.ServletContext; ++import jakarta.servlet.ServletException; ++import jakarta.servlet.http.HttpServlet; ++import jakarta.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletResponse; ++import jakarta.servlet.http.HttpSession; + import javax.xml.crypto.dsig.CanonicalizationMethod; + import java.io.File; + import java.io.IOException; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/servlets/saml/CircleOfTrustServlet.java picketlink/org/picketlink/identity/federation/web/servlets/saml/CircleOfTrustServlet.java +--- picketlink-orig/org/picketlink/identity/federation/web/servlets/saml/CircleOfTrustServlet.java 2023-12-17 08:04:43.388951982 +0100 ++++ picketlink/org/picketlink/identity/federation/web/servlets/saml/CircleOfTrustServlet.java 2023-12-17 08:05:07.572987479 +0100 +@@ -22,12 +22,12 @@ + import org.picketlink.identity.federation.core.saml.v2.metadata.store.IMetadataConfigurationStore; + import org.picketlink.identity.federation.saml.v2.metadata.EntityDescriptorType; + +-import javax.servlet.ServletConfig; +-import javax.servlet.ServletException; +-import javax.servlet.http.HttpServlet; +-import javax.servlet.http.HttpServletRequest; +-import javax.servlet.http.HttpServletResponse; +-import javax.servlet.http.HttpSession; ++import jakarta.servlet.ServletConfig; ++import jakarta.servlet.ServletException; ++import jakarta.servlet.http.HttpServlet; ++import jakarta.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletResponse; ++import jakarta.servlet.http.HttpSession; + import java.io.IOException; + import java.util.HashMap; + import java.util.Map; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/servlets/saml/MetadataServlet.java picketlink/org/picketlink/identity/federation/web/servlets/saml/MetadataServlet.java +--- picketlink-orig/org/picketlink/identity/federation/web/servlets/saml/MetadataServlet.java 2023-12-17 08:04:43.388951982 +0100 ++++ picketlink/org/picketlink/identity/federation/web/servlets/saml/MetadataServlet.java 2023-12-17 08:05:07.572987479 +0100 +@@ -42,12 +42,12 @@ + import org.picketlink.identity.federation.web.util.ConfigurationUtil; + import org.w3c.dom.Element; + +-import javax.servlet.ServletConfig; +-import javax.servlet.ServletContext; +-import javax.servlet.ServletException; +-import javax.servlet.http.HttpServlet; +-import javax.servlet.http.HttpServletRequest; +-import javax.servlet.http.HttpServletResponse; ++import jakarta.servlet.ServletConfig; ++import jakarta.servlet.ServletContext; ++import jakarta.servlet.ServletException; ++import jakarta.servlet.http.HttpServlet; ++import jakarta.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletResponse; + import javax.xml.stream.XMLStreamWriter; + import java.io.IOException; + import java.io.InputStream; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/servlets/saml/MetadataServletSP.java picketlink/org/picketlink/identity/federation/web/servlets/saml/MetadataServletSP.java +--- picketlink-orig/org/picketlink/identity/federation/web/servlets/saml/MetadataServletSP.java 2023-12-17 08:04:43.388951982 +0100 ++++ picketlink/org/picketlink/identity/federation/web/servlets/saml/MetadataServletSP.java 2023-12-17 08:05:07.572987479 +0100 +@@ -34,12 +34,12 @@ + import java.util.List; + import java.util.Map; + +-import javax.servlet.ServletConfig; +-import javax.servlet.ServletContext; +-import javax.servlet.ServletException; +-import javax.servlet.http.HttpServlet; +-import javax.servlet.http.HttpServletRequest; +-import javax.servlet.http.HttpServletResponse; ++import jakarta.servlet.ServletConfig; ++import jakarta.servlet.ServletContext; ++import jakarta.servlet.ServletException; ++import jakarta.servlet.http.HttpServlet; ++import jakarta.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletResponse; + import javax.xml.crypto.dsig.DigestMethod; + import javax.xml.crypto.dsig.SignatureMethod; + import javax.xml.parsers.DocumentBuilderFactory; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/servlets/saml/SOAPSAMLXACMLServlet.java picketlink/org/picketlink/identity/federation/web/servlets/saml/SOAPSAMLXACMLServlet.java +--- picketlink-orig/org/picketlink/identity/federation/web/servlets/saml/SOAPSAMLXACMLServlet.java 2023-12-17 08:04:43.388951982 +0100 ++++ picketlink/org/picketlink/identity/federation/web/servlets/saml/SOAPSAMLXACMLServlet.java 2023-12-17 08:05:07.572987479 +0100 +@@ -37,11 +37,11 @@ + import org.w3c.dom.Node; + import org.w3c.dom.NodeList; + +-import javax.servlet.ServletConfig; +-import javax.servlet.ServletException; +-import javax.servlet.http.HttpServlet; +-import javax.servlet.http.HttpServletRequest; +-import javax.servlet.http.HttpServletResponse; ++import jakarta.servlet.ServletConfig; ++import jakarta.servlet.ServletException; ++import jakarta.servlet.http.HttpServlet; ++import jakarta.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletResponse; + import javax.xml.soap.SOAPBody; + import javax.xml.soap.SOAPEnvelope; + import javax.xml.soap.SOAPException; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/util/ConfigurationUtil.java picketlink/org/picketlink/identity/federation/web/util/ConfigurationUtil.java +--- picketlink-orig/org/picketlink/identity/federation/web/util/ConfigurationUtil.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/util/ConfigurationUtil.java 2023-12-17 08:05:07.572987479 +0100 +@@ -36,7 +36,7 @@ + import org.picketlink.identity.federation.core.audit.PicketLinkAuditHelper; + import org.picketlink.identity.federation.web.config.AbstractSAMLConfigurationProvider; + +-import javax.servlet.ServletContext; ++import jakarta.servlet.ServletContext; + + import static org.picketlink.common.constants.GeneralConstants.AUDIT_HELPER; + import static org.picketlink.common.constants.GeneralConstants.CONFIG_FILE_LOCATION; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/util/HTTPRedirectUtil.java picketlink/org/picketlink/identity/federation/web/util/HTTPRedirectUtil.java +--- picketlink-orig/org/picketlink/identity/federation/web/util/HTTPRedirectUtil.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/util/HTTPRedirectUtil.java 2023-12-17 08:05:07.572987479 +0100 +@@ -17,7 +17,7 @@ + */ + package org.picketlink.identity.federation.web.util; + +-import javax.servlet.http.HttpServletResponse; ++import jakarta.servlet.http.HttpServletResponse; + import java.io.IOException; + + /** +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/util/IDPWebRequestUtil.java picketlink/org/picketlink/identity/federation/web/util/IDPWebRequestUtil.java +--- picketlink-orig/org/picketlink/identity/federation/web/util/IDPWebRequestUtil.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/util/IDPWebRequestUtil.java 2023-12-17 08:05:07.572987479 +0100 +@@ -46,8 +46,8 @@ + import org.picketlink.identity.federation.saml.v2.protocol.ResponseType; + import org.w3c.dom.Document; + +-import javax.servlet.http.HttpServletRequest; +-import javax.servlet.http.HttpServletResponse; ++import jakarta.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletResponse; + import javax.xml.crypto.dsig.CanonicalizationMethod; + import java.io.ByteArrayInputStream; + import java.io.IOException; +diff -uNr picketlink-orig/org/picketlink/identity/federation/web/util/PostBindingUtil.java picketlink/org/picketlink/identity/federation/web/util/PostBindingUtil.java +--- picketlink-orig/org/picketlink/identity/federation/web/util/PostBindingUtil.java 2023-12-17 08:04:43.384951976 +0100 ++++ picketlink/org/picketlink/identity/federation/web/util/PostBindingUtil.java 2023-12-17 08:05:07.572987479 +0100 +@@ -27,8 +27,8 @@ + import org.picketlink.common.util.Base64; + import org.picketlink.identity.federation.core.saml.v2.holders.DestinationInfoHolder; + +-import javax.servlet.ServletOutputStream; +-import javax.servlet.http.HttpServletResponse; ++import jakarta.servlet.ServletOutputStream; ++import jakarta.servlet.http.HttpServletResponse; + import java.io.ByteArrayInputStream; + import java.io.IOException; + import java.io.InputStream; +diff -uNr picketlink-orig/org/picketlink/trust/jbossws/handler/AbstractPicketLinkTrustHandler.java picketlink/org/picketlink/trust/jbossws/handler/AbstractPicketLinkTrustHandler.java +--- picketlink-orig/org/picketlink/trust/jbossws/handler/AbstractPicketLinkTrustHandler.java 2023-12-17 08:04:43.404952006 +0100 ++++ picketlink/org/picketlink/trust/jbossws/handler/AbstractPicketLinkTrustHandler.java 2023-12-17 08:05:07.592987508 +0100 +@@ -41,7 +41,7 @@ + import javax.naming.InitialContext; + import javax.naming.NamingException; + import javax.security.auth.Subject; +-import javax.servlet.ServletContext; ++import jakarta.servlet.ServletContext; + import javax.xml.namespace.QName; + import javax.xml.ws.handler.LogicalMessageContext; + import javax.xml.ws.handler.MessageContext; +diff -uNr picketlink-orig/org/picketlink/trust/jbossws/handler/AbstractWSAuthorizationHandler.java picketlink/org/picketlink/trust/jbossws/handler/AbstractWSAuthorizationHandler.java +--- picketlink-orig/org/picketlink/trust/jbossws/handler/AbstractWSAuthorizationHandler.java 2023-12-17 08:04:43.404952006 +0100 ++++ picketlink/org/picketlink/trust/jbossws/handler/AbstractWSAuthorizationHandler.java 2023-12-17 08:05:07.592987508 +0100 +@@ -30,7 +30,7 @@ + import java.util.Set; + + import javax.security.auth.Subject; +-import javax.servlet.ServletContext; ++import jakarta.servlet.ServletContext; + import javax.xml.namespace.QName; + import javax.xml.soap.SOAPBody; + import javax.xml.soap.SOAPException; +diff -uNr picketlink-orig/org/picketlink/trust/jbossws/handler/BinaryTokenHandler.java picketlink/org/picketlink/trust/jbossws/handler/BinaryTokenHandler.java +--- picketlink-orig/org/picketlink/trust/jbossws/handler/BinaryTokenHandler.java 2023-12-17 08:04:43.404952006 +0100 ++++ picketlink/org/picketlink/trust/jbossws/handler/BinaryTokenHandler.java 2023-12-17 08:05:07.592987508 +0100 +@@ -26,8 +26,8 @@ + + import javax.security.jacc.PolicyContext; + import javax.security.jacc.PolicyContextException; +-import javax.servlet.http.Cookie; +-import javax.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.Cookie; ++import jakarta.servlet.http.HttpServletRequest; + import javax.xml.namespace.QName; + import javax.xml.soap.SOAPElement; + import javax.xml.soap.SOAPEnvelope; +@@ -267,7 +267,7 @@ + HttpServletRequest request = (HttpServletRequest) msgContext.get(MessageContext.SERVLET_REQUEST); + if (request == null) { + try { +- request = (HttpServletRequest) PolicyContext.getContext("javax.servlet.http.HttpServletRequest"); ++ request = (HttpServletRequest) PolicyContext.getContext("jakarta.servlet.http.HttpServletRequest"); + } catch (PolicyContextException e) { + throw new RuntimeException(e); + } +diff -uNr picketlink-orig/org/picketlink/trust/jbossws/handler/SamlRequestSecurityTokenHandler.java picketlink/org/picketlink/trust/jbossws/handler/SamlRequestSecurityTokenHandler.java +--- picketlink-orig/org/picketlink/trust/jbossws/handler/SamlRequestSecurityTokenHandler.java 2023-12-17 08:04:43.404952006 +0100 ++++ picketlink/org/picketlink/trust/jbossws/handler/SamlRequestSecurityTokenHandler.java 2023-12-17 08:05:07.592987508 +0100 +@@ -25,7 +25,7 @@ + + import javax.security.jacc.PolicyContext; + import javax.security.jacc.PolicyContextException; +-import javax.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletRequest; + import javax.xml.namespace.QName; + import javax.xml.soap.SOAPBodyElement; + import javax.xml.soap.SOAPElement; +@@ -106,7 +106,7 @@ + HttpServletRequest request = (HttpServletRequest) msgContext.get(MessageContext.SERVLET_REQUEST); + if (request == null) { + try { +- request = (HttpServletRequest) PolicyContext.getContext("javax.servlet.http.HttpServletRequest"); ++ request = (HttpServletRequest) PolicyContext.getContext("jakarta.servlet.http.HttpServletRequest"); + } catch (PolicyContextException e) { + return null; + } +diff -uNr picketlink-orig/org/picketlink/trust/jbossws/jaas/SAMLBearerTokenLoginModule.java picketlink/org/picketlink/trust/jbossws/jaas/SAMLBearerTokenLoginModule.java +--- picketlink-orig/org/picketlink/trust/jbossws/jaas/SAMLBearerTokenLoginModule.java 2023-12-17 08:04:43.404952006 +0100 ++++ picketlink/org/picketlink/trust/jbossws/jaas/SAMLBearerTokenLoginModule.java 2023-12-17 08:05:07.592987508 +0100 +@@ -32,7 +32,7 @@ + import javax.security.auth.callback.CallbackHandler; + import javax.security.auth.login.LoginException; + import javax.security.jacc.PolicyContext; +-import javax.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletRequest; + import javax.xml.datatype.XMLGregorianCalendar; + import javax.xml.stream.XMLEventReader; + import javax.xml.stream.XMLInputFactory; +@@ -105,7 +105,7 @@ + public boolean login() throws LoginException { + InputStream is = null; + try { +- HttpServletRequest request = (HttpServletRequest) PolicyContext.getContext("javax.servlet.http.HttpServletRequest"); ++ HttpServletRequest request = (HttpServletRequest) PolicyContext.getContext("jakarta.servlet.http.HttpServletRequest"); + String authorization = request.getHeader(AUTHORIZATION); + if (authorization != null && authorization.startsWith(BASIC)) { + String b64Data = authorization.substring(6); +diff -uNr picketlink-orig/org/picketlink/trust/jbossws/PicketLinkDispatch.java picketlink/org/picketlink/trust/jbossws/PicketLinkDispatch.java +--- picketlink-orig/org/picketlink/trust/jbossws/PicketLinkDispatch.java 2023-12-17 08:04:43.404952006 +0100 ++++ picketlink/org/picketlink/trust/jbossws/PicketLinkDispatch.java 2023-12-17 08:05:07.592987508 +0100 +@@ -34,7 +34,7 @@ + import javax.net.ssl.SSLSocketFactory; + import javax.security.jacc.PolicyContext; + import javax.security.jacc.PolicyContextException; +-import javax.servlet.http.HttpServletRequest; ++import jakarta.servlet.http.HttpServletRequest; + import javax.xml.bind.JAXBContext; + import javax.xml.namespace.QName; + import javax.xml.soap.SOAPConnection; +@@ -121,7 +121,7 @@ + msgContext.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, Boolean.TRUE); + + /** The JACC PolicyContext key for the current Subject */ +- String WEB_REQUEST_KEY = "javax.servlet.http.HttpServletRequest"; ++ String WEB_REQUEST_KEY = "jakarta.servlet.http.HttpServletRequest"; + + HttpServletRequest request = null; + try { diff --git a/picketlink-saml/src/main/resources/core-sts.xml b/picketlink-saml/src/main/resources/core-sts.xml new file mode 100644 index 000000000..78b893504 --- /dev/null +++ b/picketlink-saml/src/main/resources/core-sts.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/dtd/security-policy.dtd b/picketlink-saml/src/main/resources/dtd/security-policy.dtd new file mode 100644 index 000000000..070f61f7a --- /dev/null +++ b/picketlink-saml/src/main/resources/dtd/security-policy.dtd @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/dtd/security_config.dtd b/picketlink-saml/src/main/resources/dtd/security_config.dtd new file mode 100644 index 000000000..eec068d5c --- /dev/null +++ b/picketlink-saml/src/main/resources/dtd/security_config.dtd @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/etc/client/auth.conf b/picketlink-saml/src/main/resources/etc/client/auth.conf new file mode 100644 index 000000000..94361d219 --- /dev/null +++ b/picketlink-saml/src/main/resources/etc/client/auth.conf @@ -0,0 +1,25 @@ +srp-client { + // Example client auth.conf for using the SRPLoginModule + org.jboss.security.srp.jaas.SRPLoginModule required + password-stacking="useFirstPass" + principalClassName="org.jboss.security.SimplePrincipal" + srpServerJndiName="SRPServerInterface" + debug=true + ; + + // jBoss LoginModule + org.jboss.security.ClientLoginModule required + password-stacking="useFirstPass" + ; + + // Put your login modules that need jBoss here +}; + +other { + // jBoss LoginModule + org.jboss.security.ClientLoginModule required + ; + + // Put your login modules that need jBoss here +}; + diff --git a/picketlink-saml/src/main/resources/etc/default.mf b/picketlink-saml/src/main/resources/etc/default.mf new file mode 100644 index 000000000..8e2f2f0f0 --- /dev/null +++ b/picketlink-saml/src/main/resources/etc/default.mf @@ -0,0 +1,10 @@ +Manifest-Version: 1.0 +Created-By: @java.vm.version@ (@java.vm.vendor@) +Specification-Title: @specification.title@ +Specification-Version: @specification.version@ +Specification-Vendor: @specification.vendor@ +Implementation-Title: @implementation.title@ +Implementation-URL: @implementation.url@ +Implementation-Version: @implementation.version@ +Implementation-Vendor: @implementation.vendor@ +Implementation-Vendor-Id: @implementation.vendor.id@ diff --git a/picketlink-saml/src/main/resources/schema/config/picketlink-fed-handler.xsd b/picketlink-saml/src/main/resources/schema/config/picketlink-fed-handler.xsd new file mode 100644 index 000000000..b33e00dc2 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/config/picketlink-fed-handler.xsd @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/config/picketlink-fed.xsd b/picketlink-saml/src/main/resources/schema/config/picketlink-fed.xsd new file mode 100644 index 000000000..e1bd15d39 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/config/picketlink-fed.xsd @@ -0,0 +1,261 @@ + + + + + + IDP Type defines the configuration for an Identity + Provider. + + + + + + + + + + + + + + + + + + + + + + + The root configuration for an Identity Provider(IDP) using picketlink Identity. + + + + + + + Aspects involved in trust decisions such as the domains that the IDP or the Service Provider + trusts. + + + + + + Comma Separated domain names such as localhost,picketlink.com,picketlink.org + + + + + + + + + Source of the Signing and Validating Key + + + + + + + Key Value Pairs Needed to authenticate into the + provider. + + + + + + + Key Value pairs identifying domains against the + alias for validating key + + + + + + + An alias that identifies the signing key + + + + + + + + + + + + + + + Base Type for IDP and SP + + + + + + + + + + + + + + + + + + + + + + + + + Service Provider Type + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The claims processors specify the classes that are capable of processing specific claims dialects. + + + + + + + + + + + + + + + + + + + The token providers specify the classes that handle the requests for each type of security Token. + For example, a SAMLTokenProvider may be used to generate SAML token, while a X509TokenProvider + may be used to generate X.509 tokens (certificates). + + + + + + + + + + + + + + + + + + + + + The service providers specify the token type expected by each service provider. + + + + + + + + + + + The service provider type contains information about a specific service provider. In particular, + it specifies the type of the token that must be issued for the provider and the alias of the + provider's PKC in the truststore. This is used by the STS to locate the PKC when encrypting the + generated token. + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/config/picketlink_v2.1.xsd b/picketlink-saml/src/main/resources/schema/config/picketlink_v2.1.xsd new file mode 100644 index 000000000..7e7f7fe93 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/config/picketlink_v2.1.xsd @@ -0,0 +1,377 @@ + + + + + + + IDP Type defines the configuration for an Identity + Provider. + + + + + + + + + + + + + + + + + + + SAML Web Browser SSO Profile has a requirement that + the IDP does not respond back in Redirect Binding. Set this to + false if you want to force the IDP to respond to SPs using the + Redirect Binding. + + + + + + + + + + The root configuration for an Identity Provider(IDP) + using picketlink Identity. + + + + + + + + Aspects involved in trust decisions such as the + domains that the IDP or the Service Provider trusts. + + + + + + Comma Separated domain names such as + localhost,picketlink.com,picketlink.org + + + + + + + + + + Source of the Signing and Validating Key + + + + + + + Key Value Pairs Needed to authenticate into the + provider. + + + + + + + Key Value pairs identifying domains against the + alias for validating key + + + + + + + An alias that identifies the signing key + + + + + + + + + + + + + + + Base Type for IDP and SP + + + + + + + + + + + + + + + + + + + + + + + + + Service Provider Type + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Defines the token timeout in miliseconds. + + + + + + + Defines the clock skew, or timing skew, for the token timeout. + + + + + + + + + + + + The claims processors specify the classes that are + capable of processing specific claims dialects. + + + + + + + + + + + + + + + + + + + The token providers specify the classes that handle + the requests for each type of security Token. + For example, a + SAMLTokenProvider may be used to generate SAML token, while a + X509TokenProvider + may be used to generate X.509 tokens + (certificates). + + + + + + + + + + + + + + + + + + + + + The service providers specify the token type expected + by each service provider. + + + + + + + + + + + The service provider type contains information about a + specific service provider. In particular, + it specifies the type of + the token that must be issued for the provider and the alias of the + provider's PKC in the truststore. This is used by the STS to locate + the PKC when encrypting the + generated token. + + + + + + + + + + + + + + + + + + + + + + + + + + Defines the subclass name of + org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2HandlerChain + to be used to manage the handlers. + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/jboss-acl-config_1_0.xsd b/picketlink-saml/src/main/resources/schema/jboss-acl-config_1_0.xsd new file mode 100644 index 000000000..2cc31cc9f --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/jboss-acl-config_1_0.xsd @@ -0,0 +1,62 @@ + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-authn-svc-v2.0.xsd b/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-authn-svc-v2.0.xsd new file mode 100644 index 000000000..c9cf13da7 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-authn-svc-v2.0.xsd @@ -0,0 +1,161 @@ + + + + + + + + + + + + + The source code in this schema file was excerpted verbatim from: + + Liberty ID-WSF Liberty ID-WSF Authentication, Single Sign-On, and Identity Mapping Services Specification + Version 2.0-errata-v1.0 + 28 November, 2006 + + Copyright (c) 2007 Liberty Alliance participants, see + http://projectliberty.org/resource_center/specifications/liberty_alliance_id_wsf_2_0_specifications/idwsf_feb_copyrights + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Contains ordered list of sequential password transformations + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-disco-svc-v2.0.xsd b/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-disco-svc-v2.0.xsd new file mode 100644 index 000000000..43825471a --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-disco-svc-v2.0.xsd @@ -0,0 +1,410 @@ + + + + + + + + + + + + + + + + + + + + + + The source code in this schema file was excerpted verbatim from: + + Liberty ID-WSF Discovery Service Specification + Version 2.0-errata-v1.0 + 29 November, 2006 + + Copyright (c) 2007 Liberty Alliance participants, see + http://projectliberty.org/resource_center/specifications/liberty_alliance_id_wsf_2_0_specifications/idwsf_feb_copyrights + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-idmapping-svc-v2.0.xsd b/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-idmapping-svc-v2.0.xsd new file mode 100644 index 000000000..966a5ab18 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-idmapping-svc-v2.0.xsd @@ -0,0 +1,68 @@ + + + + + + + + + + + The source code in this schema file was excerpted verbatim from: + + Liberty ID-WSF Liberty ID-WSF Authentication, Single Sign-On, and Identity Mapping Services Specification + Version 2.0-errata-v1.0 + 28 November, 2006 + + Copyright (c) 2007 Liberty Alliance participants, see + http://projectliberty.org/resource_center/specifications/liberty_alliance_id_wsf_2_0_specifications/idwsf_feb_copyrights + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-interaction-svc-v2.0.xsd b/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-interaction-svc-v2.0.xsd new file mode 100644 index 000000000..615668269 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-interaction-svc-v2.0.xsd @@ -0,0 +1,133 @@ + + + + + + + + + + + The source code in this schema file was excerpted verbatim from: + + Liberty ID-WSF Interaction Service Specification + Version 2.0-errata-v1.0 + 21 April, 2007 + + Copyright (c) 2007 Liberty Alliance participants, see + http://projectliberty.org/resource_center/specifications/liberty_alliance_id_wsf_2_0_specifications/idwsf_feb_copyrights + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-people-service-v1.0.xsd b/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-people-service-v1.0.xsd new file mode 100644 index 000000000..7e44427e1 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-people-service-v1.0.xsd @@ -0,0 +1,546 @@ + + + + + + + + + + + The source code in this XSD file was excerpted verbatim from: + + Liberty ID-WSF People Service Specification + Version 1.0-errata-v1.0 + 06 March, 2007 + + Copyright (c) 2007 Liberty Alliance participants, see + http://projectliberty.org/resource_center/specifications/liberty_alliance_id_wsf_2_0_specifications/idwsf_feb_copyrights + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + When sending a AddEntityRequest to a PS provider, + the SP may insert a PStoSPRedirectURL. It will be + to this URL that the invited principals will be + sent after federating their IDP account to the PS + provider. + + + + + + + + + + + + + + + + + A PS provider may insert a SPtoPSRedirectURL in its + AddEntityResponse. It will be to this URL that the + invited principal will be sent after responding to the + invitation. + + + + + + + + + + + + + + + + + A PS provider may insert a QueryString in its + AddEntityResponse or AddKnownEntityResponse. The + invited Principal can present this artifact string + to a certain provider. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-soap-binding.xsd b/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-soap-binding.xsd new file mode 100644 index 000000000..0178f5f9a --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/liberty/idwsf/liberty-idwsf-soap-binding.xsd @@ -0,0 +1,34 @@ + + + + + + The source code in this schema file was excerpted verbatim from: + + Liberty ID-WSF SOAP Binding Specification + Version 2.0 errata 1.0 + 21 April, 2007 + + Copyright (c) 2007 Liberty Alliance participants, see + http://projectliberty.org/resource_center/specifications/liberty_alliance_id_wsf_2_0_specifications/idwsf_feb_copyrights + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v1/oasis-sstc-saml-schema-assertion-1.1.xsd b/picketlink-saml/src/main/resources/schema/saml/v1/oasis-sstc-saml-schema-assertion-1.1.xsd new file mode 100644 index 000000000..7d7aa166c --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v1/oasis-sstc-saml-schema-assertion-1.1.xsd @@ -0,0 +1,225 @@ + + + + + + Document identifier: oasis-sstc-saml-schema-assertion-1.1 + Location: http://www.oasis-open.org/committees/documents.php?wg_abbrev=security + Revision history: + V1.0 (November, 2002): + Initial standard schema. + V1.1 (September, 2003): + * Note that V1.1 of this schema has the same XML namespace as V1.0. + Rebased ID content directly on XML Schema types + Added DoNotCacheCondition element and DoNotCacheConditionType + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v1/saml-schema-assertion-1.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v1/saml-schema-assertion-1.0.xsd new file mode 100644 index 000000000..435037346 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v1/saml-schema-assertion-1.0.xsd @@ -0,0 +1,227 @@ + + + + + + Document identifier: oasis-sstc-saml-schema-assertion-1.1 + Location: http://www.oasis-open.org/committees/documents.php?wg_abbrev=security + Revision history: + V1.0 (November, 2002): + Initial standard schema. + V1.1 (September, 2003): + * Note that V1.1 of this schema has the same XML namespace as V1.0. + Rebased ID content directly on XML Schema types + Added DoNotCacheCondition element and DoNotCacheConditionType + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/saml/v1/saml-schema-protocol-1.1.xsd b/picketlink-saml/src/main/resources/schema/saml/v1/saml-schema-protocol-1.1.xsd new file mode 100644 index 000000000..7884c8aa2 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v1/saml-schema-protocol-1.1.xsd @@ -0,0 +1,153 @@ + + + + + + + Document identifier: oasis-sstc-saml-schema-protocol-1.1 + Location: http://www.oasis-open.org/committees/documents.php?wg_abbrev=security + Revision history: + V1.0 (November, 2002): + Initial standard schema. + V1.1 (September, 2003): + * Note that V1.1 of this schema has the same XML namespace as V1.0. + Rebased ID content directly on XML Schema types + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/access_control-xacml-2.0-saml-assertion-schema-os.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/access_control-xacml-2.0-saml-assertion-schema-os.xsd new file mode 100644 index 000000000..be86e3f34 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/access_control-xacml-2.0-saml-assertion-schema-os.xsd @@ -0,0 +1,54 @@ + + + + + + + + + Document identifier: access_control-xacml-2.0-saml-assertion-schema-cd-02.xsd + Location: http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-saml-assertion-schema-cd-os.xsd + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/access_control-xacml-2.0-saml-protocol-schema-os.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/access_control-xacml-2.0-saml-protocol-schema-os.xsd new file mode 100644 index 000000000..88f0b9b15 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/access_control-xacml-2.0-saml-protocol-schema-os.xsd @@ -0,0 +1,63 @@ + + + + + + + + + Document identifier: access_control-xacml-2.0-saml-protocol-schema-os.xsd + Location: http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-saml-protocol-schema-os.xsd + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-assertion-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-assertion-2.0.xsd new file mode 100644 index 000000000..cdd365d88 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-assertion-2.0.xsd @@ -0,0 +1,283 @@ + + + + + + + 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. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-2.0.xsd new file mode 100644 index 000000000..7fbc11b41 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-2.0.xsd @@ -0,0 +1,23 @@ + + + + + + Document identifier: saml-schema-authn-context-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New core authentication context schema for SAML V2.0. + This is just an include of all types from the schema + referred to in the include statement below. + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-auth-telephony-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-auth-telephony-2.0.xsd new file mode 100644 index 000000000..fa8e44e80 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-auth-telephony-2.0.xsd @@ -0,0 +1,81 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:AuthenticatedTelephony + Document identifier: saml-schema-authn-context-auth-telephony-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-ip-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-ip-2.0.xsd new file mode 100644 index 000000000..db44c738e --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-ip-2.0.xsd @@ -0,0 +1,65 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocol + Document identifier: saml-schema-authn-context-ip-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-ippword-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-ippword-2.0.xsd new file mode 100644 index 000000000..8d436d2b1 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-ippword-2.0.xsd @@ -0,0 +1,66 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocolPassword + Document identifier: saml-schema-authn-context-ippword-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-kerberos-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-kerberos-2.0.xsd new file mode 100644 index 000000000..e0ddd78e3 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-kerberos-2.0.xsd @@ -0,0 +1,83 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:Kerberos + Document identifier: saml-schema-authn-context-kerberos-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-mobileonefactor-reg-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-mobileonefactor-reg-2.0.xsd new file mode 100644 index 000000000..f60d04db0 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-mobileonefactor-reg-2.0.xsd @@ -0,0 +1,186 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:MobileOneFactorContract + Document identifier: saml-schema-authn-context-mobileonefactor-reg-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-mobileonefactor-unreg-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-mobileonefactor-unreg-2.0.xsd new file mode 100644 index 000000000..d061f2d45 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-mobileonefactor-unreg-2.0.xsd @@ -0,0 +1,183 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:MobileOneFactorUnregistered + Document identifier: saml-schema-authn-context-mobileonefactor-unreg-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-mobiletwofactor-reg-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-mobiletwofactor-reg-2.0.xsd new file mode 100644 index 000000000..9d5e3a365 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-mobiletwofactor-reg-2.0.xsd @@ -0,0 +1,202 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:MobileTwoFactorContract + Document identifier: saml-schema-authn-context-mobiletwofactor-reg-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-mobiletwofactor-unreg-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-mobiletwofactor-unreg-2.0.xsd new file mode 100644 index 000000000..e5d0a7f33 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-mobiletwofactor-unreg-2.0.xsd @@ -0,0 +1,200 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:MobileTwoFactorUnregistered + Document identifier: saml-schema-authn-context-mobiletwofactor-unreg-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-nomad-telephony-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-nomad-telephony-2.0.xsd new file mode 100644 index 000000000..f492daa66 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-nomad-telephony-2.0.xsd @@ -0,0 +1,81 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:NomadTelephony + Document identifier: saml-schema-authn-context-nomad-telephony-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-personal-telephony-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-personal-telephony-2.0.xsd new file mode 100644 index 000000000..5e8a684a2 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-personal-telephony-2.0.xsd @@ -0,0 +1,80 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:PersonalizedTelephony + Document identifier: saml-schema-authn-context-personal-telephony-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-pgp-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-pgp-2.0.xsd new file mode 100644 index 000000000..be64d8b79 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-pgp-2.0.xsd @@ -0,0 +1,83 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:PGP + Document identifier: saml-schema-authn-context-pgp-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-ppt-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-ppt-2.0.xsd new file mode 100644 index 000000000..b24a4ebfb --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-ppt-2.0.xsd @@ -0,0 +1,81 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport + Document identifier: saml-schema-authn-context-ppt-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-pword-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-pword-2.0.xsd new file mode 100644 index 000000000..75952d5cd --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-pword-2.0.xsd @@ -0,0 +1,64 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:Password + Document identifier: saml-schema-authn-context-pword-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-session-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-session-2.0.xsd new file mode 100644 index 000000000..fea86e7fb --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-session-2.0.xsd @@ -0,0 +1,64 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:PreviousSession + Document identifier: saml-schema-authn-context-session-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-smartcard-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-smartcard-2.0.xsd new file mode 100644 index 000000000..abda34e82 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-smartcard-2.0.xsd @@ -0,0 +1,64 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:Smartcard + Document identifier: saml-schema-authn-context-smartcard-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-smartcardpki-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-smartcardpki-2.0.xsd new file mode 100644 index 000000000..7d9f5a726 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-smartcardpki-2.0.xsd @@ -0,0 +1,129 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:SmartcardPKI + Document identifier: saml-schema-authn-context-smartcardpki-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-softwarepki-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-softwarepki-2.0.xsd new file mode 100644 index 000000000..bd4cfdfa7 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-softwarepki-2.0.xsd @@ -0,0 +1,129 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:SoftwarePKI + Document identifier: saml-schema-authn-context-softwarepki-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-spki-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-spki-2.0.xsd new file mode 100644 index 000000000..3827cc1cb --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-spki-2.0.xsd @@ -0,0 +1,83 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:SPKI + Document identifier: saml-schema-authn-context-spki-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-srp-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-srp-2.0.xsd new file mode 100644 index 000000000..9457ea20c --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-srp-2.0.xsd @@ -0,0 +1,82 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:SecureRemotePassword + Document identifier: saml-schema-authn-context-srp-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-sslcert-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-sslcert-2.0.xsd new file mode 100644 index 000000000..a9387ecfe --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-sslcert-2.0.xsd @@ -0,0 +1,97 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient + Document identifier: saml-schema-authn-context-sslcert-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-telephony-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-telephony-2.0.xsd new file mode 100644 index 000000000..4e4b33979 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-telephony-2.0.xsd @@ -0,0 +1,79 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:Telephony + Document identifier: saml-schema-authn-context-telephony-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-timesync-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-timesync-2.0.xsd new file mode 100644 index 000000000..076e21dee --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-timesync-2.0.xsd @@ -0,0 +1,105 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:TimeSyncToken + Document identifier: saml-schema-authn-context-timesync-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-types-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-types-2.0.xsd new file mode 100644 index 000000000..1df3e68e7 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-types-2.0.xsd @@ -0,0 +1,823 @@ + + + + + + Document identifier: saml-schema-authn-context-types-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New core authentication context schema types for SAML V2.0. + + + + + + + A particular assertion on an identity + provider's part with respect to the authentication + context associated with an authentication assertion. + + + + + + + + Refers to those characteristics that describe the + processes and mechanisms + the Authentication Authority uses to initially create + an association between a Principal + and the identity (or name) by which the Principal will + be known + + + + + + + + This element indicates that identification has been + performed in a physical + face-to-face meeting with the principal and not in an + online manner. + + + + + + + + + + + + + + + + + + + + Refers to those characterstics that describe how the + 'secret' (the knowledge or possession + of which allows the Principal to authenticate to the + Authentication Authority) is kept secure + + + + + + + + This element indicates the types and strengths of + facilities + of a UA used to protect a shared secret key from + unauthorized access and/or use. + + + + + + + + This element indicates the types and strengths of + facilities + of a UA used to protect a private key from + unauthorized access and/or use. + + + + + + + The actions that must be performed + before the private key can be used. + + + + + + + Whether or not the private key is shared + with the certificate authority. + + + + + + + + In which medium is the key stored. + memory - the key is stored in memory. + smartcard - the key is stored in a smartcard. + token - the key is stored in a hardware token. + MobileDevice - the key is stored in a mobile device. + MobileAuthCard - the key is stored in a mobile + authentication card. + + + + + + + + + + + This element indicates that a password (or passphrase) + has been used to + authenticate the Principal to a remote system. + + + + + + + + This element indicates that a Pin (Personal + Identification Number) has been used to authenticate the Principal to + some local system in order to activate a key. + + + + + + + + This element indicates that a hardware or software + token is used + as a method of identifying the Principal. + + + + + + + + This element indicates that a time synchronization + token is used to identify the Principal. hardware - + the time synchonization + token has been implemented in hardware. software - the + time synchronization + token has been implemented in software. SeedLength - + the length, in bits, of the + random seed used in the time synchronization token. + + + + + + + + This element indicates that a smartcard is used to + identity the Principal. + + + + + + + + This element indicates the minimum and/or maximum + ASCII length of the password which is enforced (by the UA or the + IdP). In other words, this is the minimum and/or maximum number of + ASCII characters required to represent a valid password. + min - the minimum number of ASCII characters required + in a valid password, as enforced by the UA or the IdP. + max - the maximum number of ASCII characters required + in a valid password, as enforced by the UA or the IdP. + + + + + + + + This element indicates the length of time for which an + PIN-based authentication is valid. + + + + + + + + Indicates whether the password was chosen by the + Principal or auto-supplied by the Authentication Authority. + principalchosen - the Principal is allowed to choose + the value of the password. This is true even if + the initial password is chosen at random by the UA or + the IdP and the Principal is then free to change + the password. + automatic - the password is chosen by the UA or the + IdP to be cryptographically strong in some sense, + or to satisfy certain password rules, and that the + Principal is not free to change it or to choose a new password. + + + + + + + + + + + + + + + + + + + Refers to those characteristics that define the + mechanisms by which the Principal authenticates to the Authentication + Authority. + + + + + + + + The method that a Principal employs to perform + authentication to local system components. + + + + + + + + The method applied to validate a principal's + authentication across a network + + + + + + + + Supports Authenticators with nested combinations of + additional complexity. + + + + + + + + Indicates that the Principal has been strongly + authenticated in a previous session during which the IdP has set a + cookie in the UA. During the present session the Principal has only + been authenticated by the UA returning the cookie to the IdP. + + + + + + + + Rather like PreviousSession but using stronger + security. A secret that was established in a previous session with + the Authentication Authority has been cached by the local system and + is now re-used (e.g. a Master Secret is used to derive new session + keys in TLS, SSL, WTLS). + + + + + + + + This element indicates that the Principal has been + authenticated by a zero knowledge technique as specified in ISO/IEC + 9798-5. + + + + + + + + + + This element indicates that the Principal has been + authenticated by a challenge-response protocol utilizing shared secret + keys and symmetric cryptography. + + + + + + + + + + + + This element indicates that the Principal has been + authenticated by a mechanism which involves the Principal computing a + digital signature over at least challenge data provided by the IdP. + + + + + + + + The local system has a private key but it is used + in decryption mode, rather than signature mode. For example, the + Authentication Authority generates a secret and encrypts it using the + local system's public key: the local system then proves it has + decrypted the secret. + + + + + + + + The local system has a private key and uses it for + shared secret key agreement with the Authentication Authority (e.g. + via Diffie Helman). + + + + + + + + + + + + + + + This element indicates that the Principal has been + authenticated through connection from a particular IP address. + + + + + + + + The local system and Authentication Authority + share a secret key. The local system uses this to encrypt a + randomised string to pass to the Authentication Authority. + + + + + + + + The protocol across which Authenticator information is + transferred to an Authentication Authority verifier. + + + + + + + + This element indicates that the Authenticator has been + transmitted using bare HTTP utilizing no additional security + protocols. + + + + + + + + This element indicates that the Authenticator has been + transmitted using a transport mechanism protected by an IPSEC session. + + + + + + + + This element indicates that the Authenticator has been + transmitted using a transport mechanism protected by a WTLS session. + + + + + + + + This element indicates that the Authenticator has been + transmitted solely across a mobile network using no additional + security mechanism. + + + + + + + + + + + This element indicates that the Authenticator has been + transmitted using a transport mechnanism protected by an SSL or TLS + session. + + + + + + + + + + + + Refers to those characteristics that describe + procedural security controls employed by the Authentication Authority. + + + + + + + + + + + + Provides a mechanism for linking to external (likely + human readable) documents in which additional business agreements, + (e.g. liability constraints, obligations, etc) can be placed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This attribute indicates whether or not the + Identification mechanisms allow the actions of the Principal to be + linked to an actual end user. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This element indicates that the Key Activation Limit is + defined as a specific duration of time. + + + + + + + + This element indicates that the Key Activation Limit is + defined as a number of usages. + + + + + + + + This element indicates that the Key Activation Limit is + the session. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-x509-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-x509-2.0.xsd new file mode 100644 index 000000000..112331757 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-x509-2.0.xsd @@ -0,0 +1,83 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:X509 + Document identifier: saml-schema-authn-context-x509-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-xmldsig-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-xmldsig-2.0.xsd new file mode 100644 index 000000000..f4be6abd2 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-authn-context-xmldsig-2.0.xsd @@ -0,0 +1,83 @@ + + + + + + + + + Class identifier: urn:oasis:names:tc:SAML:2.0:ac:classes:XMLDSig + Document identifier: saml-schema-authn-context-xmldsig-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + New authentication context class schema for SAML V2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-dce-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-dce-2.0.xsd new file mode 100644 index 000000000..6517ca2e6 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-dce-2.0.xsd @@ -0,0 +1,29 @@ + + + + + Document identifier: saml-schema-dce-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + Custom schema for DCE attribute profile, first published in SAML 2.0. + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-ecp-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-ecp-2.0.xsd new file mode 100644 index 000000000..37a66dc15 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-ecp-2.0.xsd @@ -0,0 +1,57 @@ + + + + + + + + Document identifier: saml-schema-ecp-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + Custom schema for ECP profile, first published in SAML 2.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-metadata-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-metadata-2.0.xsd new file mode 100644 index 000000000..5c8d21719 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-metadata-2.0.xsd @@ -0,0 +1,337 @@ + + + + + + + + + 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. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-protocol-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-protocol-2.0.xsd new file mode 100644 index 000000000..4441fe7dd --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-protocol-2.0.xsd @@ -0,0 +1,302 @@ + + + + + + + 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. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-x500-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-x500-2.0.xsd new file mode 100644 index 000000000..8de37c116 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-x500-2.0.xsd @@ -0,0 +1,20 @@ + + + + + Document identifier: saml-schema-x500-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + Custom schema for X.500 attribute profile, first published in SAML 2.0. + + + + + diff --git a/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-xacml-2.0.xsd b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-xacml-2.0.xsd new file mode 100644 index 000000000..206fe7fcd --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/saml/v2/saml-schema-xacml-2.0.xsd @@ -0,0 +1,19 @@ + + + + + Document identifier: saml-schema-xacml-2.0 + Location: http://docs.oasis-open.org/security/saml/v2.0/ + Revision history: + V2.0 (March, 2005): + Custom schema for XACML attribute profile, first published in SAML 2.0. + + + + diff --git a/picketlink-saml/src/main/resources/schema/security-config_4_0.xsd b/picketlink-saml/src/main/resources/schema/security-config_4_0.xsd new file mode 100644 index 000000000..bdce4b2c6 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/security-config_4_0.xsd @@ -0,0 +1,160 @@ + + + + + ... + + + The instance documents may indicate the published version of + the schema using the xsi:schemaLocation attribute: + http://www.jboss.org/j2ee/schema/security-config_4_0.xsd + + The outline of a policy/application-policy is: + + + + + option1-value + option2-value + ... + + + + ... + + ... + + + + ]]> + + + + The policy element is the root of the security + configuration descriptor. + + + + + + + + + + The application-policy lists configuration for a + named policy. This currently only consists of the authentication + configuration. + + + + + + + + The name attribute defines the authentication + configuration name. This is the name that would be passed to + the JAAS LoginContext ctor to use the associated login module stack. + + + + + + + The authentication element contains the login module + stack configuration. Each login module configuration is specified + using a login-module element. + + + + + + + + + + The login-module element defines a JAAS login module + configuration entry. Each entry must have a code and flag attribute + along with zero or more login module options specified via the + module-option element. + + + + + + + + The code attribute gives the fully qualifed class + name of the javax.security.auth.spi.LoginModule interface implementation + for the login module. + + + + + + The flag attribute controls how a login module + participates in the overall authentication proceedure. + Required - The LoginModule is required to succeed. If it + succeeds or fails, authentication still continues to proceed + down the LoginModule list. + + Requisite - The LoginModule is required to succeed. If it succeeds, + authentication continues down the LoginModule list. If it fails, + control immediately returns to the application (authentication does not proceed + down the LoginModule list). + + Sufficient - The LoginModule is not required to succeed. If it does + succeed, control immediately returns to the application (authentication + does not proceed down the LoginModule list). If it fails, + authentication continues down the LoginModule list. + + Optional - The LoginModule is not required to succeed. If it succeeds or + fails, authentication still continues to proceed down the + LoginModule list. + + The overall authentication succeeds only if + all required and requisite LoginModules succeed. If a + sufficient LoginModule is configured and succeeds, then only + the required and requisite LoginModules prior to that + sufficient LoginModule need to have succeeded for the overall + authentication to succeed. If no required or requisite + LoginModules are configured for an application, then at least + one sufficient or optional LoginModule must succeed. + + + + + + + A module option defines a name, value pair that are + passed to a LoginModule when it is initialized during the login proceedure. + The name attribute defines the option name while the element value is the + option value. The type of the value can be anything from a string obtained + from the module-option body, to arbitary objects unmarshalled based on + the namespace associated with the module-option child element. + + + + + + + + The module option name. This is the key used to store + the module value in the LoginModule initalize options Map. + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/security-config_4_1.xsd b/picketlink-saml/src/main/resources/schema/security-config_4_1.xsd new file mode 100644 index 000000000..6477d8e4c --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/security-config_4_1.xsd @@ -0,0 +1,182 @@ + + + + + + + + ... + + + The outline of a policy/application-policy is: + + + + + option1-value + option2-value + ... + + + + ... + + ... + + + + ]]> + + + + false + + + + + + + + The policy element is the root of the security + configuration descriptor. + + + + + + + + + + + + + + + The application-policy lists configuration for a + named policy. This currently only consists of the authentication + configuration. + + + + + + + + + + + + + + + + The authentication element contains the login module + stack configuration. Each login module configuration is specified + using a login-module element. + + + + + + + + + + + + + + The login-module element defines a JAAS login module + configuration entry. Each entry must have a code and flag attribute + along with zero or more login module options specified via the + module-option element. + + + + + + + + + + + The flag attribute controls how a login module + participates in the overall authentication proceedure. + Required - The LoginModule is required to succeed. If it + succeeds or fails, authentication still continues to proceed + down the LoginModule list. + + Requisite - The LoginModule is required to succeed. If it succeeds, + authentication continues down the LoginModule list. If it fails, + control immediately returns to the application (authentication does not proceed + down the LoginModule list). + + Sufficient - The LoginModule is not required to succeed. If it does + succeed, control immediately returns to the application (authentication + does not proceed down the LoginModule list). If it fails, + authentication continues down the LoginModule list. + + Optional - The LoginModule is not required to succeed. If it succeeds or + fails, authentication still continues to proceed down the + LoginModule list. + + The overall authentication succeeds only if + all required and requisite LoginModules succeed. If a + sufficient LoginModule is configured and succeeds, then only + the required and requisite LoginModules prior to that + sufficient LoginModule need to have succeeded for the overall + authentication to succeed. If no required or requisite + LoginModules are configured for an application, then at least + one sufficient or optional LoginModule must succeed. + + + + + + + + + + + + + + + + + A module option defines a name, value pair that are + passed to a LoginModule when it is initialized during the login proceedure. + The name attribute defines the option name while the element value is the + option value. The type of the value can be anything from a string obtained + from the module-option body, to arbitary objects unmarshalled based on + the namespace associated with the module-option child element + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/security-config_5_0.xsd b/picketlink-saml/src/main/resources/schema/security-config_5_0.xsd new file mode 100644 index 000000000..bfb6e7661 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/security-config_5_0.xsd @@ -0,0 +1,303 @@ + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The flag attribute controls how a login module + participates in the overall authentication proceedure. + Required - The LoginModule is required to succeed. If it + succeeds or fails, authentication still continues to proceed + down the LoginModule list. + + Requisite - The LoginModule is required to succeed. If it succeeds, + authentication continues down the LoginModule list. If it fails, + control immediately returns to the application (authentication does not proceed + down the LoginModule list). + + Sufficient - The LoginModule is not required to succeed. If it does + succeed, control immediately returns to the application (authentication + does not proceed down the LoginModule list). If it fails, + authentication continues down the LoginModule list. + + Optional - The LoginModule is not required to succeed. If it succeeds or + fails, authentication still continues to proceed down the + LoginModule list. + + The overall authentication succeeds only if + all required and requisite LoginModules succeed. If a + sufficient LoginModule is configured and succeeds, then only + the required and requisite LoginModules prior to that + sufficient LoginModule need to have succeeded for the overall + authentication to succeed. If no required or requisite + LoginModules are configured for an application, then at least + one sufficient or optional LoginModule must succeed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/w3c/xmldsig/xmldsig-core-schema.xsd b/picketlink-saml/src/main/resources/schema/w3c/xmldsig/xmldsig-core-schema.xsd new file mode 100644 index 000000000..2a8633f65 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/w3c/xmldsig/xmldsig-core-schema.xsd @@ -0,0 +1,319 @@ + + + + + + ]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/w3c/xmlenc/xenc-schema.xsd b/picketlink-saml/src/main/resources/schema/w3c/xmlenc/xenc-schema.xsd new file mode 100644 index 000000000..ea16a71b3 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/w3c/xmlenc/xenc-schema.xsd @@ -0,0 +1,154 @@ + + + + + + ]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/w3c/xmlschema/XMLSchema.dtd b/picketlink-saml/src/main/resources/schema/w3c/xmlschema/XMLSchema.dtd new file mode 100644 index 000000000..3803ed6ce --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/w3c/xmlschema/XMLSchema.dtd @@ -0,0 +1,402 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %xs-datatypes; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/w3c/xmlschema/datatypes.dtd b/picketlink-saml/src/main/resources/schema/w3c/xmlschema/datatypes.dtd new file mode 100644 index 000000000..facfaad05 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/w3c/xmlschema/datatypes.dtd @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/w3c/xmlschema/xml.xsd b/picketlink-saml/src/main/resources/schema/w3c/xmlschema/xml.xsd new file mode 100644 index 000000000..bb46b0e63 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/w3c/xmlschema/xml.xsd @@ -0,0 +1,124 @@ + + + + + + + See http://www.w3.org/XML/1998/namespace.html and + http://www.w3.org/TR/REC-xml for information about this namespace. + + This schema document describes the XML namespace, in a form + suitable for import by other schema documents. + + Note that local names in this namespace are intended to be defined + only by the World Wide Web Consortium or its subgroups. The + following names are currently defined in this namespace and should + not be used with conflicting semantics by any Working Group, + specification, or document instance: + + base (as an attribute name): denotes an attribute whose value + provides a URI to be used as the base for interpreting any + relative URIs in the scope of the element on which it + appears; its value is inherited. This name is reserved + by virtue of its definition in the XML Base specification. + + lang (as an attribute name): denotes an attribute whose value + is a language code for the natural language of the content of + any element; its value is inherited. This name is reserved + by virtue of its definition in the XML specification. + + space (as an attribute name): denotes an attribute whose + value is a keyword indicating what whitespace processing + discipline is intended for the content of the element; its + value is inherited. This name is reserved by virtue of its + definition in the XML specification. + + Father (in any context at all): denotes Jon Bosak, the chair of + the original XML Working Group. This name is reserved by + the following decision of the W3C XML Plenary and + XML Coordination groups: + + In appreciation for his vision, leadership and dedication + the W3C XML Plenary on this 10th day of February, 2000 + reserves for Jon Bosak in perpetuity the XML name + xml:Father + + + + + This schema defines attributes and an attribute group + suitable for use by + schemas wishing to allow xml:base, xml:lang or xml:space attributes + on elements they define. + + To enable this, such a schema must import this schema + for the XML namespace, e.g. as follows: + <schema . . .> + . . . + <import namespace="http://www.w3.org/XML/1998/namespace" + schemaLocation="http://www.w3.org/2001/03/xml.xsd"/> + + Subsequently, qualified reference to any of the attributes + or the group defined below will have the desired effect, e.g. + + <type . . .> + . . . + <attributeGroup ref="xml:specialAttrs"/> + + will define a type which will schema-validate an instance + element with any of those attributes + + + + + + In keeping with the XML Schema WG's standard versioning + policy, this schema document will persist at + http://www.w3.org/2001/03/xml.xsd. + At the date of issue it can also be found at + http://www.w3.org/2001/xml.xsd. + The schema document at that URI may however change in the future, + in order to remain compatible with the latest version of XML Schema + itself. In other words, if the XML Schema namespace changes, the version + of this document at + http://www.w3.org/2001/xml.xsd will change + accordingly; the version at + http://www.w3.org/2001/03/xml.xsd will not change. + + + + + + In due course, we should install the relevant ISO 2- and 3-letter + codes as the enumerated possible values . . . + + + + + + + + + + + + + + + + + + See http://www.w3.org/TR/xmlbase/ for + information about this attribute. + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/wstrust/v1_3/oasis-200401-wss-wssecurity-secext-1.0.xsd b/picketlink-saml/src/main/resources/schema/wstrust/v1_3/oasis-200401-wss-wssecurity-secext-1.0.xsd new file mode 100644 index 000000000..491430b2b --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/wstrust/v1_3/oasis-200401-wss-wssecurity-secext-1.0.xsd @@ -0,0 +1,210 @@ + + + + + + + + + This type represents an element with arbitrary attributes. + + + + + + + + + + + This type is used for password elements per Section 4.1. + + + + + + + + + + This type is used for elements containing stringified binary data. + + + + + + + + + + This type represents a username token per Section 4.1 + + + + + + + + + + + A security token that is encoded in binary + + + + + + + + + + A security token key identifier + + + + + + + + + + Typedef to allow a list of usages (as URIs). + + + + + + This global attribute is used to indicate the usage of a referenced or indicated token within + the containing context + + + + + + This type represents a reference to an external security token. + + + + + + + + This type represents a reference to an embedded security token. + + + + + + + + + + This type is used reference a security token. + + + + + + + + + + + This complexType defines header block to use for security-relevant data directed at a specific + SOAP actor. + + + + + + The use of "any" is to allow extensibility and different forms of security data. + + + + + + + + + This complexType defines a container for elements to be specified from any namespace as + properties/parameters of a DSIG transformation. + + + + + + The use of "any" is to allow extensibility from any namespace. + + + + + + + + This element defines the wsse:UsernameToken element per Section 4.1. + + + + + This element defines the wsse:BinarySecurityToken element per Section 4.2. + + + + + This element defines a security token reference + + + + + This element defines a security token embedded reference + + + + + This element defines a key identifier reference + + + + + This element defines the wsse:SecurityTokenReference per Section 4.3. + + + + + This element defines the wsse:Security SOAP header element per Section 4. + + + + + This element contains properties for transformations from any namespace, including DSIG. + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/wstrust/v1_3/oasis-200401-wss-wssecurity-utility-1.0.xsd b/picketlink-saml/src/main/resources/schema/wstrust/v1_3/oasis-200401-wss-wssecurity-utility-1.0.xsd new file mode 100644 index 000000000..31a68bccc --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/wstrust/v1_3/oasis-200401-wss-wssecurity-utility-1.0.xsd @@ -0,0 +1,109 @@ + + + + + + + + This type defines the fault code value for Timestamp message expiration. + + + + + + + + + + + This global attribute supports annotating arbitrary elements with an ID. + + + + + + + Convenience attribute group used to simplify this schema. + + + + + + + + + + This type is for elements whose [children] is a psuedo-dateTime and can have arbitrary attributes. + + + + + + + + + + + + This type is for elements whose [children] is an anyURI and can have arbitrary attributes. + + + + + + + + + + + + + This complex type ties together the timestamp related elements into a composite type. + + + + + + + + + + + + + + + This element allows Timestamps to be applied anywhere element wildcards are present, + including as a SOAP header. + + + + + + + + This element allows an expiration time to be applied anywhere element wildcards are present. + + + + + + + This element allows a creation time to be applied anywhere element wildcards are present. + + + + diff --git a/picketlink-saml/src/main/resources/schema/wstrust/v1_3/ws-addr.xsd b/picketlink-saml/src/main/resources/schema/wstrust/v1_3/ws-addr.xsd new file mode 100644 index 000000000..58ddcf004 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/wstrust/v1_3/ws-addr.xsd @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/schema/wstrust/v1_3/ws-policy.xsd b/picketlink-saml/src/main/resources/schema/wstrust/v1_3/ws-policy.xsd new file mode 100644 index 000000000..7223b59e7 --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/wstrust/v1_3/ws-policy.xsd @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/picketlink-saml/src/main/resources/schema/wstrust/v1_3/ws-trust-1.3.xsd b/picketlink-saml/src/main/resources/schema/wstrust/v1_3/ws-trust-1.3.xsd new file mode 100644 index 000000000..be28c3d0d --- /dev/null +++ b/picketlink-saml/src/main/resources/schema/wstrust/v1_3/ws-trust-1.3.xsd @@ -0,0 +1,444 @@ + + + + + + + + + + + + + + + Actual content model is non-deterministic, hence wildcard. The following shows intended content model: + + <xs:element ref='wst:TokenType' minOccurs='0' /> + <xs:element ref='wst:RequestType' /> + <xs:element ref='wsp:AppliesTo' minOccurs='0' /> + <xs:element ref='wst:Claims' minOccurs='0' /> + <xs:element ref='wst:Entropy' minOccurs='0' /> + <xs:element ref='wst:Lifetime' minOccurs='0' /> + <xs:element ref='wst:AllowPostdating' minOccurs='0' /> + <xs:element ref='wst:Renewing' minOccurs='0' /> + <xs:element ref='wst:OnBehalfOf' minOccurs='0' /> + <xs:element ref='wst:Issuer' minOccurs='0' /> + <xs:element ref='wst:AuthenticationType' minOccurs='0' /> + <xs:element ref='wst:KeyType' minOccurs='0' /> + <xs:element ref='wst:KeySize' minOccurs='0' /> + <xs:element ref='wst:SignatureAlgorithm' minOccurs='0' /> + <xs:element ref='wst:Encryption' minOccurs='0' /> + <xs:element ref='wst:EncryptionAlgorithm' minOccurs='0' /> + <xs:element ref='wst:CanonicalizationAlgorithm' minOccurs='0' /> + <xs:element ref='wst:ProofEncryption' minOccurs='0' /> + <xs:element ref='wst:UseKey' minOccurs='0' /> + <xs:element ref='wst:SignWith' minOccurs='0' /> + <xs:element ref='wst:EncryptWith' minOccurs='0' /> + <xs:element ref='wst:DelegateTo' minOccurs='0' /> + <xs:element ref='wst:Forwardable' minOccurs='0' /> + <xs:element ref='wst:Delegatable' minOccurs='0' /> + <xs:element ref='wsp:Policy' minOccurs='0' /> + <xs:element ref='wsp:PolicyReference' minOccurs='0' /> + <xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Actual content model is non-deterministic, hence wildcard. The following shows intended content model: + + <xs:element ref='wst:TokenType' minOccurs='0' /> + <xs:element ref='wst:RequestType' /> + <xs:element ref='wst:RequestedSecurityToken' minOccurs='0' /> + <xs:element ref='wsp:AppliesTo' minOccurs='0' /> + <xs:element ref='wst:RequestedAttachedReference' minOccurs='0' /> + <xs:element ref='wst:RequestedUnattachedReference' minOccurs='0' /> + <xs:element ref='wst:RequestedProofToken' minOccurs='0' /> + <xs:element ref='wst:Entropy' minOccurs='0' /> + <xs:element ref='wst:Lifetime' minOccurs='0' /> + <xs:element ref='wst:Status' minOccurs='0' /> + <xs:element ref='wst:AllowPostdating' minOccurs='0' /> + <xs:element ref='wst:Renewing' minOccurs='0' /> + <xs:element ref='wst:OnBehalfOf' minOccurs='0' /> + <xs:element ref='wst:Issuer' minOccurs='0' /> + <xs:element ref='wst:AuthenticationType' minOccurs='0' /> + <xs:element ref='wst:Authenticator' minOccurs='0' /> + <xs:element ref='wst:KeyType' minOccurs='0' /> + <xs:element ref='wst:KeySize' minOccurs='0' /> + <xs:element ref='wst:SignatureAlgorithm' minOccurs='0' /> + <xs:element ref='wst:Encryption' minOccurs='0' /> + <xs:element ref='wst:EncryptionAlgorithm' minOccurs='0' /> + <xs:element ref='wst:CanonicalizationAlgorithm' minOccurs='0' /> + <xs:element ref='wst:ProofEncryption' minOccurs='0' /> + <xs:element ref='wst:UseKey' minOccurs='0' /> + <xs:element ref='wst:SignWith' minOccurs='0' /> + <xs:element ref='wst:EncryptWith' minOccurs='0' /> + <xs:element ref='wst:DelegateTo' minOccurs='0' /> + <xs:element ref='wst:Forwardable' minOccurs='0' /> + <xs:element ref='wst:Delegatable' minOccurs='0' /> + <xs:element ref='wsp:Policy' minOccurs='0' /> + <xs:element ref='wsp:PolicyReference' minOccurs='0' /> + <xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The RequestSecurityTokenCollection (RSTC) element is used to provide multiple RST requests. + One or more RSTR elements in an RSTRC element are returned in the response to the + RequestSecurityTokenCollection. + + + + + + + + + + + + The <wst:RequestSecurityTokenResponseCollection> element (RSTRC) MUST be used to return a security token or + response to a security token request on the final response. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/security-policies-service.xml b/picketlink-saml/src/main/resources/security-policies-service.xml new file mode 100644 index 000000000..975c24c39 --- /dev/null +++ b/picketlink-saml/src/main/resources/security-policies-service.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + jboss.security:service=XMLLoginConfig + + + jboss.security:service=JaasSecurityManager + + + diff --git a/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-authn-svc-v2.0.wsdl b/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-authn-svc-v2.0.wsdl new file mode 100644 index 000000000..e4373cf1d --- /dev/null +++ b/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-authn-svc-v2.0.wsdl @@ -0,0 +1,66 @@ + + + + + The source code in this WSDL file was excerpted verbatim from: + + Liberty ID-WSF Liberty ID-WSF Authentication, Single Sign-On, and Identity Mapping Services Specification + Version 2.0-errata-v1.0 + 28 November, 2006 + + Copyright (c) 2007 Liberty Alliance participants, see + http://projectliberty.org/resource_center/specifications/liberty_alliance_id_wsf_2_0_specifications/idwsf_feb_copyrights + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-disco-svc-v2.0.wsdl b/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-disco-svc-v2.0.wsdl new file mode 100644 index 000000000..a8186a0ac --- /dev/null +++ b/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-disco-svc-v2.0.wsdl @@ -0,0 +1,250 @@ + + + + + The source code in this WSDL file was excerpted verbatim from: + + Liberty ID-WSF Discovery Service Specification + Version 2.0-errata-v1.0 + 29 November, 2006 + + Copyright (c) 2007 Liberty Alliance participants, see + http://projectliberty.org/resource_center/specifications/liberty_alliance_id_wsf_2_0_specifications/idwsf_feb_copyrights + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-idmapping-svc-v2.0.wsdl b/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-idmapping-svc-v2.0.wsdl new file mode 100644 index 000000000..383407026 --- /dev/null +++ b/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-idmapping-svc-v2.0.wsdl @@ -0,0 +1,66 @@ + + + + + The source code in this WSDL file was excerpted verbatim from: + + Liberty ID-WSF Liberty ID-WSF Authentication, Single Sign-On, and Identity Mapping Services Specification + Version 2.0-errata-v1.0 + 28 November, 2006 + + Copyright (c) 2007 Liberty Alliance participants, see + http://projectliberty.org/resource_center/specifications/liberty_alliance_id_wsf_2_0_specifications/idwsf_feb_copyrights + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-interaction-svc-v2.0.wsdl b/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-interaction-svc-v2.0.wsdl new file mode 100644 index 000000000..35dc2814e --- /dev/null +++ b/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-interaction-svc-v2.0.wsdl @@ -0,0 +1,84 @@ + + + + + The source code in this WSDL file was excerpted verbatim from: + + Liberty ID-WSF Interaction Service Specification + Version 2.0-errata-v1.0 + 21 April, 2007 + + Copyright (c) 2007 Liberty Alliance participants, see + http://projectliberty.org/resource_center/specifications/liberty_alliance_id_wsf_2_0_specifications/idwsf_feb_copyrights + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-people-service-v1.0.wsdl b/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-people-service-v1.0.wsdl new file mode 100644 index 000000000..07a65b42d --- /dev/null +++ b/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-people-service-v1.0.wsdl @@ -0,0 +1,393 @@ + + + + The source code in this WSDL file was excerpted verbatim from: + + Liberty ID-WSF People Service Specification + Version 1.0-errata-v1.0 + 06 March, 2007 + + Copyright (c) 2007 Liberty Alliance participants, see + http://projectliberty.org/resource_center/specifications/liberty_alliance_id_wsf_2_0_specifications/idwsf_feb_copyrights + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-sso-svc-v2.0.wsdl b/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-sso-svc-v2.0.wsdl new file mode 100644 index 000000000..2932ea796 --- /dev/null +++ b/picketlink-saml/src/main/resources/wsdl/liberty/idwsf/liberty-idwsf-sso-svc-v2.0.wsdl @@ -0,0 +1,67 @@ + + + + + The source code in this WSDL file was excerpted verbatim from: + + Liberty ID-WSF Liberty ID-WSF Authentication, Single Sign-On, and Identity Mapping Services Specification + Version 2.0-errata-v1.0 + 28 November, 2006 + + Copyright (c) 2007 Liberty Alliance participants, see + http://projectliberty.org/resource_center/specifications/liberty_alliance_id_wsf_2_0_specifications/idwsf_feb_copyrights + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 5e9592fe1..e1a6075ba 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,6 @@ maven-parent-pom org.exoplatform 26-mips-SNAPSHOT - org.exoplatform.gatein.sso @@ -33,12 +32,11 @@ + picketlink-saml agent auth-callback common-plugin opensso - spnego - spnegosso saml packaging integration @@ -46,6 +44,7 @@ 6.6.x-mips-SNAPSHOT + meeds-io @@ -61,13 +60,18 @@ pom import - - + + org.exoplatform.gatein.sso sso-auth-callback ${project.version} + + ${project.groupId} + sso-picketlink-saml + ${project.version} + org.exoplatform.gatein.sso sso-agent @@ -88,11 +92,6 @@ sso-opensso-plugin ${project.version} - - org.exoplatform.gatein.sso - spnego - ${project.version} - org.exoplatform.gatein.sso sso-saml-plugin @@ -100,6 +99,19 @@ + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-patch-plugin + 1.2 + + + + diff --git a/saml/gatein-saml-plugin/pom.xml b/saml/gatein-saml-plugin/pom.xml index ee8e7eec4..50e0ad8dc 100644 --- a/saml/gatein-saml-plugin/pom.xml +++ b/saml/gatein-saml-plugin/pom.xml @@ -1,90 +1,67 @@ - - - sso-saml-parent - org.exoplatform.gatein.sso - 6.6.x-mips-SNAPSHOT - ../pom.xml - + + + sso-saml-parent + org.exoplatform.gatein.sso + 6.6.x-mips-SNAPSHOT + - 4.0.0 - org.exoplatform.gatein.sso - sso-saml-plugin - jar + 4.0.0 + sso-saml-plugin + jar - GateIn SSO - SAML Identity provider plugin + GateIn SSO - SAML Identity provider plugin - - 0.07 - + + 0.05 + - - - org.jboss.logging - jboss-logging - provided - - - org.apache.tomcat - tomcat-catalina - provided - - - org.apache.httpcomponents - httpclient - - - org.picketlink.distribution - picketlink-wildfly8 - provided - - - org.picketlink - picketlink-common - - - org.picketlink - picketlink-config - - - javax.servlet - javax.servlet-api - - - org.exoplatform.gatein.sso - sso-common-plugin - - - - org.exoplatform.gatein.wci - wci-wci - - - - org.exoplatform.gatein.sso - sso-integration - - - org.exoplatform.gatein.sso - sso-agent - - - org.exoplatform.core - exo.core.component.organization.api - - - org.picketlink - picketlink-federation - - - org.mockito - mockito-core - test - - - junit - junit - test - - + + + ${project.groupId} + sso-picketlink-saml + + + + ${project.groupId} + sso-integration + + + ${project.groupId} + sso-agent + + + + org.apache.tomcat + tomcat-catalina + provided + + + + org.exoplatform.gatein.wci + wci-wci + + + org.exoplatform.core + exo.core.component.organization.api + + + org.apache.httpcomponents + httpclient + + + org.mockito + mockito-core + test + + + junit + junit + test + + diff --git a/agent/src/main/java/org/gatein/sso/agent/login/SAML2IntegrationLoginModule.java b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/agent/login/SAML2IntegrationLoginModule.java similarity index 93% rename from agent/src/main/java/org/gatein/sso/agent/login/SAML2IntegrationLoginModule.java rename to saml/gatein-saml-plugin/src/main/java/org/gatein/sso/agent/login/SAML2IntegrationLoginModule.java index 7d1c2cfb7..b0622cd5f 100644 --- a/agent/src/main/java/org/gatein/sso/agent/login/SAML2IntegrationLoginModule.java +++ b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/agent/login/SAML2IntegrationLoginModule.java @@ -20,23 +20,26 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ - package org.gatein.sso.agent.login; +import java.security.Principal; +import java.util.Map; + +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginException; + +import org.picketlink.identity.federation.bindings.jboss.auth.SAML2LoginModule; + import org.exoplatform.container.ExoContainer; import org.exoplatform.container.ExoContainerContext; import org.exoplatform.container.PortalContainer; import org.exoplatform.container.RootContainer; +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; import org.exoplatform.services.security.Authenticator; import org.exoplatform.services.security.Identity; import org.exoplatform.services.security.UsernameCredential; -import org.picketlink.identity.federation.bindings.jboss.auth.SAML2LoginModule; - -import javax.security.auth.Subject; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.login.LoginException; -import java.security.Principal; -import java.util.Map; /** * Login module for integration with GateIn. It's running on GateIn (SAML SP) side. @@ -57,6 +60,8 @@ public class SAML2IntegrationLoginModule extends SAML2LoginModule // Default value is false, so we are preferring delegation to JbossLoginModule and using roles from portal DB. private static final String OPTION_USE_SAML_ROLES = "useSAMLRoles"; + private static final Log log = ExoLogger.getLogger(SAML2IntegrationLoginModule.class); + private static final String[] ALL_VALID_OPTIONS = { OPTION_PORTAL_CONTAINER_NAME, @@ -88,13 +93,11 @@ public void initialize(Subject subject, CallbackHandler callbackHandler, Maptrue if it requires the portal environment - * false otherwise. - */ - protected boolean requirePortalEnvironment() { - if (requirePortalEnvironment == null) { - synchronized (this) { - if (requirePortalEnvironment == null) { - this.requirePortalEnvironment = PortalContainer.isPortalContainerName(servletContextName); - } - } - } - return requirePortalEnvironment.booleanValue(); - } - - /** - * @return the current {@link ServletContext} - */ - protected ServletContext getServletContext() { - if (requirePortalEnvironment()) { - ExoContainer container = getContainer(); - if (container instanceof PortalContainer) { - return ((PortalContainer) container).getPortalContext(); - } - } - if (this.config != null) { - return this.config.getServletContext(); - } - return null; - } - - private FilterConfig getFilterConfig(FilterConfig config) { - if (this.config == null) { - if (config == null) { - this.config = new SAMLFilterConfig("PortalIDPWebBrowserSSOFilter", getServletContext(), interceptorContext); - } else { - this.config = config; - } - } - return this.config; - } -} diff --git a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAML2LogoutFilter.java b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAML2LogoutFilter.java index 58522abac..31c32e8a9 100644 --- a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAML2LogoutFilter.java +++ b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAML2LogoutFilter.java @@ -2,19 +2,7 @@ import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; - import org.apache.commons.lang.StringUtils; -import org.exoplatform.services.log.ExoLogger; -import org.exoplatform.services.log.Log; import org.gatein.sso.agent.filter.api.SSOInterceptor; import org.gatein.sso.agent.filter.api.SSOInterceptorInitializationContext; import org.picketlink.common.constants.GeneralConstants; @@ -26,6 +14,18 @@ import org.exoplatform.container.RootContainer; import org.exoplatform.container.util.ContainerUtil; import org.exoplatform.container.xml.InitParams; +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; public class SAML2LogoutFilter extends SPFilter implements SSOInterceptor { diff --git a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAMLFilterConfig.java b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAMLFilterConfig.java index 07ed65984..0494e9a93 100644 --- a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAMLFilterConfig.java +++ b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAMLFilterConfig.java @@ -2,8 +2,8 @@ import java.util.Enumeration; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletContext; import org.gatein.sso.agent.filter.api.SSOInterceptorInitializationContext; diff --git a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAMLHTTPRequestWrapper.java b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAMLHTTPRequestWrapper.java index df81b2405..c4a08654d 100644 --- a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAMLHTTPRequestWrapper.java +++ b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAMLHTTPRequestWrapper.java @@ -3,8 +3,8 @@ import java.util.Enumeration; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; /** * This class is used to combine two HTTP Request datas diff --git a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAMLSPServletContextWrapper.java b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAMLSPServletContextWrapper.java index 2f44fdce9..b85ff5508 100644 --- a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAMLSPServletContextWrapper.java +++ b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/filter/SAMLSPServletContextWrapper.java @@ -10,29 +10,29 @@ import java.util.Map; import java.util.Set; -import javax.servlet.Filter; -import javax.servlet.FilterRegistration; -import javax.servlet.FilterRegistration.Dynamic; -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; -import javax.servlet.SessionCookieConfig; -import javax.servlet.SessionTrackingMode; -import javax.servlet.descriptor.JspConfigDescriptor; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterRegistration; +import jakarta.servlet.FilterRegistration.Dynamic; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRegistration; +import jakarta.servlet.SessionCookieConfig; +import jakarta.servlet.SessionTrackingMode; +import jakarta.servlet.descriptor.JspConfigDescriptor; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; /** - * This class wraps an HTTP ServletContext to be able to get - * a configuration file from local folder outside the webapp + * This class wraps an HTTP ServletContext to be able to get a configuration + * file from local folder outside the webapp */ public class SAMLSPServletContextWrapper implements ServletContext { public static final String FILE_PREFIX = "file:"; - public static final Log log = ExoLogger.getLogger(PortalIDPWebBrowserSSOFilter.class); + private static final Log LOG = ExoLogger.getLogger(SAMLSPServletContextWrapper.class); private ServletContext delegate; @@ -71,17 +71,17 @@ public void addListener(Class arg0) { } @Override - public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, String arg1) { + public jakarta.servlet.ServletRegistration.Dynamic addServlet(String arg0, String arg1) { return delegate.addServlet(arg0, arg1); } @Override - public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, Servlet arg1) { + public jakarta.servlet.ServletRegistration.Dynamic addServlet(String arg0, Servlet arg1) { return delegate.addServlet(arg0, arg1); } @Override - public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, Class arg1) { + public jakarta.servlet.ServletRegistration.Dynamic addServlet(String arg0, Class arg1) { return delegate.addServlet(arg0, arg1); } @@ -222,7 +222,7 @@ public InputStream getResourceAsStream(String arg0) { return fsResource.openStream(); } } catch (IOException e) { - log.warn("Error occurred when retieving file" + arg0, e); + LOG.warn("Error occurred when retieving file" + arg0, e); } } return delegate.getResourceAsStream(arg0); @@ -238,23 +238,11 @@ public String getServerInfo() { return delegate.getServerInfo(); } - @SuppressWarnings("deprecation") - @Override - public Servlet getServlet(String arg0) throws ServletException { - return delegate.getServlet(arg0); - } - @Override public String getServletContextName() { return delegate.getServletContextName(); } - @SuppressWarnings("deprecation") - @Override - public Enumeration getServletNames() { - return delegate.getServletNames(); - } - @Override public ServletRegistration getServletRegistration(String arg0) { return delegate.getServletRegistration(arg0); @@ -265,12 +253,6 @@ public ServletRegistration getServletRegistration(String arg0) { return delegate.getServletRegistrations(); } - @SuppressWarnings("deprecation") - @Override - public Enumeration getServlets() { - return delegate.getServlets(); - } - @Override public SessionCookieConfig getSessionCookieConfig() { return delegate.getSessionCookieConfig(); @@ -281,12 +263,6 @@ public void log(String arg0) { delegate.log(arg0); } - @SuppressWarnings("deprecation") - @Override - public void log(Exception arg0, String arg1) { - delegate.log(arg0, arg1); - } - @Override public void log(String arg0, Throwable arg1) { delegate.log(arg0, arg1); @@ -339,7 +315,7 @@ public String getVirtualServerName() { } @Override - public javax.servlet.ServletRegistration.Dynamic addJspFile(String servletName, String jspFile) { + public jakarta.servlet.ServletRegistration.Dynamic addJspFile(String servletName, String jspFile) { return delegate.addJspFile(servletName, jspFile); } diff --git a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/listener/IDPHttpSessionListener.java b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/listener/IDPHttpSessionListener.java deleted file mode 100644 index deec0c39e..000000000 --- a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/listener/IDPHttpSessionListener.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * JBoss, a division of Red Hat - * Copyright 2012, Red Hat Middleware, LLC, and individual - * contributors as indicated 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.gatein.sso.saml.plugin.listener; - -import org.exoplatform.services.log.ExoLogger; -import org.exoplatform.services.log.Log; -import org.gatein.sso.integration.SSOUtils; - -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; - -/** - * Class exists to avoid dependency on picketlink module from gatein.ear and use it only during SAML2 setup - * - * @author Marek Posolda - */ -public class IDPHttpSessionListener implements HttpSessionListener -{ - private static final Log log = ExoLogger.getLogger(IDPHttpSessionListener.class); - - private static final String PROPERTY_IDP_ENABLED = "gatein.sso.idp.listener.enabled"; - - private volatile HttpSessionListener delegate; - - public void sessionDestroyed(HttpSessionEvent se) - { - if ("true".equals(SSOUtils.getSystemProperty(PROPERTY_IDP_ENABLED, "false"))) - { - HttpSessionListener delegate = getOrInitDelegate(); - delegate.sessionDestroyed(se); - } - else - { - if (log.isTraceEnabled()) - { - log.trace("Portal is not acting as SAML2 IDP. Ignore this listener"); - } - } - } - - public void sessionCreated(HttpSessionEvent se) - { - } - - private HttpSessionListener getOrInitDelegate() - { - if (delegate == null) - { - synchronized (this) - { - if (delegate == null) - { - delegate = new org.picketlink.identity.federation.web.listeners.IDPHttpSessionListener(); - } - } - } - - return delegate; - } -} diff --git a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/AbstractSAML11SPRedirectFormAuthenticator.java b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/AbstractSAML11SPRedirectFormAuthenticator.java index b2505b45e..ca62df499 100644 --- a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/AbstractSAML11SPRedirectFormAuthenticator.java +++ b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/AbstractSAML11SPRedirectFormAuthenticator.java @@ -8,8 +8,8 @@ import java.util.ArrayList; import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.catalina.LifecycleException; import org.apache.catalina.Session; diff --git a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/AbstractSPFormAuthenticator.java b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/AbstractSPFormAuthenticator.java index 37e42368a..c177f8ceb 100644 --- a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/AbstractSPFormAuthenticator.java +++ b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/AbstractSPFormAuthenticator.java @@ -15,10 +15,6 @@ import java.util.List; import java.util.Set; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; import org.apache.catalina.Session; @@ -27,23 +23,12 @@ import org.apache.catalina.connector.Response; import org.apache.catalina.realm.GenericPrincipal; import org.apache.tomcat.util.descriptor.web.LoginConfig; -import org.exoplatform.container.ExoContainer; -import org.exoplatform.container.ExoContainerContext; -import org.exoplatform.container.PortalContainer; -import org.exoplatform.container.RootContainer; -import org.exoplatform.services.organization.Membership; -import org.exoplatform.services.organization.OrganizationService; -import org.exoplatform.services.security.IdentityRegistry; -import org.exoplatform.services.security.MembershipEntry; -import org.exoplatform.services.security.MembershipHashSet; -import org.exoplatform.services.security.RolesExtractor; import org.picketlink.common.ErrorCodes; import org.picketlink.common.constants.GeneralConstants; import org.picketlink.common.constants.JBossSAMLConstants; import org.picketlink.common.exceptions.ConfigurationException; import org.picketlink.common.exceptions.ParsingException; import org.picketlink.common.exceptions.ProcessingException; -import org.picketlink.common.exceptions.TrustKeyProcessingException; import org.picketlink.common.exceptions.fed.AssertionExpiredException; import org.picketlink.common.util.DocumentUtil; import org.picketlink.common.util.StringUtil; @@ -69,719 +54,800 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.exoplatform.container.PortalContainer; +import org.exoplatform.services.organization.Membership; +import org.exoplatform.services.organization.OrganizationService; +import org.exoplatform.services.security.MembershipEntry; +import org.exoplatform.services.security.MembershipHashSet; +import org.exoplatform.services.security.RolesExtractor; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + /** - * Abstract class to be extended by Service Provider valves to handle SAML requests and responses. - * forked from org.picketlink.identity.federation.bindings.tomcat.sp.AbstractSPFormAuthenticator - * and made compatible with Tomcat 8.5 since picketlink doesn't provide such a support + * Abstract class to be extended by Service Provider valves to handle SAML + * requests and responses. forked from + * org.picketlink.identity.federation.bindings.tomcat.sp.AbstractSPFormAuthenticator + * and made compatible with Tomcat 8.5 since picketlink doesn't provide such a + * support */ public abstract class AbstractSPFormAuthenticator extends BaseFormAuthenticator { - - protected boolean jbossEnv = false; - - public AbstractSPFormAuthenticator() { - super(); - ServerDetector detector = new ServerDetector(); - jbossEnv = detector.isJboss(); + private static final String FORM_PRINCIPAL_NOTE = "org.apache.catalina.authenticator.PRINCIPAL"; + + protected boolean jbossEnv = false; + + AbstractSPFormAuthenticator() { + super(); + ServerDetector detector = new ServerDetector(); + jbossEnv = detector.isJboss(); + } + + /* + * (non-Javadoc) + * @see + * org.picketlink.identity.federation.bindings.tomcat.sp.BaseFormAuthenticator + * #processStart() + */ + @Override + protected void startPicketLink() throws LifecycleException { + super.startPicketLink(); + initKeyProvider(context); + } + + /** + *

+ * Send the request to the IDP. Subclasses should override this method to + * implement how requests must be sent to the IDP. + *

+ * + * @param destination idp url + * @param samlDocument request or response document + * @param relayState used in SAML Workflow + * @param response Apache Catalina HTTP Response + * @param request Apache Catalina HTTP Request + * @param willSendRequest are we sending Request or Response to IDP + * @param destinationQueryStringWithSignature used only with Redirect binding + * and with signature enabled. + * @throws ProcessingException Exception to indicate a server processing error + * @throws ConfigurationException Exception indicating an issue with the + * configuration + * @throws IOException I/O exception + */ + protected void sendRequestToIDP(String destination, + Document samlDocument, + String relayState, + Request request, + Response response, + boolean willSendRequest, + String destinationQueryStringWithSignature) throws ProcessingException, + ConfigurationException, + IOException { + + if (isAjaxRequest(request) && request.getUserPrincipal() == null) { + response.sendError(Response.SC_FORBIDDEN); + } else { + if (isHttpPostBinding()) { + sendHttpPostBindingRequest(destination, samlDocument, relayState, response, willSendRequest); + } else { + sendHttpRedirectRequest(destination, + samlDocument, + relayState, + response, + willSendRequest, + destinationQueryStringWithSignature); + } } - - /* - * (non-Javadoc) - * - * @see org.picketlink.identity.federation.bindings.tomcat.sp.BaseFormAuthenticator#processStart() - */ - @Override - protected void startPicketLink() throws LifecycleException { - super.startPicketLink(); - initKeyProvider(context); + } + + /** + *

+ * Sends a HTTP Redirect request to the IDP. + *

+ * + * @param destination idp url + * @param samlDocument SAML request document + * @param relayState used in SAML Workflow + * @param response Apache Catalina HTTP Response + * @param willSendRequest are we sending Request or Response to IDP + * @param destinationQueryStringWithSignature used only with Redirect binding + * and with signature enabled. + * @throws IOException I/O exception + * @throws UnsupportedEncodingException when decoding SAML Message + * @throws ConfigurationException Exception indicating an issue with the + * configuration + * @throws ProcessingException Exception to indicate a server processing error + */ + protected void sendHttpRedirectRequest(String destination, + Document samlDocument, + String relayState, + Response response, + boolean willSendRequest, + String destinationQueryStringWithSignature) throws IOException, + ProcessingException, + ConfigurationException { + String destinationQueryString = null; + + // We already have queryString with signature from + // SAML2SignatureGenerationHandler + if (destinationQueryStringWithSignature != null) { + destinationQueryString = destinationQueryStringWithSignature; + } else { + String samlMessage = DocumentUtil.getDocumentAsString(samlDocument); + String base64Request = RedirectBindingUtil.deflateBase64URLEncode(samlMessage.getBytes("UTF-8")); + destinationQueryString = RedirectBindingUtil.getDestinationQueryString(base64Request, relayState, willSendRequest); } - /** - *

- * Send the request to the IDP. Subclasses should override this method to implement how requests must be sent to the IDP. - *

- * - * @param destination idp url - * @param samlDocument request or response document - * @param relayState used in SAML Workflow - * @param response Apache Catalina HTTP Response - * @param request Apache Catalina HTTP Request - * @param willSendRequest are we sending Request or Response to IDP - * @param destinationQueryStringWithSignature used only with Redirect binding and with signature enabled. - * @throws ProcessingException Exception to indicate a server processing error - * @throws ConfigurationException Exception indicating an issue with the configuration - * @throws IOException I/O exception - */ - protected void sendRequestToIDP(String destination, Document samlDocument, String relayState, Request request, Response response, - boolean willSendRequest, String destinationQueryStringWithSignature) throws ProcessingException, ConfigurationException, IOException { - - if (isAjaxRequest(request) && request.getUserPrincipal() == null) { - response.sendError(Response.SC_FORBIDDEN); - } else { - if (isHttpPostBinding()) { - sendHttpPostBindingRequest(destination, samlDocument, relayState, response, willSendRequest); - } else { - sendHttpRedirectRequest(destination, samlDocument, relayState, response, willSendRequest, destinationQueryStringWithSignature); - } - } + RedirectBindingUtilDestHolder holder = new RedirectBindingUtilDestHolder(); + + holder.setDestination(destination).setDestinationQueryString(destinationQueryString); + + HTTPRedirectUtil.sendRedirectForRequestor(RedirectBindingUtil.getDestinationURL(holder), response); + } + + /** + *

+ * Sends a HTTP POST request to the IDP. + *

+ * + * @param destination idp url + * @param samlDocument request or response document + * @param relayState used in SAML Workflow + * @param response Apache Catalina HTTP Response + * @param willSendRequest are we sending Request or Response to IDP + * @throws ProcessingException Exception to indicate a server processing error + * @throws ConfigurationException Exception indicating an issue with the + * configuration + * @throws IOException I/O exception + */ + protected void sendHttpPostBindingRequest(String destination, + Document samlDocument, + String relayState, + Response response, + boolean willSendRequest) throws ProcessingException, + IOException, + ConfigurationException { + String samlMessage = PostBindingUtil.base64Encode(DocumentUtil.getDocumentAsString(samlDocument)); + + DestinationInfoHolder destinationHolder = new DestinationInfoHolder(destination, samlMessage, relayState); + + PostBindingUtil.sendPost(destinationHolder, response, willSendRequest); + } + + /** + *

+ * Initialize the KeyProvider configurations. This configurations are to be + * used during signing and validation of SAML assertions. + *

+ * + * @param context Apache Catalina Context + * @throws LifecycleException any exception occurred while processing key + * provider + */ + protected void initKeyProvider(Context context) throws LifecycleException { + if (!doSupportSignature()) { + return; } - /** - *

- * Sends a HTTP Redirect request to the IDP. - *

- * - * @param destination idp url - * @param samlDocument SAML request document - * @param relayState used in SAML Workflow - * @param response Apache Catalina HTTP Response - * @param willSendRequest are we sending Request or Response to IDP - * @param destinationQueryStringWithSignature used only with Redirect binding and with signature enabled. - * @throws IOException I/O exception - * @throws UnsupportedEncodingException when decoding SAML Message - * @throws ConfigurationException Exception indicating an issue with the configuration - * @throws ProcessingException Exception to indicate a server processing error - */ - protected void sendHttpRedirectRequest(String destination, Document samlDocument, String relayState, Response response, - boolean willSendRequest, String destinationQueryStringWithSignature) throws IOException, - ProcessingException, ConfigurationException { - String destinationQueryString = null; - - // We already have queryString with signature from SAML2SignatureGenerationHandler - if (destinationQueryStringWithSignature != null) { - destinationQueryString = destinationQueryStringWithSignature; - } - else { - String samlMessage = DocumentUtil.getDocumentAsString(samlDocument); - String base64Request = RedirectBindingUtil.deflateBase64URLEncode(samlMessage.getBytes("UTF-8")); - destinationQueryString = RedirectBindingUtil.getDestinationQueryString(base64Request, relayState, willSendRequest); - } + KeyProviderType keyProvider = this.spConfiguration.getKeyProvider(); + + if (keyProvider == null && doSupportSignature()) + throw new LifecycleException(ErrorCodes.NULL_VALUE + "KeyProvider is null for context=" + context.getName()); + + try { + String keyManagerClassName = keyProvider.getClassName(); + if (keyManagerClassName == null) + throw new RuntimeException(ErrorCodes.NULL_VALUE + "KeyManager class name"); + + Class clazz = SecurityActions.loadClass(getClass(), keyManagerClassName); - RedirectBindingUtilDestHolder holder = new RedirectBindingUtilDestHolder(); + if (clazz == null) + throw new ClassNotFoundException(ErrorCodes.CLASS_NOT_LOADED + keyManagerClassName); + this.keyManager = (TrustKeyManager) clazz.newInstance(); - holder.setDestination(destination).setDestinationQueryString(destinationQueryString); + List authProperties = CoreConfigUtil.getKeyProviderProperties(keyProvider); - HTTPRedirectUtil.sendRedirectForRequestor(RedirectBindingUtil.getDestinationURL(holder), response); + keyManager.setAuthProperties(authProperties); + keyManager.setValidatingAlias(keyProvider.getValidatingAlias()); + + String identityURL = this.spConfiguration.getIdentityURL(); + + // Special case when you need X509Data in SignedInfo + if (authProperties != null) { + for (AuthPropertyType authPropertyType : authProperties) { + String key = authPropertyType.getKey(); + if (GeneralConstants.X509CERTIFICATE.equals(key)) { + // we need X509Certificate in SignedInfo. The value is the alias + // name + keyManager.addAdditionalOption(GeneralConstants.X509CERTIFICATE, authPropertyType.getValue()); + break; + } + } + } + keyManager.addAdditionalOption(ServiceProviderBaseProcessor.IDP_KEY, new URL(identityURL).getHost()); + } catch (Exception e) { + logger.trustKeyManagerCreationError(e); + throw new LifecycleException(e.getLocalizedMessage()); } - /** - *

- * Sends a HTTP POST request to the IDP. - *

- * - * @param destination idp url - * @param samlDocument request or response document - * @param relayState used in SAML Workflow - * @param response Apache Catalina HTTP Response - * @param willSendRequest are we sending Request or Response to IDP - * @throws ProcessingException Exception to indicate a server processing error - * @throws ConfigurationException Exception indicating an issue with the configuration - * @throws IOException I/O exception - */ - protected void sendHttpPostBindingRequest(String destination, Document samlDocument, String relayState, Response response, - boolean willSendRequest) throws ProcessingException, IOException, - ConfigurationException { - String samlMessage = PostBindingUtil.base64Encode(DocumentUtil.getDocumentAsString(samlDocument)); - - DestinationInfoHolder destinationHolder = new DestinationInfoHolder(destination, samlMessage, relayState); - - PostBindingUtil.sendPost(destinationHolder, response, willSendRequest); + logger.trace("Key Provider=" + keyProvider.getClassName()); + } + + @Override + protected boolean doAuthenticate(Request request, HttpServletResponse response) throws IOException { + if (response instanceof Response) { + LoginConfig loginConfig = request.getContext().getLoginConfig(); + Response catalinaResponse = (Response) response; + return authenticate(request, catalinaResponse, loginConfig); + } + throw logger.samlSPResponseNotCatalinaResponseError(response); + } + + /** + * Authenticate the request + * + * @param request Apache Catalina Request + * @param response Apache Catalina Response + * @return true if authenticated, else false + * @throws IOException any I/O exception + */ + public boolean authenticate(Request request, HttpServletResponse response) throws IOException { + if (response instanceof Response) { + LoginConfig loginConfig = request.getContext().getLoginConfig(); + Response catalinaResponse = (Response) response; + return authenticate(request, catalinaResponse, loginConfig); } + throw logger.samlSPResponseNotCatalinaResponseError(response); + } + + /* + * (non-Javadoc) + * @see + * org.apache.catalina.authenticator.FormAuthenticator#authenticate(org.apache + * .catalina.connector.Request, org.apache.catalina.connector.Response, + * org.apache.catalina.deploy.LoginConfig) + */ + private boolean authenticate(Request request, Response response, LoginConfig loginConfig) throws IOException { + try { + // needs to be done first, *before* accessing any parameters. + // super.authenticate(..) gets called to late + String characterEncoding = getCharacterEncoding(); + if (characterEncoding != null) { + request.setCharacterEncoding(characterEncoding); + } - /** - *

- * Initialize the KeyProvider configurations. This configurations are to be used during signing and validation of SAML - * assertions. - *

- * - * @param context Apache Catalina Context - * @throws LifecycleException any exception occurred while processing key provider - */ - protected void initKeyProvider(Context context) throws LifecycleException { - if (!doSupportSignature()) { - return; + Session session = request.getSessionInternal(true); + + // check if this call is resulting from the redirect after successful + // authentication. + // if so, make the authentication successful and continue the original + // request + if (saveRestoreRequest && matchRequest(request)) { + logger.trace("Restoring request from session '" + session.getIdInternal() + "'"); + Principal savedPrincipal = (Principal) session.getNote(FORM_PRINCIPAL_NOTE); + register(request, + response, + savedPrincipal, + HttpServletRequest.FORM_AUTH, + (String) session.getNote(Constants.SESS_USERNAME_NOTE), + (String) session.getNote(Constants.SESS_PASSWORD_NOTE)); + + // try to restore the original request (including post data, etc...) + if (restoreRequest(request, session)) { + // success! user is authenticated; continue processing original + // request + logger.trace("Continuing with restored request."); + return true; + } else { + // no saved request found... + logger.trace("Restore of original request failed!"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST); + return false; } + } - KeyProviderType keyProvider = this.spConfiguration.getKeyProvider(); - - if (keyProvider == null && doSupportSignature()) - throw new LifecycleException(ErrorCodes.NULL_VALUE + "KeyProvider is null for context=" + context.getName()); + // Eagerly look for Local LogOut + boolean localLogout = isLocalLogout(request); + if (localLogout) { try { - String keyManagerClassName = keyProvider.getClassName(); - if (keyManagerClassName == null) - throw new RuntimeException(ErrorCodes.NULL_VALUE + "KeyManager class name"); - - Class clazz = SecurityActions.loadClass(getClass(), keyManagerClassName); - - if (clazz == null) - throw new ClassNotFoundException(ErrorCodes.CLASS_NOT_LOADED + keyManagerClassName); - this.keyManager = (TrustKeyManager) clazz.newInstance(); - - List authProperties = CoreConfigUtil.getKeyProviderProperties(keyProvider); - - keyManager.setAuthProperties(authProperties); - keyManager.setValidatingAlias(keyProvider.getValidatingAlias()); - - String identityURL = this.spConfiguration.getIdentityURL(); - - //Special case when you need X509Data in SignedInfo - if(authProperties != null){ - for(AuthPropertyType authPropertyType: authProperties){ - String key = authPropertyType.getKey(); - if(GeneralConstants.X509CERTIFICATE.equals(key)){ - //we need X509Certificate in SignedInfo. The value is the alias name - keyManager.addAdditionalOption(GeneralConstants.X509CERTIFICATE, authPropertyType.getValue()); - break; - } - } - } - keyManager.addAdditionalOption(ServiceProviderBaseProcessor.IDP_KEY, new URL(identityURL).getHost()); - } catch (Exception e) { - logger.trustKeyManagerCreationError(e); - throw new LifecycleException(e.getLocalizedMessage()); + sendToLogoutPage(request, response, session); + } catch (ServletException e) { + logger.samlLogoutError(e); + throw new IOException(e); } + return false; + } - logger.trace("Key Provider=" + keyProvider.getClassName()); - } + String samlRequest = request.getParameter(GeneralConstants.SAML_REQUEST_KEY); + String samlResponse = request.getParameter(GeneralConstants.SAML_RESPONSE_KEY); - @Override - protected boolean doAuthenticate(Request request, HttpServletResponse response) throws IOException { - if (response instanceof Response) { - LoginConfig loginConfig = request.getContext().getLoginConfig(); - Response catalinaResponse = (Response) response; - return authenticate(request, catalinaResponse, loginConfig); + Principal principal = request.getUserPrincipal(); + + // If we have already authenticated the user and there is no request from + // IDP or logout from user + if (principal != null && !(isGlobalLogout(request) || isNotNull(samlRequest) || isNotNull(samlResponse))) + return true; + + // General User Request + if (!isNotNull(samlRequest) && !isNotNull(samlResponse)) { + return generalUserRequest(request, response, loginConfig); } - throw logger.samlSPResponseNotCatalinaResponseError(response); - } - /** - * Authenticate the request - * - * @param request Apache Catalina Request - * @param response Apache Catalina Response - * @return true if authenticated, else false - * @throws IOException any I/O exception - */ - public boolean authenticate(Request request, HttpServletResponse response) throws IOException { - if (response instanceof Response) { - LoginConfig loginConfig = request.getContext().getLoginConfig(); - Response catalinaResponse = (Response) response; - return authenticate(request, catalinaResponse, loginConfig); - } - throw logger.samlSPResponseNotCatalinaResponseError(response); - } + // Handle a SAML Response from IDP + if (isNotNull(samlResponse)) { + return handleSAMLResponse(request, response, loginConfig); + } - /* - * (non-Javadoc) - * - * @see org.apache.catalina.authenticator.FormAuthenticator#authenticate(org.apache.catalina.connector.Request, - * org.apache.catalina.connector.Response, org.apache.catalina.deploy.LoginConfig) - */ - private boolean authenticate(Request request, Response response, LoginConfig loginConfig) throws IOException { + // Handle SAML Requests from IDP + if (isNotNull(samlRequest)) { + return handleSAMLRequest(request, response, loginConfig); + } // end if + + return localAuthentication(request, response, loginConfig); + } catch (IOException e) { + if (StringUtil.isNotNull(spConfiguration.getErrorPage())) { try { - // needs to be done first, *before* accessing any parameters. super.authenticate(..) gets called to late - String characterEncoding = getCharacterEncoding(); - if (characterEncoding != null) { - request.setCharacterEncoding(characterEncoding); - } - - Session session = request.getSessionInternal(true); - - // check if this call is resulting from the redirect after successful authentication. - // if so, make the authentication successful and continue the original request - if (saveRestoreRequest && matchRequest(request)) { - logger.trace("Restoring request from session '" + session.getIdInternal() + "'"); - Principal savedPrincipal = (Principal)session.getNote(Constants.FORM_PRINCIPAL_NOTE); - register (request, response, savedPrincipal, HttpServletRequest.FORM_AUTH, (String)session.getNote(Constants.SESS_USERNAME_NOTE), (String)session.getNote(Constants.SESS_PASSWORD_NOTE)); - - // try to restore the original request (including post data, etc...) - if (restoreRequest(request, session)) { - // success! user is authenticated; continue processing original request - logger.trace("Continuing with restored request."); - return true; - } - else { - // no saved request found... - logger.trace("Restore of original request failed!"); - response.sendError(HttpServletResponse.SC_BAD_REQUEST); - return false; - } - } - - // Eagerly look for Local LogOut - boolean localLogout = isLocalLogout(request); - - if (localLogout) { - try { - sendToLogoutPage(request, response, session); - } catch (ServletException e) { - logger.samlLogoutError(e); - throw new IOException(e); - } - return false; - } - - String samlRequest = request.getParameter(GeneralConstants.SAML_REQUEST_KEY); - String samlResponse = request.getParameter(GeneralConstants.SAML_RESPONSE_KEY); - - Principal principal = request.getUserPrincipal(); - - // If we have already authenticated the user and there is no request from IDP or logout from user - if (principal != null && !(isGlobalLogout(request) || isNotNull(samlRequest) || isNotNull(samlResponse))) - return true; - - // General User Request - if (!isNotNull(samlRequest) && !isNotNull(samlResponse)) { - return generalUserRequest(request, response, loginConfig); - } - - // Handle a SAML Response from IDP - if (isNotNull(samlResponse)) { - return handleSAMLResponse(request, response, loginConfig); - } - - // Handle SAML Requests from IDP - if (isNotNull(samlRequest)) { - return handleSAMLRequest(request, response, loginConfig); - }// end if - - return localAuthentication(request, response, loginConfig); - } catch (IOException e) { - if (StringUtil.isNotNull(spConfiguration.getErrorPage())) { - try { - request.getRequestDispatcher(spConfiguration.getErrorPage()).forward(request.getRequest(), response); - } catch (ServletException e1) { - logger.samlErrorPageForwardError(spConfiguration.getErrorPage(), e1); - } - return false; - } else { - throw e; - } + request.getRequestDispatcher(spConfiguration.getErrorPage()).forward(request.getRequest(), response); + } catch (ServletException e1) { + logger.samlErrorPageForwardError(spConfiguration.getErrorPage(), e1); } + return false; + } else { + throw e; + } } - - /** - *

- * Indicates if the current request is a GlobalLogout request. - *

- * - * @param request Apache Catalina Request - * @return true if this is a global SAML logout - */ - private boolean isGlobalLogout(Request request) { - String gloStr = request.getParameter(GeneralConstants.GLOBAL_LOGOUT); - return isNotNull(gloStr) && "true".equalsIgnoreCase(gloStr); + } + + /** + *

+ * Indicates if the current request is a GlobalLogout request. + *

+ * + * @param request Apache Catalina Request + * @return true if this is a global SAML logout + */ + private boolean isGlobalLogout(Request request) { + String gloStr = request.getParameter(GeneralConstants.GLOBAL_LOGOUT); + return isNotNull(gloStr) && "true".equalsIgnoreCase(gloStr); + } + + /** + *

+ * Indicates if the current request is a LocalLogout request. + *

+ * + * @param request Apache Catalina Request + * @return true if this is a local SAML logout + */ + private boolean isLocalLogout(Request request) { + try { + if (request.getCharacterEncoding() == null) { + request.setCharacterEncoding("UTF-8"); + } + } catch (UnsupportedEncodingException e) { + logger.error("Request have no encoding, and we are unable to set it to UTF-8"); + logger.error(e); } + String lloStr = request.getParameter(GeneralConstants.LOCAL_LOGOUT); + return isNotNull(lloStr) && "true".equalsIgnoreCase(lloStr); + } + + /** + * Handle the IDP Request + * + * @param request Apache Catalina Request + * @param response Apache Catalina Response + * @param loginConfig Apache Catalina Login Config + * @return true if processed by SAML Workflow + * @throws IOException any I/O error while authenticating + */ + private boolean handleSAMLRequest(Request request, Response response, LoginConfig loginConfig) throws IOException { + String samlRequest = request.getParameter(GeneralConstants.SAML_REQUEST_KEY); + HTTPContext httpContext = new HTTPContext(request, response, context.getServletContext()); + Set handlers = chain.handlers(); + + try { + ServiceProviderSAMLRequestProcessor requestProcessor = new ServiceProviderSAMLRequestProcessor( + request.getMethod() + .equals("POST"), + this.serviceURL, + this.picketLinkConfiguration); + requestProcessor.setTrustKeyManager(keyManager); + boolean result = requestProcessor.process(samlRequest, httpContext, handlers, chainLock); + + if (enableAudit) { + PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent("Info"); + auditEvent.setType(PicketLinkAuditEventType.REQUEST_FROM_IDP); + auditEvent.setWhoIsAuditing(getContextPath()); + auditHelper.audit(auditEvent); + } - /** - *

- * Indicates if the current request is a LocalLogout request. - *

- * - * @param request Apache Catalina Request - * @return true if this is a local SAML logout - */ - private boolean isLocalLogout(Request request) { - try { - if (request.getCharacterEncoding()==null) { - request.setCharacterEncoding("UTF-8"); - } - } catch (UnsupportedEncodingException e) { - logger.error("Request have no encoding, and we are unable to set it to UTF-8"); - logger.error(e); - } - String lloStr = request.getParameter(GeneralConstants.LOCAL_LOGOUT); - return isNotNull(lloStr) && "true".equalsIgnoreCase(lloStr); + // If response is already commited, we need to stop with processing of + // HTTP request + if (response.isCommitted() || response.isAppCommitted()) + return false; + + if (result) + return result; + } catch (Exception e) { + logger.samlSPHandleRequestError(e); + throw logger.samlSPProcessingExceptionError(e); } - /** - * Handle the IDP Request - * - * @param request Apache Catalina Request - * @param response Apache Catalina Response - * @param loginConfig Apache Catalina Login Config - * @return true if processed by SAML Workflow - * @throws IOException any I/O error while authenticating - */ - private boolean handleSAMLRequest(Request request, Response response, LoginConfig loginConfig) throws IOException { - String samlRequest = request.getParameter(GeneralConstants.SAML_REQUEST_KEY); - HTTPContext httpContext = new HTTPContext(request, response, context.getServletContext()); - Set handlers = chain.handlers(); + return localAuthentication(request, response, loginConfig); + } - try { - ServiceProviderSAMLRequestProcessor requestProcessor = new ServiceProviderSAMLRequestProcessor( - request.getMethod().equals("POST"), this.serviceURL, this.picketLinkConfiguration); - requestProcessor.setTrustKeyManager(keyManager); - boolean result = requestProcessor.process(samlRequest, httpContext, handlers, chainLock); - - if (enableAudit) { - PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent("Info"); - auditEvent.setType(PicketLinkAuditEventType.REQUEST_FROM_IDP); - auditEvent.setWhoIsAuditing(getContextPath()); - auditHelper.audit(auditEvent); - } - - // If response is already commited, we need to stop with processing of HTTP request - if (response.isCommitted() || response.isAppCommitted()) - return false; - - if (result) - return result; - } catch (Exception e) { - logger.samlSPHandleRequestError(e); - throw logger.samlSPProcessingExceptionError(e); - } + private Document toSAMLResponseDocument(String samlResponse, boolean isPostBinding) throws ParsingException { + InputStream dataStream = null; - return localAuthentication(request, response, loginConfig); + if (isPostBinding) { + // deal with SAML response from IDP + dataStream = PostBindingUtil.base64DecodeAsStream(samlResponse); + } else { + // deal with SAML response from IDP + dataStream = RedirectBindingUtil.base64DeflateDecode(samlResponse); } - private Document toSAMLResponseDocument(String samlResponse, boolean isPostBinding) throws ParsingException { - InputStream dataStream = null; + try { + return DocumentUtil.getDocument(dataStream); + } catch (Exception e) { + logger.samlResponseFromIDPParsingFailed(); + throw new ParsingException("", e); + } + } + + /** + * Handle IDP Response + * + * @param request Apache Catalina Request + * @param response Apache Catalina Response + * @param loginConfig Apache Catalina Login Config + * @return true if logged in in SAML SP side + * @throws IOException any I/O error in authentication process + */ + private boolean handleSAMLResponse(Request request, Response response, LoginConfig loginConfig) throws IOException { + if (!super.validate(request)) { + throw new IOException(ErrorCodes.VALIDATION_CHECK_FAILED); + } - if (isPostBinding) { - // deal with SAML response from IDP - dataStream = PostBindingUtil.base64DecodeAsStream(samlResponse); - } else { - // deal with SAML response from IDP - dataStream = RedirectBindingUtil.base64DeflateDecode(samlResponse); - } + String samlVersion = getSAMLVersion(request); - try { - return DocumentUtil.getDocument(dataStream); - } catch (Exception e) { - logger.samlResponseFromIDPParsingFailed(); - throw new ParsingException("", e); - } + if (!JBossSAMLConstants.VERSION_2_0.get().equals(samlVersion)) { + return handleSAML11UnsolicitedResponse(request, response, loginConfig, this); } - /** - * Handle IDP Response - * - * @param request Apache Catalina Request - * @param response Apache Catalina Response - * @param loginConfig Apache Catalina Login Config - * @return true if logged in in SAML SP side - * @throws IOException any I/O error in authentication process - */ - private boolean handleSAMLResponse(Request request, Response response, LoginConfig loginConfig) throws IOException { - if (!super.validate(request)) { - throw new IOException(ErrorCodes.VALIDATION_CHECK_FAILED); - } + return handleSAML2Response(request, response, loginConfig); + } - String samlVersion = getSAMLVersion(request); + private boolean handleSAML2Response(Request request, Response response, LoginConfig loginConfig) throws IOException { + Session session = request.getSessionInternal(true); + String samlResponse = request.getParameter(GeneralConstants.SAML_RESPONSE_KEY); + HTTPContext httpContext = new HTTPContext(request, response, context.getServletContext()); + Set handlers = chain.handlers(); - if (!JBossSAMLConstants.VERSION_2_0.get().equals(samlVersion)) { - return handleSAML11UnsolicitedResponse(request, response, loginConfig, this); - } + Principal principal = request.getUserPrincipal(); - return handleSAML2Response(request, response, loginConfig); - } + boolean willSendRequest;// deal with SAML response from IDP - private boolean handleSAML2Response(Request request, Response response, LoginConfig loginConfig) throws IOException { - Session session = request.getSessionInternal(true); - String samlResponse = request.getParameter(GeneralConstants.SAML_RESPONSE_KEY); - HTTPContext httpContext = new HTTPContext(request, response, context.getServletContext()); - Set handlers = chain.handlers(); + try { + ServiceProviderSAMLResponseProcessor responseProcessor = + new ServiceProviderSAMLResponseProcessor(request.getMethod() + .equals("POST"), + serviceURL, + this.picketLinkConfiguration); + if (auditHelper != null) { + responseProcessor.setAuditHelper(auditHelper); + } - Principal principal = request.getUserPrincipal(); + responseProcessor.setTrustKeyManager(keyManager); - boolean willSendRequest;// deal with SAML response from IDP + SAML2HandlerResponse saml2HandlerResponse = responseProcessor.process(samlResponse, + httpContext, + handlers, + chainLock); - try { - ServiceProviderSAMLResponseProcessor responseProcessor = new ServiceProviderSAMLResponseProcessor(request.getMethod().equals("POST"), serviceURL, this.picketLinkConfiguration); - if(auditHelper != null){ - responseProcessor.setAuditHelper(auditHelper); - } - - responseProcessor.setTrustKeyManager(keyManager); - - SAML2HandlerResponse saml2HandlerResponse = responseProcessor.process(samlResponse, httpContext, handlers, - chainLock); - - Document samlResponseDocument = saml2HandlerResponse.getResultingDocument(); - String relayState = saml2HandlerResponse.getRelayState(); - - String destination = saml2HandlerResponse.getDestination(); - - willSendRequest = saml2HandlerResponse.getSendRequest(); - - String destinationQueryStringWithSignature = saml2HandlerResponse.getDestinationQueryStringWithSignature(); - - if (destination != null && samlResponseDocument != null) { - sendRequestToIDP(destination, samlResponseDocument, relayState, request, response, willSendRequest, destinationQueryStringWithSignature); - } else { - // See if the session has been invalidated - - boolean sessionValidity = session.isValid(); - - if (!sessionValidity) { - sendToLogoutPage(request, response, session); - return false; - } - - // We got a response with the principal - List roles = saml2HandlerResponse.getRoles(); - - if (principal == null) { - principal = (Principal) session.getSession().getAttribute(GeneralConstants.PRINCIPAL_ID); - } - - String username = principal.getName(); - String password = ServiceProviderSAMLContext.EMPTY_PASSWORD; - - roles.addAll(extractGateinRoles(username)); - if (logger.isTraceEnabled()) { - logger.trace("Roles determined for username=" + username + "=" + Arrays.toString(roles.toArray())); - } - - // Map to JBoss specific principal - if ((new ServerDetector()).isJboss() || jbossEnv) { - // Push a context - ServiceProviderSAMLContext.push(username, roles); - principal = context.getRealm().authenticate(username, password); - ServiceProviderSAMLContext.clear(); - } else { - // tomcat env - principal = getGenericPrincipal(request, username, roles); - } - - session.setNote(Constants.SESS_USERNAME_NOTE, username); - session.setNote(Constants.SESS_PASSWORD_NOTE, password); - request.setUserPrincipal(principal); - - if (enableAudit) { - PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent("Info"); - auditEvent.setType(PicketLinkAuditEventType.RESPONSE_FROM_IDP); - auditEvent.setSubjectName(username); - auditEvent.setWhoIsAuditing(getContextPath()); - auditHelper.audit(auditEvent); - } - - // Redirect the user to the originally requested URL - if (saveRestoreRequest) { - // Store the authenticated principal in the session. - session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal); - - // Redirect to the original URL. Note that this will trigger the - // authenticator again, but on resubmission we will look in the - // session notes to retrieve the authenticated principal and - // prevent reauthentication - String requestURI = savedRequestURL(session); - - if (requestURI != null) { - logger.trace("Redirecting back to original Request URI: " + requestURI); - response.sendRedirect(response.encodeRedirectURL(requestURI)); - } - } - - register(request, response, principal, HttpServletRequest.FORM_AUTH, username, password); - return true; - } - } catch (ProcessingException pe) { - Throwable t = pe.getCause(); - if (t != null && t instanceof AssertionExpiredException) { - logger.error("Assertion has expired. Asking IDP for reissue"); - if (enableAudit) { - PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent("Info"); - auditEvent.setType(PicketLinkAuditEventType.EXPIRED_ASSERTION); - auditEvent.setAssertionID(((AssertionExpiredException) t).getId()); - auditHelper.audit(auditEvent); - } - // Just issue a fresh request back to IDP - return generalUserRequest(request, response, loginConfig); - } - logger.samlSPHandleRequestError(pe); - throw logger.samlSPProcessingExceptionError(pe); - } catch (Exception e) { - logger.samlSPHandleRequestError(e); - throw logger.samlSPProcessingExceptionError(e); - } + Document samlResponseDocument = saml2HandlerResponse.getResultingDocument(); + String relayState = saml2HandlerResponse.getRelayState(); - return localAuthentication(request, response, loginConfig); - } + String destination = saml2HandlerResponse.getDestination(); - private String getSAMLVersion(Request request) { - String samlResponse = request.getParameter(GeneralConstants.SAML_RESPONSE_KEY); - String version; + willSendRequest = saml2HandlerResponse.getSendRequest(); - try { - Document samlDocument = toSAMLResponseDocument(samlResponse, "POST".equalsIgnoreCase(request.getMethod())); - Element element = samlDocument.getDocumentElement(); + String destinationQueryStringWithSignature = saml2HandlerResponse.getDestinationQueryStringWithSignature(); - // let's try SAML 2.0 Version attribute first - version = element.getAttribute("Version"); + if (destination != null && samlResponseDocument != null) { + sendRequestToIDP(destination, + samlResponseDocument, + relayState, + request, + response, + willSendRequest, + destinationQueryStringWithSignature); + } else { + // See if the session has been invalidated - if (isNullOrEmpty(version)) { - // fallback to SAML 1.1 Minor and Major attributes - String minorVersion = element.getAttribute("MinorVersion"); - String majorVersion = element.getAttribute("MajorVersion"); + boolean sessionValidity = session.isValid(); - version = minorVersion + "." + majorVersion; - } - } catch (Exception e) { - throw new RuntimeException("Could not extract version from SAML Response.", e); + if (!sessionValidity) { + sendToLogoutPage(request, response, session); + return false; } - return version; - } + // We got a response with the principal + List roles = saml2HandlerResponse.getRoles(); - protected boolean isPOSTBindingResponse() { - return spConfiguration.isIdpUsesPostBinding(); - } + if (principal == null) { + principal = (Principal) session.getSession().getAttribute(GeneralConstants.PRINCIPAL_ID); + } + String username = principal.getName(); + String password = ServiceProviderSAMLContext.EMPTY_PASSWORD; - /* - * (non-Javadoc) - * - * @see org.picketlink.identity.federation.bindings.tomcat.sp.BaseFormAuthenticator#getBinding() - */ - @Override - protected String getBinding() { - return spConfiguration.getBindingType(); - } + roles.addAll(extractGateinRoles(username)); + if (logger.isTraceEnabled()) { + logger.trace("Roles determined for username=" + username + "=" + Arrays.toString(roles.toArray())); + } - /** - * Handle the user invocation for the first time - * - * @param request Apache Catalina Request - * @param response Apache Catalina Response - * @param loginConfig Apache Catalina Login Config - * @return true if logged in in SAML SP side - * @throws IOException any I/O error in authentication process - */ - private boolean generalUserRequest(Request request, Response response, LoginConfig loginConfig) throws IOException { - Session session = request.getSessionInternal(true); - boolean willSendRequest = false; - HTTPContext httpContext = new HTTPContext(request, response, context.getServletContext()); - Set handlers = chain.handlers(); - - boolean postBinding = spConfiguration.getBindingType().equals("POST"); - - // Neither saml request nor response from IDP - // So this is a user request - SAML2HandlerResponse saml2HandlerResponse = null; - try { - ServiceProviderBaseProcessor baseProcessor = new ServiceProviderBaseProcessor(postBinding, serviceURL, this.picketLinkConfiguration); - if (issuerID != null) - baseProcessor.setIssuer(issuerID); - - // If the user has a different desired idp - String idp = (String) request.getAttribute(org.picketlink.identity.federation.web.constants.GeneralConstants.DESIRED_IDP); - if (StringUtil.isNotNull(idp)) { - baseProcessor.setIdentityURL(idp); - } else { - baseProcessor.setIdentityURL(identityURL); - } - baseProcessor.setAuditHelper(auditHelper); - - saml2HandlerResponse = baseProcessor.process(httpContext, handlers, chainLock); - } catch (ProcessingException pe) { - logger.samlSPHandleRequestError(pe); - throw new RuntimeException(pe); - } catch (ParsingException pe) { - logger.samlSPHandleRequestError(pe); - throw new RuntimeException(pe); - } catch (ConfigurationException pe) { - logger.samlSPHandleRequestError(pe); - throw new RuntimeException(pe); + // Map to JBoss specific principal + if ((new ServerDetector()).isJboss() || jbossEnv) { + // Push a context + ServiceProviderSAMLContext.push(username, roles); + principal = context.getRealm().authenticate(username, password); + ServiceProviderSAMLContext.clear(); + } else { + // tomcat env + principal = getGenericPrincipal(request, username, roles); } - willSendRequest = saml2HandlerResponse.getSendRequest(); - - Document samlResponseDocument = saml2HandlerResponse.getResultingDocument(); - String relayState = saml2HandlerResponse.getRelayState(); - - String destination = saml2HandlerResponse.getDestination(); - String destinationQueryStringWithSignature = saml2HandlerResponse.getDestinationQueryStringWithSignature(); - - if (destination != null && samlResponseDocument != null) { - try { - if (saveRestoreRequest && !isGlobalLogout(request)) { - this.saveRequest(request, session); - } - if (enableAudit) { - PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent("Info"); - auditEvent.setType(PicketLinkAuditEventType.REQUEST_TO_IDP); - auditEvent.setWhoIsAuditing(getContextPath()); - auditHelper.audit(auditEvent); - } - sendRequestToIDP(destination, samlResponseDocument, relayState, request, response, willSendRequest, destinationQueryStringWithSignature); - return false; - } catch (Exception e) { - logger.samlSPHandleRequestError(e); - throw logger.samlSPProcessingExceptionError(e); - } + session.setNote(Constants.SESS_USERNAME_NOTE, username); + session.setNote(Constants.SESS_PASSWORD_NOTE, password); + request.setUserPrincipal(principal); + + if (enableAudit) { + PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent("Info"); + auditEvent.setType(PicketLinkAuditEventType.RESPONSE_FROM_IDP); + auditEvent.setSubjectName(username); + auditEvent.setWhoIsAuditing(getContextPath()); + auditHelper.audit(auditEvent); } - return localAuthentication(request, response, loginConfig); - } - - /** - * Extract Gatein roles to put in Principal - * @param userId - * @return - */ - private List extractGateinRoles(String userId) { - OrganizationService organizationService = - PortalContainer.getInstance().getComponentInstanceOfType(OrganizationService.class); - RolesExtractor rolesExtractor=PortalContainer.getInstance().getComponentInstanceOfType(RolesExtractor.class); - List result = new ArrayList<>(); - Set entries = new MembershipHashSet(); - Collection memberships; - try { - memberships = organizationService.getMembershipHandler().findMembershipsByUser(userId); - } catch (Exception e) { - memberships = null; + // Redirect the user to the originally requested URL + if (saveRestoreRequest) { + // Store the authenticated principal in the session. + session.setNote(FORM_PRINCIPAL_NOTE, principal); + + // Redirect to the original URL. Note that this will trigger the + // authenticator again, but on resubmission we will look in the + // session notes to retrieve the authenticated principal and + // prevent reauthentication + String requestURI = savedRequestURL(session); + + if (requestURI != null) { + logger.trace("Redirecting back to original Request URI: " + requestURI); + response.sendRedirect(response.encodeRedirectURL(requestURI)); + } } - if (memberships != null) { - for (Membership membership : memberships) - entries.add(new MembershipEntry(membership.getGroupId(), membership.getMembershipType())); + + register(request, response, principal, HttpServletRequest.FORM_AUTH, username, password); + return true; + } + } catch (ProcessingException pe) { + Throwable t = pe.getCause(); + if (t != null && t instanceof AssertionExpiredException) { + logger.error("Assertion has expired. Asking IDP for reissue"); + if (enableAudit) { + PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent("Info"); + auditEvent.setType(PicketLinkAuditEventType.EXPIRED_ASSERTION); + auditEvent.setAssertionID(((AssertionExpiredException) t).getId()); + auditHelper.audit(auditEvent); } - result.addAll(rolesExtractor.extractRoles(userId, entries)); - return result; + // Just issue a fresh request back to IDP + return generalUserRequest(request, response, loginConfig); + } + logger.samlSPHandleRequestError(pe); + throw logger.samlSPProcessingExceptionError(pe); + } catch (Exception e) { + logger.samlSPHandleRequestError(e); + throw logger.samlSPProcessingExceptionError(e); } - /** - *

- * Indicates if the SP is configure with HTTP POST Binding. - *

- * - * @return true if post binding - */ - protected boolean isHttpPostBinding() { - return getBinding().equalsIgnoreCase("POST"); - } + return localAuthentication(request, response, loginConfig); + } + + private String getSAMLVersion(Request request) { + String samlResponse = request.getParameter(GeneralConstants.SAML_RESPONSE_KEY); + String version; + + try { + Document samlDocument = toSAMLResponseDocument(samlResponse, "POST".equalsIgnoreCase(request.getMethod())); + Element element = samlDocument.getDocumentElement(); - public Context getContext() { - return (Context) getContainer(); + // let's try SAML 2.0 Version attribute first + version = element.getAttribute("Version"); + + if (isNullOrEmpty(version)) { + // fallback to SAML 1.1 Minor and Major attributes + String minorVersion = element.getAttribute("MinorVersion"); + String majorVersion = element.getAttribute("MajorVersion"); + + version = minorVersion + "." + majorVersion; + } + } catch (Exception e) { + throw new RuntimeException("Could not extract version from SAML Response.", e); } - @Override - public boolean restoreRequest(Request request, Session session) throws IOException { - return super.restoreRequest(request, session); + return version; + } + + protected boolean isPOSTBindingResponse() { + return spConfiguration.isIdpUsesPostBinding(); + } + + /* + * (non-Javadoc) + * @see + * org.picketlink.identity.federation.bindings.tomcat.sp.BaseFormAuthenticator + * #getBinding() + */ + @Override + protected String getBinding() { + return spConfiguration.getBindingType(); + } + + /** + * Handle the user invocation for the first time + * + * @param request Apache Catalina Request + * @param response Apache Catalina Response + * @param loginConfig Apache Catalina Login Config + * @return true if logged in in SAML SP side + * @throws IOException any I/O error in authentication process + */ + private boolean generalUserRequest(Request request, Response response, LoginConfig loginConfig) throws IOException { + Session session = request.getSessionInternal(true); + boolean willSendRequest = false; + HTTPContext httpContext = new HTTPContext(request, response, context.getServletContext()); + Set handlers = chain.handlers(); + + boolean postBinding = spConfiguration.getBindingType().equals("POST"); + + // Neither saml request nor response from IDP + // So this is a user request + SAML2HandlerResponse saml2HandlerResponse = null; + try { + ServiceProviderBaseProcessor baseProcessor = new ServiceProviderBaseProcessor(postBinding, + serviceURL, + this.picketLinkConfiguration); + if (issuerID != null) + baseProcessor.setIssuer(issuerID); + + // If the user has a different desired idp + String idp = (String) request.getAttribute(org.picketlink.identity.federation.web.constants.GeneralConstants.DESIRED_IDP); + if (StringUtil.isNotNull(idp)) { + baseProcessor.setIdentityURL(idp); + } else { + baseProcessor.setIdentityURL(identityURL); + } + baseProcessor.setAuditHelper(auditHelper); + + saml2HandlerResponse = baseProcessor.process(httpContext, handlers, chainLock); + } catch (ProcessingException pe) { + logger.samlSPHandleRequestError(pe); + throw new RuntimeException(pe); + } catch (ParsingException pe) { + logger.samlSPHandleRequestError(pe); + throw new RuntimeException(pe); + } catch (ConfigurationException pe) { + logger.samlSPHandleRequestError(pe); + throw new RuntimeException(pe); } - /** - * Subclasses need to return the context path - * based on the capability of their servlet api - * - * @return Servlet Context Path - */ - protected abstract String getContextPath(); - - protected Principal getGenericPrincipal(Request request, String username, List roles){ - //sometimes, IDP send username in assertion with capitals letters, or with inconsistent format. - //this option allows to force the username in lower case, just before creating the principal, - //so that, all operations in exo side will use a consistant format. - String forceLowerCase = System.getProperty("gatein.sso.saml.username.forcelowercase","false"); - if(forceLowerCase.equalsIgnoreCase("true")) { - username=username.toLowerCase(); + willSendRequest = saml2HandlerResponse.getSendRequest(); + + Document samlResponseDocument = saml2HandlerResponse.getResultingDocument(); + String relayState = saml2HandlerResponse.getRelayState(); + + String destination = saml2HandlerResponse.getDestination(); + String destinationQueryStringWithSignature = saml2HandlerResponse.getDestinationQueryStringWithSignature(); + + if (destination != null && samlResponseDocument != null) { + try { + if (saveRestoreRequest && !isGlobalLogout(request)) { + this.saveRequest(request, session); + } + if (enableAudit) { + PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent("Info"); + auditEvent.setType(PicketLinkAuditEventType.REQUEST_TO_IDP); + auditEvent.setWhoIsAuditing(getContextPath()); + auditHelper.audit(auditEvent); } - return new GenericPrincipal(username, null, roles); + sendRequestToIDP(destination, + samlResponseDocument, + relayState, + request, + response, + willSendRequest, + destinationQueryStringWithSignature); + return false; + } catch (Exception e) { + logger.samlSPHandleRequestError(e); + throw logger.samlSPProcessingExceptionError(e); + } } - private boolean isAjaxRequest(Request request) { - String requestedWithHeader = request.getHeader(GeneralConstants.HTTP_HEADER_X_REQUESTED_WITH); - return requestedWithHeader != null && "XMLHttpRequest".equalsIgnoreCase(requestedWithHeader); + return localAuthentication(request, response, loginConfig); + } + + /** + * Extract Gatein roles to put in Principal + * + * @param userId + * @return + */ + private List extractGateinRoles(String userId) { + OrganizationService organizationService = + PortalContainer.getInstance().getComponentInstanceOfType(OrganizationService.class); + RolesExtractor rolesExtractor = PortalContainer.getInstance().getComponentInstanceOfType(RolesExtractor.class); + List result = new ArrayList<>(); + Set entries = new MembershipHashSet(); + Collection memberships; + try { + memberships = organizationService.getMembershipHandler().findMembershipsByUser(userId); + } catch (Exception e) { + memberships = null; } + if (memberships != null) { + for (Membership membership : memberships) + entries.add(new MembershipEntry(membership.getGroupId(), membership.getMembershipType())); + } + result.addAll(rolesExtractor.extractRoles(userId, entries)); + return result; + } + + /** + *

+ * Indicates if the SP is configure with HTTP POST Binding. + *

+ * + * @return true if post binding + */ + protected boolean isHttpPostBinding() { + return getBinding().equalsIgnoreCase("POST"); + } + + public Context getContext() { + return (Context) getContainer(); + } + + @Override + public boolean restoreRequest(Request request, Session session) throws IOException { + return super.restoreRequest(request, session); + } + + /** + * Subclasses need to return the context path based on the capability of their + * servlet api + * + * @return Servlet Context Path + */ + protected abstract String getContextPath(); + + protected Principal getGenericPrincipal(Request request, String username, List roles) { + // sometimes, IDP send username in assertion with capitals letters, or with + // inconsistent format. + // this option allows to force the username in lower case, just before + // creating the principal, + // so that, all operations in exo side will use a consistant format. + String forceLowerCase = System.getProperty("gatein.sso.saml.username.forcelowercase", "false"); + if (forceLowerCase.equalsIgnoreCase("true")) { + username = username.toLowerCase(); + } + return new GenericPrincipal(username, null, roles); + } + + private boolean isAjaxRequest(Request request) { + String requestedWithHeader = request.getHeader(GeneralConstants.HTTP_HEADER_X_REQUESTED_WITH); + return requestedWithHeader != null && "XMLHttpRequest".equalsIgnoreCase(requestedWithHeader); + } } diff --git a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/BaseFormAuthenticator.java b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/BaseFormAuthenticator.java index 8bcc5a4cd..eb8571056 100644 --- a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/BaseFormAuthenticator.java +++ b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/BaseFormAuthenticator.java @@ -3,11 +3,14 @@ import static org.picketlink.common.constants.GeneralConstants.CONFIG_FILE_LOCATION; import static org.picketlink.common.util.StringUtil.isNullOrEmpty; +import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Paths; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.List; @@ -18,11 +21,11 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import javax.xml.crypto.dsig.CanonicalizationMethod; import org.apache.catalina.Context; @@ -31,7 +34,10 @@ import org.apache.catalina.authenticator.FormAuthenticator; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; import org.apache.tomcat.util.descriptor.web.LoginConfig; +import org.gatein.sso.saml.plugin.filter.SAMLSPServletContextWrapper; import org.picketlink.common.ErrorCodes; import org.picketlink.common.PicketLinkLogger; import org.picketlink.common.PicketLinkLoggerFactory; @@ -68,556 +74,602 @@ import org.picketlink.identity.federation.web.util.SAMLConfigurationProvider; import org.w3c.dom.Document; +import org.exoplatform.commons.utils.PropertyManager; +import org.exoplatform.container.xml.Deserializer; + /** - * Base Class for Service Provider Form Authenticators - * forked from org.picketlink.identity.federation.bindings.tomcat.sp.BaseFormAuthenticator - * and made compatible with Tomcat 8.5 since picketlink doesn't provide such a support + * Base Class for Service Provider Form Authenticators forked from + * org.picketlink.identity.federation.bindings.tomcat.sp.BaseFormAuthenticator + * and made compatible with Tomcat 8.5 since picketlink doesn't provide such a + * support */ public abstract class BaseFormAuthenticator extends FormAuthenticator { - protected static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger(); - - protected boolean enableAudit = false; - protected PicketLinkAuditHelper auditHelper = null; - - protected TrustKeyManager keyManager; - - protected SPType spConfiguration = null; - - protected PicketLinkType picketLinkConfiguration = null; - - protected String serviceURL = null; - - protected String identityURL = null; - - protected String issuerID = null; - - protected String configFile; - - /** - * If the service provider is configured with an IDP metadata file, then this certificate can be picked up from the metadata - */ - protected transient X509Certificate idpCertificate = null; - - protected transient SAML2HandlerChain chain = null; - - protected transient String samlHandlerChainClass = null; + protected static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger(); - protected Map chainConfigOptions = new HashMap(); + protected boolean enableAudit = false; - // Whether the authenticator has to to save and restore request - protected boolean saveRestoreRequest = true; - - /** - * A Lock for Handler operations in the chain - */ - protected Lock chainLock = new ReentrantLock(); - - protected String canonicalizationMethod = CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS; - - /** - * The user can inject a fully qualified name of a {@link SAMLConfigurationProvider} - */ - protected SAMLConfigurationProvider configProvider = null; - - protected int timerInterval = -1; - - protected Timer timer = null; - - public BaseFormAuthenticator() { - super(); - } - - protected String idpAddress = null; - - /** - * If the request.getRemoteAddr is not exactly the IDP address that you have keyed in your deployment descriptor for - * keystore alias, you can set it here explicitly - * - * @param idpAddress IP address of IDP - */ - public void setIdpAddress(String idpAddress) { - this.idpAddress = idpAddress; - } - - /** - * Get the name of the configuration file - * @return SAML config file path - */ - public String getConfigFile() { - return configFile; - } + protected PicketLinkAuditHelper auditHelper = null; - /** - * Set the name of the configuration file - * @param configFile set config file path - */ - public void setConfigFile(String configFile) { - this.configFile = configFile; - } + protected TrustKeyManager keyManager; - /** - * Set the SAML Handler Chain Class fqn - * @param samlHandlerChainClass FQN of SAML Handler Chain - */ - public void setSamlHandlerChainClass(String samlHandlerChainClass) { - this.samlHandlerChainClass = samlHandlerChainClass; - } + protected SPType spConfiguration = null; - /** - * Set the service URL - * @param serviceURL Service URL - */ - public void setServiceURL(String serviceURL) { - this.serviceURL = serviceURL; + protected PicketLinkType picketLinkConfiguration = null; + + protected String serviceURL = null; + + protected String identityURL = null; + + protected String issuerID = null; + + protected String configFile; + + /** + * If the service provider is configured with an IDP metadata file, then this + * certificate can be picked up from the metadata + */ + protected transient X509Certificate idpCertificate = null; + + protected transient SAML2HandlerChain chain = null; + + protected transient String samlHandlerChainClass = null; + + protected Map chainConfigOptions = new HashMap(); + + // Whether the authenticator has to to save and restore request + protected boolean saveRestoreRequest = true; + + /** + * A Lock for Handler operations in the chain + */ + protected Lock chainLock = new ReentrantLock(); + + protected String canonicalizationMethod = CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS; + + /** + * The user can inject a fully qualified name of a + * {@link SAMLConfigurationProvider} + */ + protected SAMLConfigurationProvider configProvider = null; + + protected int timerInterval = -1; + + protected Timer timer = null; + + public BaseFormAuthenticator() { + super(); + } + + protected String idpAddress = null; + + /** + * If the request.getRemoteAddr is not exactly the IDP address that you have + * keyed in your deployment descriptor for keystore alias, you can set it here + * explicitly + * + * @param idpAddress IP address of IDP + */ + public void setIdpAddress(String idpAddress) { + this.idpAddress = idpAddress; + } + + /** + * Get the name of the configuration file + * + * @return SAML config file path + */ + public String getConfigFile() { + return configFile; + } + + /** + * Set the name of the configuration file + * + * @param configFile set config file path + */ + public void setConfigFile(String configFile) { + this.configFile = configFile; + } + + /** + * Set the SAML Handler Chain Class fqn + * + * @param samlHandlerChainClass FQN of SAML Handler Chain + */ + public void setSamlHandlerChainClass(String samlHandlerChainClass) { + this.samlHandlerChainClass = samlHandlerChainClass; + } + + /** + * Set the service URL + * + * @param serviceURL Service URL + */ + public void setServiceURL(String serviceURL) { + this.serviceURL = serviceURL; + } + + /** + * Set whether the authenticator saves/restores the request during form + * authentication + * + * @param saveRestoreRequest saves/restores the request during authentication + * if true + */ + public void setSaveRestoreRequest(boolean saveRestoreRequest) { + this.saveRestoreRequest = saveRestoreRequest; + } + + /** + * Set the {@link SAMLConfigurationProvider} fqn + * + * @param cp fqn of a {@link SAMLConfigurationProvider} + */ + public void setConfigProvider(String cp) { + if (cp == null) + throw new IllegalStateException(ErrorCodes.NULL_ARGUMENT + cp); + Class clazz = SecurityActions.loadClass(getClass(), cp); + if (clazz == null) + throw new RuntimeException(ErrorCodes.CLASS_NOT_LOADED + cp); + try { + configProvider = (SAMLConfigurationProvider) clazz.newInstance(); + } catch (Exception e) { + throw new RuntimeException(ErrorCodes.CANNOT_CREATE_INSTANCE + cp + ":" + e.getMessage()); } - - /** - * Set whether the authenticator saves/restores the request - * during form authentication - * @param saveRestoreRequest saves/restores the request during authentication if true - */ - public void setSaveRestoreRequest(boolean saveRestoreRequest) { - this.saveRestoreRequest = saveRestoreRequest; + } + + /** + * Set an instance of the {@link SAMLConfigurationProvider} + * + * @param configProvider SAML IDP/SP config provider + */ + public void setConfigProvider(SAMLConfigurationProvider configProvider) { + this.configProvider = configProvider; + } + + /** + * Get the {@link SPType} + * + * @return SAML SP configuration + */ + public SPType getConfiguration() { + return spConfiguration; + } + + /** + * Set a separate issuer id + * + * @param issuerID id of the issuer + */ + public void setIssuerID(String issuerID) { + this.issuerID = issuerID; + } + + /** + * Set the logout page + * + * @param logOutPage logout page URL + */ + public void setLogOutPage(String logOutPage) { + logger.warn("Option logOutPage is now configured with the PicketLinkSP element."); + + } + + /** + * Set the Timer Value to reload the configuration + * + * @param value an integer value that represents timer value (in miliseconds) + */ + public void setTimerInterval(String value) { + if (StringUtil.isNotNull(value)) { + timerInterval = Integer.parseInt(value); } - - /** - * Set the {@link SAMLConfigurationProvider} fqn - * @param cp fqn of a {@link SAMLConfigurationProvider} - */ - public void setConfigProvider(String cp) { - if (cp == null) - throw new IllegalStateException(ErrorCodes.NULL_ARGUMENT + cp); - Class clazz = SecurityActions.loadClass(getClass(), cp); - if (clazz == null) - throw new RuntimeException(ErrorCodes.CLASS_NOT_LOADED + cp); + } + + /** + * Perform validation os the request object + * + * @param request Apache Catalina Request + * @return true if request contains a SAML Response parameter + */ + protected boolean validate(Request request) { + return request.getParameter("SAMLResponse") != null; + } + + /** + * Get the Identity URL + * + * @return Identity URL + */ + public String getIdentityURL() { + return identityURL; + } + + /** + * Get the {@link X509Certificate} of the IDP if provided via the IDP metadata + * file + * + * @return {@link X509Certificate} or null + */ + public X509Certificate getIdpCertificate() { + return idpCertificate; + } + + /** + * Fall back on local authentication at the service provider side + * + * @param request Apache Catalina Request + * @param response Apache Catalina Response + * @param loginConfig Apache Catalina Login Config + * @return true if authenticated + * @throws IOException any I/O error during authentication + */ + protected boolean localAuthentication(Request request, Response response, LoginConfig loginConfig) throws IOException { + if (request.getUserPrincipal() == null) { + logger.samlSPFallingBackToLocalFormAuthentication();// fallback + try { + return super.authenticate(request, response.getResponse()); + } catch (NoSuchMethodError e) { + // Use Reflection try { - configProvider = (SAMLConfigurationProvider) clazz.newInstance(); - } catch (Exception e) { - throw new RuntimeException(ErrorCodes.CANNOT_CREATE_INSTANCE + cp + ":" + e.getMessage()); + Method method = super.getClass().getMethod("authenticate", + new Class[] { HttpServletRequest.class, HttpServletResponse.class, + LoginConfig.class }); + return (Boolean) method.invoke(this, + new Object[] { request.getRequest(), response.getResponse(), + loginConfig }); + } catch (Exception ex) { + throw logger.unableLocalAuthentication(ex); } + } + } else + return true; + } + + /** + * Return the SAML Binding that this authenticator supports + * + * @return supported SAML Binding + */ + protected abstract String getBinding(); + + /** + * Attempt to process a metadata file available locally + * + * @param idpMetadataFile path of configuration file of IDP Metadata + */ + protected void processIDPMetadataFile(String idpMetadataFile) { + ServletContext servletContext = context.getServletContext(); + InputStream is = servletContext.getResourceAsStream(idpMetadataFile); + if (is == null) + return; + + Object metadata = null; + try { + Document samlDocument = DocumentUtil.getDocument(is); + SAMLParser parser = new SAMLParser(); + metadata = parser.parse(DocumentUtil.getNodeAsStream(samlDocument)); + } catch (Exception e) { + throw new RuntimeException(e); } - - /** - * Set an instance of the {@link SAMLConfigurationProvider} - * @param configProvider SAML IDP/SP config provider - */ - public void setConfigProvider(SAMLConfigurationProvider configProvider) { - this.configProvider = configProvider; + IDPSSODescriptorType idpSSO = null; + if (metadata instanceof EntitiesDescriptorType) { + EntitiesDescriptorType entities = (EntitiesDescriptorType) metadata; + idpSSO = handleMetadata(entities); + } else { + idpSSO = handleMetadata((EntityDescriptorType) metadata); } - - /** - * Get the {@link SPType} - * @return SAML SP configuration - */ - public SPType getConfiguration() { - return spConfiguration; + if (idpSSO == null) { + logger.samlSPUnableToGetIDPDescriptorFromMetadata(); + return; } - - /** - * Set a separate issuer id - * - * @param issuerID id of the issuer - */ - public void setIssuerID(String issuerID) { - this.issuerID = issuerID; + List endpoints = idpSSO.getSingleSignOnService(); + for (EndpointType endpoint : endpoints) { + String endpointBinding = endpoint.getBinding().toString(); + if (endpointBinding.contains("HTTP-POST")) + endpointBinding = "POST"; + else if (endpointBinding.contains("HTTP-Redirect")) + endpointBinding = "REDIRECT"; + if (getBinding().equals(endpointBinding)) { + identityURL = endpoint.getLocation().toString(); + break; + } } - - /** - * Set the logout page - * @param logOutPage logout page URL - */ - public void setLogOutPage(String logOutPage) { - logger.warn("Option logOutPage is now configured with the PicketLinkSP element."); - + List keyDescriptors = idpSSO.getKeyDescriptor(); + if (keyDescriptors.size() > 0) { + this.idpCertificate = MetaDataExtractor.getCertificate(keyDescriptors.get(0)); } - - /** - * Set the Timer Value to reload the configuration - * @param value an integer value that represents timer value (in miliseconds) - */ - public void setTimerInterval(String value){ - if(StringUtil.isNotNull(value)){ - timerInterval = Integer.parseInt(value); + } + + /** + * Process the configuration from the configuration file + */ + @SuppressWarnings("deprecation") + protected void processConfiguration() { + ServletContext servletContext = context.getServletContext(); + InputStream is = null; + try { + if (isNullOrEmpty(this.configFile)) { + this.configFile = PropertyManager.getProperty("gatein.sso.saml.config.file"); + if (StringUtils.contains(this.configFile, "$")) { + this.configFile = Deserializer.resolveString(this.configFile); } - } - - /** - * Perform validation os the request object - * - * @param request Apache Catalina Request - * @return true if request contains a SAML Response parameter - */ - protected boolean validate(Request request) { - return request.getParameter("SAMLResponse") != null; - } - - /** - * Get the Identity URL - * - * @return Identity URL - */ - public String getIdentityURL() { - return identityURL; - } - - /** - * Get the {@link X509Certificate} of the IDP if provided via the IDP metadata file - * - * @return {@link X509Certificate} or null - */ - public X509Certificate getIdpCertificate() { - return idpCertificate; - } - - /** - * Fall back on local authentication at the service provider side - * - * @param request Apache Catalina Request - * @param response Apache Catalina Response - * @param loginConfig Apache Catalina Login Config - * @return true if authenticated - * @throws IOException any I/O error during authentication - */ - protected boolean localAuthentication(Request request, Response response, LoginConfig loginConfig) throws IOException { - if (request.getUserPrincipal() == null) { - logger.samlSPFallingBackToLocalFormAuthentication();// fallback - try { - return super.authenticate(request, response.getResponse()); - } catch (NoSuchMethodError e) { - // Use Reflection - try { - Method method = super.getClass().getMethod("authenticate", - new Class[] { HttpServletRequest.class, HttpServletResponse.class, LoginConfig.class }); - return (Boolean) method.invoke(this, new Object[] { request.getRequest(), response.getResponse(), - loginConfig }); - } catch (Exception ex) { - throw logger.unableLocalAuthentication(ex); - } - } - } else - return true; - } - - /** - * Return the SAML Binding that this authenticator supports - * - * @return supported SAML Binding - */ - protected abstract String getBinding(); - - /** - * Attempt to process a metadata file available locally - * - * @param idpMetadataFile path of configuration file of IDP Metadata - */ - protected void processIDPMetadataFile(String idpMetadataFile) { - ServletContext servletContext = context.getServletContext(); - InputStream is = servletContext.getResourceAsStream(idpMetadataFile); - if (is == null) - return; - - Object metadata = null; - try { - Document samlDocument = DocumentUtil.getDocument(is); - SAMLParser parser = new SAMLParser(); - metadata = parser.parse(DocumentUtil.getNodeAsStream(samlDocument)); - } catch (Exception e) { - throw new RuntimeException(e); + if (StringUtils.isBlank(this.configFile)) { + this.configFile = CONFIG_FILE_LOCATION; } - IDPSSODescriptorType idpSSO = null; - if (metadata instanceof EntitiesDescriptorType) { - EntitiesDescriptorType entities = (EntitiesDescriptorType) metadata; - idpSSO = handleMetadata(entities); + if (Files.exists(Paths.get(this.configFile))) { + is = new FileInputStream(this.configFile); } else { - idpSSO = handleMetadata((EntityDescriptorType) metadata); - } - if (idpSSO == null) { - logger.samlSPUnableToGetIDPDescriptorFromMetadata(); - return; + this.configFile = SAMLSPServletContextWrapper.FILE_PREFIX + this.configFile; + is = servletContext.getResourceAsStream(this.configFile); } - List endpoints = idpSSO.getSingleSignOnService(); - for (EndpointType endpoint : endpoints) { - String endpointBinding = endpoint.getBinding().toString(); - if (endpointBinding.contains("HTTP-POST")) - endpointBinding = "POST"; - else if (endpointBinding.contains("HTTP-Redirect")) - endpointBinding = "REDIRECT"; - if (getBinding().equals(endpointBinding)) { - identityURL = endpoint.getLocation().toString(); - break; - } - } - List keyDescriptors = idpSSO.getKeyDescriptor(); - if (keyDescriptors.size() > 0) { - this.idpCertificate = MetaDataExtractor.getCertificate(keyDescriptors.get(0)); - } - } - - /** - * Process the configuration from the configuration file - */ - @SuppressWarnings("deprecation") - protected void processConfiguration() { - ServletContext servletContext = context.getServletContext(); - InputStream is = null; - - if (isNullOrEmpty(this.configFile)) { - this.configFile = CONFIG_FILE_LOCATION; - is = servletContext.getResourceAsStream(this.configFile); - } else { - try { - is = new FileInputStream(this.configFile); - } catch (FileNotFoundException e) { - throw logger.samlIDPConfigurationError(e); - } + } else { + try { + is = new FileInputStream(this.configFile); + } catch (FileNotFoundException e) { + throw logger.samlIDPConfigurationError(e); } + } + // Work on the IDP Configuration + if (configProvider != null) { try { - // Work on the IDP Configuration - if (configProvider != null) { - try { - if (is == null) { - // Try the older version - is = servletContext.getResourceAsStream(GeneralConstants.DEPRECATED_CONFIG_FILE_LOCATION); - - // Additionally parse the deprecated config file - if (is != null && configProvider instanceof AbstractSAMLConfigurationProvider) { - ((AbstractSAMLConfigurationProvider) configProvider).setConfigFile(is); - } - } else { - // Additionally parse the consolidated config file - if (is != null && configProvider instanceof AbstractSAMLConfigurationProvider) { - ((AbstractSAMLConfigurationProvider) configProvider).setConsolidatedConfigFile(is); - } - } - - picketLinkConfiguration = configProvider.getPicketLinkConfiguration(); - spConfiguration = configProvider.getSPConfiguration(); - } catch (ProcessingException e) { - throw logger.samlSPConfigurationError(e); - } catch (ParsingException e) { - throw logger.samlSPConfigurationError(e); - } - } else { - if (is != null) { - try { - picketLinkConfiguration = ConfigurationUtil.getConfiguration(is); - spConfiguration = (SPType) picketLinkConfiguration.getIdpOrSP(); - } catch (ParsingException e) { - logger.trace(e); - throw logger.samlSPConfigurationError(e); - } - } else { - is = servletContext.getResourceAsStream(GeneralConstants.DEPRECATED_CONFIG_FILE_LOCATION); - if (is == null) - throw logger.configurationFileMissing(configFile); - spConfiguration = ConfigurationUtil.getSPConfiguration(is); - } - } - - if (this.picketLinkConfiguration != null) { - enableAudit = picketLinkConfiguration.isEnableAudit(); + if (is == null) { + // Try the older version + is = servletContext.getResourceAsStream(GeneralConstants.DEPRECATED_CONFIG_FILE_LOCATION); - //See if we have the system property enabled - if(!enableAudit){ - String sysProp = SecurityActions.getSystemProperty(GeneralConstants.AUDIT_ENABLE, "NULL"); - if(!"NULL".equals(sysProp)){ - enableAudit = Boolean.parseBoolean(sysProp); - } - } - - if (enableAudit) { - if (auditHelper == null) { - String securityDomainName = PicketLinkAuditHelper.getSecurityDomainName(servletContext); - - auditHelper = new PicketLinkAuditHelper(securityDomainName); - } - } + // Additionally parse the deprecated config file + if (is != null && configProvider instanceof AbstractSAMLConfigurationProvider) { + ((AbstractSAMLConfigurationProvider) configProvider).setConfigFile(is); } - - if (StringUtil.isNotNull(spConfiguration.getIdpMetadataFile())) { - processIDPMetadataFile(spConfiguration.getIdpMetadataFile()); - } else { - this.identityURL = spConfiguration.getIdentityURL(); + } else { + // Additionally parse the consolidated config file + if (is != null && configProvider instanceof AbstractSAMLConfigurationProvider) { + ((AbstractSAMLConfigurationProvider) configProvider).setConsolidatedConfigFile(is); } - this.serviceURL = spConfiguration.getServiceURL(); - this.canonicalizationMethod = spConfiguration.getCanonicalizationMethod(); + } + + picketLinkConfiguration = configProvider.getPicketLinkConfiguration(); + spConfiguration = configProvider.getSPConfiguration(); + } catch (ProcessingException e) { + throw logger.samlSPConfigurationError(e); + } catch (ParsingException e) { + throw logger.samlSPConfigurationError(e); + } + } else { + if (is != null) { + try { + picketLinkConfiguration = ConfigurationUtil.getConfiguration(is); + spConfiguration = (SPType) picketLinkConfiguration.getIdpOrSP(); + } catch (ParsingException e) { + logger.trace(e); + throw logger.samlSPConfigurationError(e); + } + } else { + is = servletContext.getResourceAsStream(GeneralConstants.DEPRECATED_CONFIG_FILE_LOCATION); + if (is == null) + throw logger.configurationFileMissing(configFile); + spConfiguration = ConfigurationUtil.getSPConfiguration(is); + } + } - logger.samlSPSettingCanonicalizationMethod(canonicalizationMethod); - XMLSignatureUtil.setCanonicalizationMethodType(canonicalizationMethod); + if (this.picketLinkConfiguration != null) { + enableAudit = picketLinkConfiguration.isEnableAudit(); - logger.trace("Identity Provider URL=" + this.identityURL); - } catch (Exception e) { - throw new RuntimeException(e); + // See if we have the system property enabled + if (!enableAudit) { + String sysProp = SecurityActions.getSystemProperty(GeneralConstants.AUDIT_ENABLE, "NULL"); + if (!"NULL".equals(sysProp)) { + enableAudit = Boolean.parseBoolean(sysProp); + } } - } - protected IDPSSODescriptorType handleMetadata(EntitiesDescriptorType entities) { - IDPSSODescriptorType idpSSO = null; - - List entityDescs = entities.getEntityDescriptor(); - for (Object entityDescriptor : entityDescs) { - if (entityDescriptor instanceof EntitiesDescriptorType) { - idpSSO = getIDPSSODescriptor(entities); - } else - idpSSO = handleMetadata((EntityDescriptorType) entityDescriptor); - if (idpSSO != null) - break; + if (enableAudit) { + if (auditHelper == null) { + String securityDomainName = PicketLinkAuditHelper.getSecurityDomainName(servletContext); + + auditHelper = new PicketLinkAuditHelper(securityDomainName); + } + } + } + + if (StringUtil.isNotNull(spConfiguration.getIdpMetadataFile())) { + processIDPMetadataFile(spConfiguration.getIdpMetadataFile()); + } else { + this.identityURL = spConfiguration.getIdentityURL(); + } + this.serviceURL = spConfiguration.getServiceURL(); + this.canonicalizationMethod = spConfiguration.getCanonicalizationMethod(); + + logger.samlSPSettingCanonicalizationMethod(canonicalizationMethod); + XMLSignatureUtil.setCanonicalizationMethodType(canonicalizationMethod); + + logger.trace("Identity Provider URL=" + this.identityURL); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + logger.trace("Can't close Input Stream", e); } - return idpSSO; + } } - - protected IDPSSODescriptorType handleMetadata(EntityDescriptorType entityDescriptor) { - return CoreConfigUtil.getIDPDescriptor(entityDescriptor); + } + + protected IDPSSODescriptorType handleMetadata(EntitiesDescriptorType entities) { + IDPSSODescriptorType idpSSO = null; + + List entityDescs = entities.getEntityDescriptor(); + for (Object entityDescriptor : entityDescs) { + if (entityDescriptor instanceof EntitiesDescriptorType) { + idpSSO = getIDPSSODescriptor(entities); + } else + idpSSO = handleMetadata((EntityDescriptorType) entityDescriptor); + if (idpSSO != null) + break; } + return idpSSO; + } - protected IDPSSODescriptorType getIDPSSODescriptor(EntitiesDescriptorType entities) { - List entityDescs = entities.getEntityDescriptor(); - for (Object entityDescriptor : entityDescs) { + protected IDPSSODescriptorType handleMetadata(EntityDescriptorType entityDescriptor) { + return CoreConfigUtil.getIDPDescriptor(entityDescriptor); + } - if (entityDescriptor instanceof EntitiesDescriptorType) { - return getIDPSSODescriptor((EntitiesDescriptorType) entityDescriptor); - } - return CoreConfigUtil.getIDPDescriptor((EntityDescriptorType) entityDescriptor); - } - return null; + protected IDPSSODescriptorType getIDPSSODescriptor(EntitiesDescriptorType entities) { + List entityDescs = entities.getEntityDescriptor(); + for (Object entityDescriptor : entityDescs) { + + if (entityDescriptor instanceof EntitiesDescriptorType) { + return getIDPSSODescriptor((EntitiesDescriptorType) entityDescriptor); + } + return CoreConfigUtil.getIDPDescriptor((EntityDescriptorType) entityDescriptor); } + return null; + } - protected void initializeHandlerChain() throws ConfigurationException, ProcessingException { - populateChainConfig(); - SAML2HandlerChainConfig handlerChainConfig = new DefaultSAML2HandlerChainConfig(chainConfigOptions); + protected void initializeHandlerChain() throws ConfigurationException, ProcessingException { + populateChainConfig(); + SAML2HandlerChainConfig handlerChainConfig = new DefaultSAML2HandlerChainConfig(chainConfigOptions); - Set samlHandlers = chain.handlers(); + Set samlHandlers = chain.handlers(); - for (SAML2Handler handler : samlHandlers) { - handler.initChainConfig(handlerChainConfig); - } + for (SAML2Handler handler : samlHandlers) { + handler.initChainConfig(handlerChainConfig); } - - protected void populateChainConfig() throws ConfigurationException, ProcessingException { - chainConfigOptions.put(GeneralConstants.CONFIGURATION, spConfiguration); - chainConfigOptions.put(GeneralConstants.ROLE_VALIDATOR_IGNORE, "false"); // No validator as tomcat realm does validn - - if (doSupportSignature()) { - chainConfigOptions.put(GeneralConstants.KEYPAIR, keyManager.getSigningKeyPair()); - //If there is a need for X509Data in signedinfo - String certificateAlias = (String)keyManager.getAdditionalOption(GeneralConstants.X509CERTIFICATE); - if(certificateAlias != null){ - chainConfigOptions.put(GeneralConstants.X509CERTIFICATE, keyManager.getCertificate(certificateAlias)); - } - } + } + + protected void populateChainConfig() throws ConfigurationException, ProcessingException { + chainConfigOptions.put(GeneralConstants.CONFIGURATION, spConfiguration); + chainConfigOptions.put(GeneralConstants.ROLE_VALIDATOR_IGNORE, "false"); // No + // validator + // as + // tomcat + // realm + // does + // validn + + if (doSupportSignature()) { + chainConfigOptions.put(GeneralConstants.KEYPAIR, keyManager.getSigningKeyPair()); + // If there is a need for X509Data in signedinfo + String certificateAlias = (String) keyManager.getAdditionalOption(GeneralConstants.X509CERTIFICATE); + if (certificateAlias != null) { + chainConfigOptions.put(GeneralConstants.X509CERTIFICATE, keyManager.getCertificate(certificateAlias)); + } } - - protected void sendToLogoutPage(Request request, Response response, Session session) throws IOException, ServletException { - // we are invalidated. - RequestDispatcher dispatch = context.getServletContext().getRequestDispatcher(this.getConfiguration().getLogOutPage()); - if (dispatch == null) - logger.samlSPCouldNotDispatchToLogoutPage(this.getConfiguration().getLogOutPage()); - else { - logger.trace("Forwarding request to logOutPage: " + this.getConfiguration().getLogOutPage()); - session.expire(); - try { - dispatch.forward(request, response); - } catch (Exception e) { - // JBAS5.1 and 6 quirkiness - dispatch.forward(request.getRequest(), response); - } + } + + protected void sendToLogoutPage(Request request, Response response, Session session) throws IOException, ServletException { + // we are invalidated. + RequestDispatcher dispatch = context.getServletContext().getRequestDispatcher(this.getConfiguration().getLogOutPage()); + if (dispatch == null) + logger.samlSPCouldNotDispatchToLogoutPage(this.getConfiguration().getLogOutPage()); + else { + logger.trace("Forwarding request to logOutPage: " + this.getConfiguration().getLogOutPage()); + session.expire(); + try { + dispatch.forward(request, response); + } catch (Exception e) { + // JBAS5.1 and 6 quirkiness + dispatch.forward(request.getRequest(), response); + } + } + } + + // Mock test purpose + public void testStart() throws LifecycleException { + this.saveRestoreRequest = false; + if (context == null) + throw new RuntimeException("Catalina Context not set up"); + startPicketLink(); + } + + protected void startPicketLink() throws LifecycleException { + SystemPropertiesUtil.ensure(); + Handlers handlers = null; + + // Introduce a timer to reload configuration if desired + if (timerInterval > 0) { + if (timer == null) { + timer = new Timer(); + } + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + // Clear the configuration + picketLinkConfiguration = null; + spConfiguration = null; + + processConfiguration(); + try { + initKeyProvider(context); + } catch (LifecycleException e) { + logger.trace(e.getMessage()); + } } + }, timerInterval, timerInterval); } - // Mock test purpose - public void testStart() throws LifecycleException { - this.saveRestoreRequest = false; - if (context == null) - throw new RuntimeException("Catalina Context not set up"); - startPicketLink(); + // Get the chain from config + if (StringUtil.isNullOrEmpty(samlHandlerChainClass)) { + chain = SAML2HandlerChainFactory.createChain(); + } else { + try { + chain = SAML2HandlerChainFactory.createChain(this.samlHandlerChainClass); + } catch (ProcessingException e1) { + throw new LifecycleException(e1); + } } - protected void startPicketLink() throws LifecycleException { - SystemPropertiesUtil.ensure(); - Handlers handlers = null; + ServletContext servletContext = context.getServletContext(); - //Introduce a timer to reload configuration if desired - if(timerInterval > 0 ){ - if(timer == null){ - timer = new Timer(); - } - timer.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - //Clear the configuration - picketLinkConfiguration = null; - spConfiguration = null; - - processConfiguration(); - try { - initKeyProvider(context); - } catch (LifecycleException e) { - logger.trace(e.getMessage()); - } - } - }, timerInterval, timerInterval); - } + this.processConfiguration(); - // Get the chain from config - if (StringUtil.isNullOrEmpty(samlHandlerChainClass)) { - chain = SAML2HandlerChainFactory.createChain(); - } else { - try { - chain = SAML2HandlerChainFactory.createChain(this.samlHandlerChainClass); - } catch (ProcessingException e1) { - throw new LifecycleException(e1); - } - } + try { + if (picketLinkConfiguration != null) { + handlers = picketLinkConfiguration.getHandlers(); + } else { + // Get the handlers + String handlerConfigFileName = GeneralConstants.HANDLER_CONFIG_FILE_LOCATION; + handlers = ConfigurationUtil.getHandlers(servletContext.getResourceAsStream(handlerConfigFileName)); + } - ServletContext servletContext = context.getServletContext(); + chain.addAll(HandlerUtil.getHandlers(handlers)); - this.processConfiguration(); - - try { - if (picketLinkConfiguration != null) { - handlers = picketLinkConfiguration.getHandlers(); - } else { - // Get the handlers - String handlerConfigFileName = GeneralConstants.HANDLER_CONFIG_FILE_LOCATION; - handlers = ConfigurationUtil.getHandlers(servletContext.getResourceAsStream(handlerConfigFileName)); - } - - chain.addAll(HandlerUtil.getHandlers(handlers)); - - this.initKeyProvider(context); - this.populateChainConfig(); - this.initializeHandlerChain(); - } catch (Exception e) { - throw new RuntimeException(e); - } + this.initKeyProvider(context); + this.populateChainConfig(); + this.initializeHandlerChain(); + } catch (Exception e) { + throw new RuntimeException(e); + } - if (this.picketLinkConfiguration == null) { - this.picketLinkConfiguration = new PicketLinkType(); + if (this.picketLinkConfiguration == null) { + this.picketLinkConfiguration = new PicketLinkType(); - this.picketLinkConfiguration.setIdpOrSP(getConfiguration()); - this.picketLinkConfiguration.setHandlers(handlers); - } + this.picketLinkConfiguration.setIdpOrSP(getConfiguration()); + this.picketLinkConfiguration.setHandlers(handlers); } - - /** - *

- * Indicates if digital signatures/validation of SAML assertions are enabled. Subclasses that supports signature should - * override this method. - *

- * - * @return true if SP Configuration supports signature - */ - protected boolean doSupportSignature() { - if (spConfiguration != null) { - return spConfiguration.isSupportsSignature(); - } - return false; + } + + /** + *

+ * Indicates if digital signatures/validation of SAML assertions are enabled. + * Subclasses that supports signature should override this method. + *

+ * + * @return true if SP Configuration supports signature + */ + protected boolean doSupportSignature() { + if (spConfiguration != null) { + return spConfiguration.isSupportsSignature(); } + return false; + } - protected abstract void initKeyProvider(Context context) throws LifecycleException; + protected abstract void initKeyProvider(Context context) throws LifecycleException; - public void setAuditHelper(PicketLinkAuditHelper auditHelper) { - this.auditHelper = auditHelper; - } + public void setAuditHelper(PicketLinkAuditHelper auditHelper) { + this.auditHelper = auditHelper; + } } diff --git a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/ServiceProviderAuthenticator.java b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/ServiceProviderAuthenticator.java index ae8afcacd..e5314939f 100644 --- a/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/ServiceProviderAuthenticator.java +++ b/saml/gatein-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/ServiceProviderAuthenticator.java @@ -2,12 +2,6 @@ import org.apache.catalina.LifecycleException; - -/** - * Unified Service Provider Authenticator - * Forked from org.picketlink.identity.federation.bindings.tomcat.sp.ServiceProviderAuthenticator - * and made compatible with Tomcat 8.5 since picketlink doesn't provide such a support - */ public class ServiceProviderAuthenticator extends AbstractSPFormAuthenticator { @Override diff --git a/saml/gatein-saml-plugin/src/main/resources/conf/configuration.xml b/saml/gatein-saml-plugin/src/main/resources/conf/configuration.xml new file mode 100644 index 000000000..b8c940b02 --- /dev/null +++ b/saml/gatein-saml-plugin/src/main/resources/conf/configuration.xml @@ -0,0 +1,38 @@ + + + + + + SAMLProperties + org.exoplatform.container.ExtendedPropertyConfigurator + + + SAMLProperties + + + + + + + + diff --git a/saml/gatein-saml-plugin/src/main/resources/conf/portal/configuration.xml b/saml/gatein-saml-plugin/src/main/resources/conf/portal/configuration.xml index 5bdaea41f..a8f2b1435 100644 --- a/saml/gatein-saml-plugin/src/main/resources/conf/portal/configuration.xml +++ b/saml/gatein-saml-plugin/src/main/resources/conf/portal/configuration.xml @@ -1,68 +1,68 @@ + org.gatein.sso.integration.SSOFilterIntegrator - PortalIDPWebBrowserSSOFilter + LoginRedirectFilter addPlugin org.gatein.sso.integration.SSOFilterIntegratorPlugin filterClass - org.gatein.sso.saml.plugin.filter.PortalIDPWebBrowserSSOFilter + org.gatein.sso.agent.filter.LoginRedirectFilter enabled - ${gatein.sso.filter.saml.idp.enabled:false} + ${gatein.sso.filter.login.enabled:true} filterMapping /sso - CONFIG_FILE - ${gatein.sso.saml.config.file} - - - IGNORE_SIGNATURES - ${gatein.sso.saml.signature.ignore:true} + LOGIN_URL + ${gatein.sso.filter.login.sso.url} + + + + org.gatein.sso.integration.SSOFilterIntegrator - PortalSPWebBrowserSSOFilter + LogoutFilter addPlugin org.gatein.sso.integration.SSOFilterIntegratorPlugin filterClass - org.gatein.sso.saml.plugin.filter.SAML2LogoutFilter + ${gatein.sso.filter.logout.class} enabled - ${gatein.sso.saml.sp.enabled:false} + ${gatein.sso.filter.logout.enabled:true} filterMapping @@ -70,7 +70,7 @@ CONFIG_FILE - ${exo.conf.dir}/saml2/picketlink-sp.xml + ${gatein.sso.saml.config.file} IGNORE_SIGNATURES @@ -80,7 +80,12 @@ ROLES users + + LOGOUT_URL + ${gatein.sso.filter.logout.url} + + diff --git a/saml/gatein-saml-plugin/src/test/java/org/gatein/sso/saml/plugin/filter/PortalIDPWebBrowserSSOFilterTest.java b/saml/gatein-saml-plugin/src/test/java/org/gatein/sso/saml/plugin/filter/PortalIDPWebBrowserSSOFilterTest.java deleted file mode 100644 index 85b298ac0..000000000 --- a/saml/gatein-saml-plugin/src/test/java/org/gatein/sso/saml/plugin/filter/PortalIDPWebBrowserSSOFilterTest.java +++ /dev/null @@ -1,108 +0,0 @@ -package org.gatein.sso.saml.plugin.filter; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.startsWith; -import static org.mockito.Mockito.doCallRealMethod; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.mockito.internal.verification.VerificationModeFactory; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.picketlink.common.constants.GeneralConstants; -import org.picketlink.identity.federation.web.filters.IDPFilter; - -import junit.framework.TestCase; - -public class PortalIDPWebBrowserSSOFilterTest extends TestCase { - - public void testLoginRedirect() throws Exception { - // Given - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - HttpSession httpSession = mock(HttpSession.class); - FilterChain chain = mock(FilterChain.class); - - FilterConfig filterConfig = mock(FilterConfig.class); - ServletContext servletContext = mock(ServletContext.class); - - PortalIDPWebBrowserSSOFilter idpWebBrowserSSOFilter = mock(PortalIDPWebBrowserSSOFilter.class); - - // When - when(response.encodeRedirectURL(any())).thenAnswer(new Answer() { - public String answer(InvocationOnMock invocation) throws Throwable { - return (String) invocation.getArguments()[0]; - } - }); - when(request.getSession()).thenReturn(httpSession); - when(request.getSession(anyBoolean())).thenReturn(httpSession); - when(request.getParameter(GeneralConstants.SAML_REQUEST_KEY)).thenReturn("SOME SAML REQUEST"); - when(request.getRequestURI()).thenReturn("/portal"); - when(httpSession.getId()).thenReturn("fakeHttpSession"); - when(filterConfig.getServletContext()).thenReturn(servletContext); - when(servletContext.getServletContextName()).thenReturn("portal"); - when(servletContext.getContextPath()).thenReturn("/portal"); - when(request.getContextPath()).thenReturn("/portal"); - - doNothing().when(((IDPFilter)idpWebBrowserSSOFilter)).doFilter(request, response, chain); - doCallRealMethod().when(idpWebBrowserSSOFilter).doFilter(request, response, chain); - - idpWebBrowserSSOFilter.init(filterConfig); - idpWebBrowserSSOFilter.doFilter(request, response, chain); - // Then - verify(response, VerificationModeFactory.times(1)).sendRedirect(startsWith("/portal/dologin?initialURI=")); - verify(chain, VerificationModeFactory.times(0)).doFilter(request, response); - } - - public void testSAMLLogin() throws Exception { - // Given - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletRequest originalRequest = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - HttpSession httpSession = mock(HttpSession.class); - FilterChain chain = mock(FilterChain.class); - - FilterConfig filterConfig = mock(FilterConfig.class); - ServletContext servletContext = mock(ServletContext.class); - - PortalIDPWebBrowserSSOFilter idpWebBrowserSSOFilter = mock(PortalIDPWebBrowserSSOFilter.class); - - // When - when(response.encodeRedirectURL(any())).thenAnswer(new Answer() { - public String answer(InvocationOnMock invocation) throws Throwable { - return (String) invocation.getArguments()[0]; - } - }); - when(request.getSession()).thenReturn(httpSession); - when(request.getSession(anyBoolean())).thenReturn(httpSession); - when(httpSession.getAttribute(PortalIDPWebBrowserSSOFilter.ORIGINAL_HTTP_SERVLET_REQUEST_PARAM)).thenReturn(originalRequest); - when(request.getRequestURI()).thenReturn("/portal"); - when(httpSession.getId()).thenReturn("fakeHttpSession"); - when(filterConfig.getServletContext()).thenReturn(servletContext); - when(servletContext.getServletContextName()).thenReturn("portal"); - when(servletContext.getContextPath()).thenReturn("/portal"); - when(request.getContextPath()).thenReturn("/portal"); - when(idpWebBrowserSSOFilter.getInitParameter(GeneralConstants.ROLES)).thenReturn("users"); - - doNothing().when(((IDPFilter)idpWebBrowserSSOFilter)).doFilter(request, response, chain); - doCallRealMethod().when(idpWebBrowserSSOFilter).doFilter(request, response, chain); - - idpWebBrowserSSOFilter.init(filterConfig); - idpWebBrowserSSOFilter.doFilter(request, response, chain); - - // Then - verify(response, VerificationModeFactory.times(0)).sendRedirect(any()); - verify(chain, VerificationModeFactory.times(0)).doFilter(request, response); - verify(httpSession, VerificationModeFactory.times(1)).removeAttribute(PortalIDPWebBrowserSSOFilter.ORIGINAL_HTTP_SERVLET_REQUEST_PARAM); - } -} diff --git a/saml/gatein-saml-plugin/src/test/java/org/gatein/sso/saml/plugin/filter/SAML2LogoutFilterTest.java b/saml/gatein-saml-plugin/src/test/java/org/gatein/sso/saml/plugin/filter/SAML2LogoutFilterTest.java index bd71d64ed..2c55b2219 100644 --- a/saml/gatein-saml-plugin/src/test/java/org/gatein/sso/saml/plugin/filter/SAML2LogoutFilterTest.java +++ b/saml/gatein-saml-plugin/src/test/java/org/gatein/sso/saml/plugin/filter/SAML2LogoutFilterTest.java @@ -7,12 +7,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import org.mockito.internal.verification.VerificationModeFactory; import org.picketlink.common.constants.GeneralConstants;