diff options
| author | Andreas Fitzek <andreas.fitzek@iaik.tugraz.at> | 2013-05-28 16:37:44 +0200 | 
|---|---|---|
| committer | Andreas Fitzek <andreas.fitzek@iaik.tugraz.at> | 2013-05-28 16:37:44 +0200 | 
| commit | 545bda2ed80c3ca45e2be1723a514b21c780a05a (patch) | |
| tree | 5eec399a4abb2d9dae82b9e1db865016d91ca96f | |
| parent | 0ead924cc31ad1fe499ac6d4139243283d94b704 (diff) | |
| download | moa-id-spss-545bda2ed80c3ca45e2be1723a514b21c780a05a.tar.gz moa-id-spss-545bda2ed80c3ca45e2be1723a514b21c780a05a.tar.bz2 moa-id-spss-545bda2ed80c3ca45e2be1723a514b21c780a05a.zip | |
Metadata generation for IDP
4 files changed, 377 insertions, 1 deletions
| diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java index 585655e7c..c993290e9 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java @@ -256,6 +256,7 @@ public class DispatcherServlet extends AuthServlet {  				AuthenticationManager.logout(req, resp);  			} catch (Throwable e) { +				e.printStackTrace();  				// Try handle module specific, if not possible rethrow  				if (!info.generateErrorMessage(e, req, resp, protocolRequest)) {  					throw e; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/MetadataAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/MetadataAction.java new file mode 100644 index 000000000..75fc6197f --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/MetadataAction.java @@ -0,0 +1,184 @@ +package at.gv.egovernment.moa.id.protocols.pvp2x; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.opensaml.Configuration; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.metadata.ArtifactResolutionService; +import org.opensaml.saml2.metadata.ContactPerson; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.IDPSSODescriptor; +import org.opensaml.saml2.metadata.KeyDescriptor; +import org.opensaml.saml2.metadata.SingleSignOnService; +import org.opensaml.xml.io.Marshaller; +import org.opensaml.xml.io.MarshallingException; +import org.opensaml.xml.security.SecurityException; +import org.opensaml.xml.security.credential.BasicKeyInfoGeneratorFactory.BasicKeyInfoGenerator; +import org.opensaml.xml.security.credential.BasicKeyInfoGeneratorFactory; +import org.opensaml.xml.security.credential.Credential; +import org.opensaml.xml.security.credential.UsageType; +import org.opensaml.xml.security.keyinfo.KeyInfoGenerator; +import org.opensaml.xml.signature.Signature; +import org.opensaml.xml.signature.SignatureException; +import org.opensaml.xml.signature.Signer; +import org.w3c.dom.Document; + +import at.gv.egovernment.moa.id.MOAIDException; +import at.gv.egovernment.moa.id.moduls.IAction; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; +import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialProvider; +import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException; +import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils; + +public class MetadataAction implements IAction { + +	public void processRequest(IRequest req, HttpServletRequest httpReq, +			HttpServletResponse httpResp) throws MOAIDException { +		try { + +			EntityDescriptor idpEntityDescriptor = SAML2Utils +					.createSAMLObject(EntityDescriptor.class); + +			idpEntityDescriptor.setEntityID("https://localhost:8443/moa-id-auth"); +			 +			List<ContactPerson> persons = PVPConfiguration.getInstance().getIDPContacts(); +			 +			idpEntityDescriptor.getContactPersons().addAll(persons); + +			idpEntityDescriptor.setOrganization(PVPConfiguration.getInstance().getIDPOrganisation()); +			 +			BasicKeyInfoGeneratorFactory keyInfoFactory = new BasicKeyInfoGeneratorFactory(); +			keyInfoFactory.setEmitPublicKeyValue(true); +			keyInfoFactory.setEmitEntityIDAsKeyName(true); +			KeyInfoGenerator keyInfoGenerator = keyInfoFactory.newInstance(); +			 +			Credential credential = CredentialProvider +					.getIDPSigningCredential(); +			 +			KeyDescriptor signKeyDescriptor = SAML2Utils +					.createSAMLObject(KeyDescriptor.class); +			signKeyDescriptor.setUse(UsageType.SIGNING); +			signKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(credential)); + +			Signature signature = CredentialProvider +					.getIDPSignature(credential); + +			idpEntityDescriptor.setSignature(signature); + +			IDPSSODescriptor idpSSODescriptor = SAML2Utils.createSAMLObject(IDPSSODescriptor.class); +			 +			idpSSODescriptor.setWantAuthnRequestsSigned(true); +			 +			SingleSignOnService postSingleSignOnService =  +					SAML2Utils.createSAMLObject(SingleSignOnService.class); +			 +			postSingleSignOnService.setLocation("https://enter.post.url"); +			postSingleSignOnService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); +			 +			idpSSODescriptor.getSingleSignOnServices().add(postSingleSignOnService); +			 +			SingleSignOnService redirectSingleSignOnService =  +					SAML2Utils.createSAMLObject(SingleSignOnService.class); +			 +			redirectSingleSignOnService.setLocation("https://enter.redirect.url"); +			redirectSingleSignOnService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); +			 +			ArtifactResolutionService artifactResolutionService = SAML2Utils.createSAMLObject( +					ArtifactResolutionService.class); +			 +			artifactResolutionService.setBinding(SAMLConstants.SAML2_SOAP11_BINDING_URI); +			artifactResolutionService.setLocation("https://enter.soap.url"); +			 +			idpSSODescriptor.getArtifactResolutionServices().add(artifactResolutionService); +			 +			idpSSODescriptor.getSingleSignOnServices().add(redirectSingleSignOnService); +			 +			idpSSODescriptor.getKeyDescriptors().add(signKeyDescriptor); +			 +			idpEntityDescriptor.getRoleDescriptors().add(idpSSODescriptor); +			 +			DocumentBuilder builder; +			DocumentBuilderFactory factory = DocumentBuilderFactory +					.newInstance(); + +			builder = factory.newDocumentBuilder(); +			Document document = builder.newDocument(); +			Marshaller out = Configuration.getMarshallerFactory() +					.getMarshaller(idpEntityDescriptor); +			out.marshall(idpEntityDescriptor, document); + +			Signer.signObject(signature); + +			Transformer transformer = TransformerFactory.newInstance() +					.newTransformer(); + +			StringWriter sw = new StringWriter(); +			StreamResult sr = new StreamResult(sw); +			DOMSource source = new DOMSource(document); +			transformer.transform(source, sr); +			sw.close(); + +			String metadataXML = sw.toString(); + +			System.out.println("METADATA: " + metadataXML); + +			httpResp.setContentType("text/xml"); +			httpResp.getOutputStream().write(metadataXML.getBytes()); + +			httpResp.getOutputStream().close(); + +		} catch (CredentialsNotAvailableException e) { +			e.printStackTrace(); +		} catch (SecurityException e) { +			// TODO Auto-generated catch block +			e.printStackTrace(); +		} catch (ParserConfigurationException e) { +			// TODO Auto-generated catch block +			e.printStackTrace(); +		} catch (MarshallingException e) { +			// TODO Auto-generated catch block +			e.printStackTrace(); +		} catch (SignatureException e) { +			// TODO Auto-generated catch block +			e.printStackTrace(); +		} catch (TransformerConfigurationException e) { +			// TODO Auto-generated catch block +			e.printStackTrace(); +		} catch (TransformerFactoryConfigurationError e) { +			// TODO Auto-generated catch block +			e.printStackTrace(); +		} catch (IOException e) { +			// TODO Auto-generated catch block +			e.printStackTrace(); +		} catch (TransformerException e) { +			// TODO Auto-generated catch block +			e.printStackTrace(); +		} +	} + +	public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, +			HttpServletResponse httpResp) { +		return false; +	} + +	public String getDefaultActionName() { +		return (PVP2XProtocol.METADATA); +	} + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java index 673b65243..4633f22d2 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java @@ -48,6 +48,7 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {  	public static final String REDIRECT = "Redirect";  	public static final String POST = "Post";  	public static final String SOAP = "Soap"; +	public static final String METADATA = "Metadata";  	private static List<ServletInfo> servletList = new ArrayList<ServletInfo>(); @@ -70,6 +71,7 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {  		actions.put(REDIRECT, new AuthenticationAction());  		actions.put(POST, new AuthenticationAction()); +		actions.put(METADATA, new MetadataAction());  		instance = new PVP2XProtocol();  	} @@ -118,6 +120,10 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {  	public IRequest preProcess(HttpServletRequest request,  			HttpServletResponse response, String action) throws MOAIDException { +		if(METADATA.equals(action)) { +			return new PVPTargetConfiguration(); +		} +		  		IDecoder decoder = findDecoder(action);  		if (decoder == null) {  			return null; @@ -213,6 +219,10 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {  		if(request.getParameter("SAMLRequest") != null) {  			return getAction(REDIRECT);  		} +		 +		if(METADATA.equals(request.getParameter("action"))) { +			return getAction(METADATA); +		}  		return null;  	} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/PVPConfiguration.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/PVPConfiguration.java index 5ec852d46..79126416f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/PVPConfiguration.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/PVPConfiguration.java @@ -2,9 +2,40 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.config;  import java.io.File;  import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List;  import java.util.Properties; +import java.util.Set; + +import javax.xml.namespace.QName; + +import org.opensaml.saml2.common.Extensions; +import org.opensaml.saml2.metadata.Company; +import org.opensaml.saml2.metadata.ContactPerson; +import org.opensaml.saml2.metadata.ContactPersonTypeEnumeration; +import org.opensaml.saml2.metadata.EmailAddress; +import org.opensaml.saml2.metadata.GivenName; +import org.opensaml.saml2.metadata.LocalizedString; +import org.opensaml.saml2.metadata.Organization; +import org.opensaml.saml2.metadata.OrganizationDisplayName; +import org.opensaml.saml2.metadata.OrganizationName; +import org.opensaml.saml2.metadata.OrganizationURL; +import org.opensaml.saml2.metadata.SurName; +import org.opensaml.saml2.metadata.TelephoneNumber; +import org.opensaml.xml.Namespace; +import org.opensaml.xml.NamespaceManager; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.schema.XSBooleanValue; +import org.opensaml.xml.util.AttributeMap; +import org.opensaml.xml.util.IDIndex; +import org.opensaml.xml.validation.ValidationException; +import org.opensaml.xml.validation.Validator; +import org.w3c.dom.Element;  import at.gv.egovernment.moa.id.config.ConfigurationProvider; +import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;  import at.gv.egovernment.moa.logging.Logger;  public class PVPConfiguration { @@ -24,13 +55,29 @@ public class PVPConfiguration {  	public static final String IDP_KEY_PASS = "idp.ks.keypassword";  	public static final String METADATA_FILE = "md.file"; +	public static final String IDP_ENTITY = "idp.entityid"; +	public static final String IDP_ORG_NAME = "idp.org.name"; +	public static final String IDP_ORG_DISPNAME = "idp.org.dispname"; +	public static final String IDP_ORG_URL = "idp.org.url"; +	 +	public static final String IDP_CONTACT_PREFIX = "idp.contact"; +	public static final String IDP_CONTACT_LIST = "idp.contact_list"; +	 +	public static final String IDP_CONTACT_SURNAME = "surname"; +	public static final String IDP_CONTACT_GIVENNAME = "givenname"; +	public static final String IDP_CONTACT_MAIL = "mail"; +	public static final String IDP_CONTACT_TYPE = "type"; +	public static final String IDP_CONTACT_COMPANY = "company"; +	public static final String IDP_CONTACT_PHONE = "phone"; +	 +	  	Properties props = new Properties();  	private PVPConfiguration() {  		try {  			String fileName = System.getProperty(ConfigurationProvider.CONFIG_PROPERTY_NAME);  			String pathName = (new File(fileName)).getParent(); -			String configFile = pathName + File.pathSeparator + PVP_CONFIG_FILE; +			String configFile = pathName + "/" + PVP_CONFIG_FILE;  			Logger.info("PVP Config file " + configFile);  			FileInputStream is = new FileInputStream(configFile); @@ -60,4 +107,138 @@ public class PVPConfiguration {  	public String getMetadataFile() {  		return props.getProperty(METADATA_FILE);  	} +	 +	public List<ContactPerson> getIDPContacts() { +		List<ContactPerson> list = new ArrayList<ContactPerson>(); +		 +		String contactList = props.getProperty(IDP_CONTACT_LIST); +		 +		if(contactList != null) { +			 +			String[] contact_keys = contactList.split(","); +			 +			for(int i = 0; i < contact_keys.length; i++) { +			 +				String key = contact_keys[i]; +				 +				ContactPerson person = SAML2Utils.createSAMLObject(ContactPerson.class);  +				 +				String type = props.getProperty(IDP_CONTACT_PREFIX +  +						"." + key + "." + IDP_CONTACT_TYPE); +				 +				if(type == null) { +					Logger.error("IDP Contact with key " + key + " has no type defined!"); +					break; +				} +				 +				ContactPersonTypeEnumeration enumType = null; +				 +				if(type.equals(ContactPersonTypeEnumeration.ADMINISTRATIVE.toString())) { +					enumType = ContactPersonTypeEnumeration.ADMINISTRATIVE; +				} else if(type.equals(ContactPersonTypeEnumeration.BILLING.toString())){ +					enumType = ContactPersonTypeEnumeration.BILLING; +				} else if(type.equals(ContactPersonTypeEnumeration.OTHER.toString())){ +					enumType = ContactPersonTypeEnumeration.OTHER; +				}else if(type.equals(ContactPersonTypeEnumeration.SUPPORT.toString())){ +					enumType = ContactPersonTypeEnumeration.SUPPORT; +				}else if(type.equals(ContactPersonTypeEnumeration.TECHNICAL.toString())){ +					enumType = ContactPersonTypeEnumeration.TECHNICAL; +				} +				 +				if(enumType == null) { +					Logger.error("IDP Contact with key " + key + " has invalid type defined: " +  +							type); +					break; +				} +				 +				person.setType(enumType); +				 +				String givenName = props.getProperty(IDP_CONTACT_PREFIX +  +						"." + key + "." + IDP_CONTACT_GIVENNAME); +				 +				if(givenName != null) { +					GivenName name = SAML2Utils.createSAMLObject(GivenName.class); +					name.setName(givenName); +					person.setGivenName(name); +				} +			 +				String company = props.getProperty(IDP_CONTACT_PREFIX +  +						"." + key + "." + IDP_CONTACT_COMPANY); +				 +				if(company != null) { +					Company comp = SAML2Utils.createSAMLObject(Company.class); +					comp.setName(company); +					person.setCompany(comp); +				} +				 +				String surname = props.getProperty(IDP_CONTACT_PREFIX +  +						"." + key + "." + IDP_CONTACT_SURNAME); +				  +				if(surname != null) { +					SurName name = SAML2Utils.createSAMLObject(SurName.class); +					name.setName(surname); +					person.setSurName(name); +				} +				 +				Set<Object> keySet = props.keySet(); +				Iterator<Object> keyIt = keySet.iterator(); +				 +				while(keyIt.hasNext()) { +				 +					String currentKey = keyIt.next().toString(); +					 +					if(currentKey.startsWith(IDP_CONTACT_PREFIX +  +						"." + key + "." + IDP_CONTACT_PHONE)) { +						String phone = props.getProperty(currentKey); +						 +						if(phone != null) { +							TelephoneNumber telePhone = SAML2Utils.createSAMLObject(TelephoneNumber.class); +							telePhone.setNumber(phone); +							person.getTelephoneNumbers().add(telePhone); +						} +					} else if(currentKey.startsWith(IDP_CONTACT_PREFIX +  +							"." + key + "." + IDP_CONTACT_MAIL)) { +						String mail = props.getProperty(currentKey); +						 +						if(mail != null) { +							EmailAddress mailAddress = SAML2Utils.createSAMLObject(EmailAddress.class); +							mailAddress.setAddress(mail); +							person.getEmailAddresses().add(mailAddress); +						} +					} +				} +				list.add(person); +			}	 +		} +		return list; +	} +	 +	public Organization getIDPOrganisation() { +		Organization org = SAML2Utils.createSAMLObject(Organization.class); + +		String org_name = props.getProperty(IDP_ORG_NAME); +		String org_dispname = props.getProperty(IDP_ORG_DISPNAME); +		String org_url = props.getProperty(IDP_ORG_URL); + +		if(org_name == null || org_dispname == null || org_url == null) { +			return null; +		} +		 +		OrganizationDisplayName dispName = SAML2Utils.createSAMLObject( +				OrganizationDisplayName.class); +		dispName.setName(new LocalizedString(org_dispname, "de")); +		org.getDisplayNames().add(dispName); +		 +		OrganizationName name = SAML2Utils.createSAMLObject( +				OrganizationName.class); +		name.setName(new LocalizedString(org_name, "de")); +		org.getOrganizationNames().add(name); +		 +		OrganizationURL url = SAML2Utils.createSAMLObject( +				OrganizationURL.class); +		url.setURL(new LocalizedString(org_url, "de")); +		org.getURLs().add(url); + +		return org; +	}  } | 
