package org.jboss.seam.security.external.saml.sp; import java.io.Reader; import java.io.Writer; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.enterprise.inject.Typed; import javax.inject.Inject; import javax.servlet.http.HttpServletResponse; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import org.jboss.seam.security.external.SamlMultiUserServiceProviderApi; import org.jboss.seam.security.external.dialogues.api.Dialogued; import org.jboss.seam.security.external.jaxb.samlv2.metadata.EntityDescriptorType; import org.jboss.seam.security.external.jaxb.samlv2.metadata.IDPSSODescriptorType; import org.jboss.seam.security.external.jaxb.samlv2.metadata.IndexedEndpointType; import org.jboss.seam.security.external.jaxb.samlv2.metadata.ObjectFactory; import org.jboss.seam.security.external.jaxb.samlv2.metadata.SPSSODescriptorType; import org.jboss.seam.security.external.saml.SamlConstants; import org.jboss.seam.security.external.saml.SamlEntityBean; import org.jboss.seam.security.external.saml.SamlExternalEntity; import org.jboss.seam.security.external.saml.SamlIdpOrSp; import org.jboss.seam.security.external.saml.SamlServiceType; import org.jboss.seam.security.external.saml.api.SamlServiceProviderConfigurationApi; import org.jboss.seam.security.external.saml.api.SamlSpSession; /** * @author Marcel Kolsteren */ @Typed(SamlSpBean.class) public class SamlSpBean extends SamlEntityBean implements SamlSpBeanApi, SamlMultiUserServiceProviderApi, SamlServiceProviderConfigurationApi { private List<SamlExternalIdentityProvider> identityProviders = new LinkedList<SamlExternalIdentityProvider>(); @Inject private SamlSpSingleSignOnService samlSpSingleSignOnService; @Inject private SamlSpSingleLogoutService samlSpSingleLogoutService; @Inject private SamlSpSessions samlSpSessions; private boolean authnRequestsSigned = false; private boolean wantAssertionsSigned = false; public SamlExternalIdentityProvider addExternalIdentityProvider(String entityId, IDPSSODescriptorType idpSsoDescriptor) { SamlExternalIdentityProvider samlIdentityProvider = new SamlExternalIdentityProvider(entityId, idpSsoDescriptor); identityProviders.add(samlIdentityProvider); return samlIdentityProvider; } public SamlExternalIdentityProvider addExternalSamlEntity(Reader reader) { EntityDescriptorType entityDescriptor = readEntityDescriptor(reader); String entityId = entityDescriptor.getEntityID(); IDPSSODescriptorType IDPSSODescriptor = (IDPSSODescriptorType) entityDescriptor.getRoleDescriptorOrIDPSSODescriptorOrSPSSODescriptor().get(0); return addExternalIdentityProvider(entityId, IDPSSODescriptor); } @Override public List<SamlExternalEntity> getExternalSamlEntities() { List<SamlExternalEntity> samlEntities = new LinkedList<SamlExternalEntity>(); for (SamlExternalIdentityProvider idp : identityProviders) { samlEntities.add(idp); } return samlEntities; } public List<SamlExternalIdentityProvider> getIdentityProviders() { return identityProviders; } public boolean isAuthnRequestsSigned() { return authnRequestsSigned; } public void setAuthnRequestsSigned(boolean authnRequestsSigned) { this.authnRequestsSigned = authnRequestsSigned; } public boolean isWantAssertionsSigned() { return wantAssertionsSigned; } public void setWantAssertionsSigned(boolean wantAssertionsSigned) { this.wantAssertionsSigned = wantAssertionsSigned; } public SamlExternalIdentityProvider getExternalSamlEntityByEntityId(String entityId) { for (SamlExternalEntity identityProvider : identityProviders) { SamlExternalIdentityProvider samlIdentityProvider = (SamlExternalIdentityProvider) identityProvider; if (samlIdentityProvider.getEntityId().equals(entityId)) { return samlIdentityProvider; } } return null; } public void writeMetaData(Writer writer) { try { ObjectFactory metaDataFactory = new ObjectFactory(); IndexedEndpointType acsRedirectEndpoint = metaDataFactory.createIndexedEndpointType(); acsRedirectEndpoint.setBinding(SamlConstants.HTTP_REDIRECT_BINDING); acsRedirectEndpoint.setLocation(getServiceURL(SamlServiceType.SAML_ASSERTION_CONSUMER_SERVICE)); IndexedEndpointType acsPostEndpoint = metaDataFactory.createIndexedEndpointType(); acsPostEndpoint.setBinding(SamlConstants.HTTP_POST_BINDING); acsPostEndpoint.setLocation(getServiceURL(SamlServiceType.SAML_ASSERTION_CONSUMER_SERVICE)); SPSSODescriptorType spSsoDescriptor = metaDataFactory.createSPSSODescriptorType(); spSsoDescriptor.getAssertionConsumerService().add(acsRedirectEndpoint); spSsoDescriptor.getAssertionConsumerService().add(acsPostEndpoint); addSloEndpointsToMetaData(spSsoDescriptor); spSsoDescriptor.setAuthnRequestsSigned(isAuthnRequestsSigned()); spSsoDescriptor.setWantAssertionsSigned(isWantAssertionsSigned()); spSsoDescriptor.getProtocolSupportEnumeration().add(SamlConstants.PROTOCOL_NSURI); addNameIDFormatsToMetaData(spSsoDescriptor); if (getSigningKey() != null) { addKeyDescriptorToMetaData(spSsoDescriptor); } EntityDescriptorType entityDescriptor = metaDataFactory.createEntityDescriptorType(); entityDescriptor.setEntityID(getEntityId()); entityDescriptor.getRoleDescriptorOrIDPSSODescriptorOrSPSSODescriptor().add(spSsoDescriptor); Marshaller marshaller = metaDataJaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal(metaDataFactory.createEntityDescriptor(entityDescriptor), writer); } catch (JAXBException e) { throw new RuntimeException(e); } } @Dialogued(join = true) public void login(String idpEntityId, HttpServletResponse response) { SamlExternalIdentityProvider idp = getExternalSamlEntityByEntityId(idpEntityId); if (idp == null) { throw new RuntimeException("Identity provider " + idpEntityId + " not found"); } samlSpSingleSignOnService.sendAuthenticationRequestToIDP(idp, response); } @Dialogued(join = true) public void localLogout(SamlSpSession session) { samlSpSessions.removeSession((SamlSpSessionImpl) session); } @Dialogued(join = true) public void globalLogout(SamlSpSession session, HttpServletResponse response) { localLogout(session); samlSpSingleLogoutService.sendSingleLogoutRequestToIDP((SamlSpSessionImpl) session, response); } public Set<SamlSpSession> getSessions() { Set<SamlSpSession> sessions = new HashSet<SamlSpSession>(); sessions.addAll(samlSpSessions.getSessions()); return sessions; } @Override public SamlIdpOrSp getIdpOrSp() { return SamlIdpOrSp.SP; } }