/** * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2016 * * 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 it.infn.cnaf.voms.test.saml_client; import it.infn.cnaf.voms.saml.axis_serializers.DeserializerFactory; import it.infn.cnaf.voms.saml.axis_serializers.SerializerFactory; import it.infn.cnaf.voms.saml.axis_skeletons.AttributeAuthorityPortType; import it.infn.cnaf.voms.saml.axis_skeletons.AttributeAuthorityServiceLocator; import it.infn.cnaf.voms.saml.emi.AttributeWizard; import java.net.MalformedURLException; import java.net.URL; import java.rmi.RemoteException; import java.security.Security; import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.xml.rpc.ServiceException; import javax.xml.rpc.encoding.TypeMapping; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.glite.security.voms.admin.util.PathNamingScheme; import org.joda.time.DateTime; import org.opensaml.Configuration; import org.opensaml.DefaultBootstrap; import org.opensaml.common.SAMLVersion; import org.opensaml.saml2.core.Attribute; import org.opensaml.saml2.core.AttributeQuery; import org.opensaml.saml2.core.Issuer; import org.opensaml.saml2.core.NameID; import org.opensaml.saml2.core.Response; import org.opensaml.saml2.core.Subject; import org.opensaml.saml2.core.impl.AttributeQueryBuilder; import org.opensaml.saml2.core.impl.IssuerBuilder; import org.opensaml.saml2.core.impl.NameIDBuilder; import org.opensaml.saml2.core.impl.SubjectBuilder; import org.opensaml.xml.ConfigurationException; import org.opensaml.xml.XMLObject; import org.opensaml.xml.XMLObjectBuilderFactory; import org.opensaml.xml.io.Marshaller; import org.opensaml.xml.io.MarshallerFactory; import org.opensaml.xml.io.MarshallingException; import org.w3c.dom.Element; public class VOMSSAMLClient { static final String MY_DN = "CN=Andrea Ceccanti,L=CNAF,OU=Personal Certificate,O=INFN,C=IT"; static final String MY_OTHER_DN = "emailAddress=andrea.ceccanti@cnaf.infn.it,CN=cecco,OU=Voms-Admin testing,O=Voms-Admin,ST=Test,C=IT"; static { Security.addProvider(new BouncyCastleProvider()); } public static void main(String[] args) throws MalformedURLException, ServiceException, RemoteException { new VOMSSAMLClient(args); } public static Element marshall(XMLObject xmlObject) throws MarshallingException { Element element; MarshallerFactory marshallerFactory = Configuration.getMarshallerFactory(); Marshaller marshaller = marshallerFactory.getMarshaller(xmlObject); element = marshaller.marshall(xmlObject); return element; } public void usage() { System.out.format("usage: %s <host> <vo> <dn>", this.getClass().getName()); } public void testEmptyAttributeQuery() { } public VOMSSAMLClient(String[] args) throws MalformedURLException, ServiceException, RemoteException { if (args.length < 3) { usage(); System.exit(-1); } String host = args[0]; String vo = args[1]; String dn = args[2]; initializeOpenSAML(); List<String> fqans = new ArrayList<String>(); if (args.length > 2) { for (int i = 2; i < args.length; i++) fqans.add(args[i]); } AttributeQuery query = buildAttributeQuery(MY_DN, vo, fqans); System.out.println("Query:"); print(query); AttributeAuthorityPortType aa = getVOMSSamlService(host, vo); Response response = aa.attributeQuery(query); System.out.println("Response:"); print(response); } AttributeQuery buildAttributeQuery(String userDn, String voName, List<String> fqans) { XMLObjectBuilderFactory bf = Configuration.getBuilderFactory(); AttributeQueryBuilder qb = (AttributeQueryBuilder) bf .getBuilder(AttributeQuery.DEFAULT_ELEMENT_NAME); AttributeQuery query = qb.buildObject(); query.setID(UUID.randomUUID().toString()); query.setVersion(SAMLVersion.VERSION_20); query.setIssueInstant(new DateTime()); IssuerBuilder issuerBuilder = (IssuerBuilder) bf .getBuilder(Issuer.DEFAULT_ELEMENT_NAME); Issuer issuer = issuerBuilder.buildObject(); issuer.setValue(userDn); issuer.setFormat(NameID.X509_SUBJECT); query.setIssuer(issuer); SubjectBuilder subjectBuilder = (SubjectBuilder) bf .getBuilder(Subject.DEFAULT_ELEMENT_NAME); Subject subject = subjectBuilder.buildObject(); NameIDBuilder nameIdBuilder = (NameIDBuilder) bf .getBuilder(NameID.DEFAULT_ELEMENT_NAME); NameID requester = nameIdBuilder.buildObject(); requester.setFormat(NameID.X509_SUBJECT); requester.setValue(userDn); subject.setNameID(requester); query.setSubject(subject); if (!fqans.isEmpty()) { List<Attribute> requestedAttrs = new ArrayList<Attribute>(); requestedAttrs.add(AttributeWizard.createVOAttribute(voName)); List<String> groups = new ArrayList<String>(); List<String> roles = new ArrayList<String>(); for (String f : fqans) { if (PathNamingScheme.isGroupFQAN(f)) groups.add(f); else roles.add(f); } requestedAttrs.add(AttributeWizard .createPrimaryGroupAttributeFromString(null)); requestedAttrs.add(AttributeWizard .createGroupAttributeFromStrings(groups)); if (!roles.isEmpty()) { requestedAttrs.add(AttributeWizard .createRoleAttributeFromStrings(roles)); requestedAttrs.add(AttributeWizard .createPrimaryRoleAttributeFromString(null)); } query.getAttributes().addAll(requestedAttrs); } return query; } AttributeAuthorityPortType getVOMSSamlService(String host, String vo) { String url = String.format("https://%s:8443/voms/%s/services/VOMSSaml", host, vo); try { AttributeAuthorityServiceLocator loc = new AttributeAuthorityServiceLocator(); TypeMapping typeMapping = loc.getTypeMappingRegistry() .getDefaultTypeMapping(); typeMapping.register(AttributeQuery.class, AttributeQuery.TYPE_NAME, new SerializerFactory(), new DeserializerFactory()); typeMapping.register(Response.class, Response.TYPE_NAME, new SerializerFactory(), new DeserializerFactory()); AttributeAuthorityPortType aa = loc .getAttributeAuthorityPortType(new URL(url)); return aa; } catch (Throwable t) { printExceptionAndExit(t); } return null; } void initializeOpenSAML() { try { DefaultBootstrap.bootstrap(); } catch (ConfigurationException e) { printExceptionAndExit(e); } } void parseCredentials(String certFile, String keyFile) { } public void print(XMLObject xmlObject) { try { Element element = marshall(xmlObject); Transformer tr = TransformerFactory.newInstance().newTransformer(); tr.setOutputProperty(OutputKeys.INDENT, "yes"); tr.setOutputProperty(OutputKeys.METHOD, "xml"); tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(4)); tr.transform(new DOMSource(element), new StreamResult(System.out)); } catch (Throwable t) { printExceptionAndExit(t); } } public void printExceptionAndExit(Throwable t) { t.printStackTrace(); System.exit(1); } }