diff options
22 files changed, 381 insertions, 123 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 c993290e9..5fa0dfcc3 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 @@ -33,64 +33,6 @@ public class DispatcherServlet extends AuthServlet {  	public static final String PARAM_TARGET_MODULE = "mod";  	public static final String PARAM_TARGET_ACTION = "action"; -	/* -	 * public static final String PARAM_DISPATCHER_TARGETS = -	 * "DispatcherTargets"; public static final String PARAM_DISPATCHER_TYPE = -	 * "DispatcherType"; public static final String PARAM_DISPATCHER_TYPE_UNAUTH -	 * = "UNAUTH"; public static final String PARAM_DISPATCHER_TYPE_AUTH = -	 * "AUTH"; public static String SYSTEM_NEWLINE = -	 * System.getProperty("line.separator"); -	 */ -	/* -	 * private HashMap<String, HashMap<String, HttpServlet>> endpointMap = new -	 * HashMap<String, HashMap<String, HttpServlet>>(); -	 *  -	 * private void registerModule(IModulInfo modulInfo) { -	 *  -	 * HashMap<String, HttpServlet> tempMap = new HashMap<String, -	 * HttpServlet>(); -	 *  -	 * try { -	 *  -	 * String path = modulInfo.getPath(); -	 *  -	 * if (path == null) { throw new Exception(String.format( -	 * "%s does not return a valid target path!", new Object[] { -	 * modulInfo.getClass().getName() })); } -	 *  -	 * Logger.debug("Registering: " + modulInfo.getName() + " under " + path); -	 *  -	 * List<ServletInfo> servletInfos = modulInfo.getServlets(); -	 *  -	 * Iterator<ServletInfo> servletInfoIterator = servletInfos.iterator(); -	 *  -	 * while (servletInfoIterator.hasNext()) { -	 *  -	 * ServletInfo servletInfo = servletInfoIterator.next(); -	 *  -	 * if (servletInfo.getType() == ServletType.UNAUTH) { HttpServlet servlet = -	 * servletInfo.getServletInstance(); String target = -	 * servletInfo.getTarget(); -	 *  -	 * if (target == null) { throw new Exception( String.format( -	 * "%s does not return a valid target identifier!", new Object[] { -	 * servlet.getClass() .getName() })); } -	 *  -	 * if (tempMap.containsKey(target)) { throw new Exception(String.format( -	 * "%s tried to overwrite %s/%s", new Object[] { -	 * servlet.getClass().getName(), path, target })); } -	 *  -	 * tempMap.put(target, servlet); Logger.info("Registered Servlet class: " + -	 * servlet.getClass().getName() + " OK"); } -	 *  -	 * } -	 *  -	 * // when there was no error we register all servlets into the real // -	 * endpoint map ... if (!tempMap.isEmpty()) { endpointMap.put(path, -	 * tempMap); } } catch (Throwable e) { -	 * Logger.error("Registering Modul class: " + modulInfo.getClass().getName() -	 * + " FAILED!!", e); } } -	 */  	@Override  	public void init(ServletConfig config) throws ServletException {  		try { @@ -105,15 +47,6 @@ public class DispatcherServlet extends AuthServlet {  			throw new ServletException(ex);  		}  		Logger.info("Dispatcher Servlet initialization"); - -		/* -		 * List<IModulInfo> modules = ModulStorage.getAllModules(); -		 * Iterator<IModulInfo> it = modules.iterator(); while (it.hasNext()) { -		 * IModulInfo info = it.next(); String targetClass = -		 * info.getClass().getName(); try { registerModule(info); } catch -		 * (Throwable e) { Logger.error("Registering Class " + targetClass + -		 * " FAILED!!", e); } } -		 */  	}  	protected void processRequest(HttpServletRequest req, diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/ExternalPVPSessionStore.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/ExternalPVPSessionStore.java new file mode 100644 index 000000000..1e3c6145f --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/ExternalPVPSessionStore.java @@ -0,0 +1,28 @@ +package at.gv.egovernment.moa.id.protocols.pvp2x; + +import java.util.HashMap; +import java.util.Map; + +import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.xml.io.MarshallingException; + +public class ExternalPVPSessionStore { +	 +	private Map<String, SPSSODescriptor> externalSessions = new HashMap<String, SPSSODescriptor>(); +	 +	public boolean contains(String sessionID) { +		return externalSessions.containsKey(sessionID); +	} + +	public void put(String sessionID, SPSSODescriptor sso) throws MarshallingException { +		externalSessions.put(sessionID, sso); +	} + +	public SPSSODescriptor get(String sessionID) { +		return externalSessions.get(sessionID); +	} + +	public void remove(String sessionID) { +		externalSessions.remove(sessionID); +	} +} 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 index d9129165e..85d5c2a46 100644 --- 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 @@ -17,13 +17,17 @@ import javax.xml.transform.TransformerFactoryConfigurationError;  import javax.xml.transform.dom.DOMSource;  import javax.xml.transform.stream.StreamResult; +import org.joda.time.DateTime;  import org.opensaml.Configuration;  import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.core.NameIDType;  import org.opensaml.saml2.metadata.ArtifactResolutionService;  import org.opensaml.saml2.metadata.ContactPerson; +import org.opensaml.saml2.metadata.EntitiesDescriptor;  import org.opensaml.saml2.metadata.EntityDescriptor;  import org.opensaml.saml2.metadata.IDPSSODescriptor;  import org.opensaml.saml2.metadata.KeyDescriptor; +import org.opensaml.saml2.metadata.NameIDFormat;  import org.opensaml.saml2.metadata.SingleSignOnService;  import org.opensaml.xml.io.Marshaller;  import org.opensaml.xml.io.MarshallingException; @@ -52,9 +56,20 @@ public class MetadataAction implements IAction {  			HttpServletResponse httpResp) throws MOAIDException {  		try { +			EntitiesDescriptor idpEntitiesDescriptor =  +					SAML2Utils.createSAMLObject(EntitiesDescriptor.class); +			 +			idpEntitiesDescriptor.setName(PVPConfiguration.getInstance().getIDPIssuerName()); + +			idpEntitiesDescriptor.setID(SAML2Utils.getSecureIdentifier()); +			 +			idpEntitiesDescriptor.setValidUntil(new DateTime().plusWeeks(4)); +			  			EntityDescriptor idpEntityDescriptor = SAML2Utils  					.createSAMLObject(EntityDescriptor.class); +			idpEntitiesDescriptor.getEntityDescriptors().add(idpEntityDescriptor); +			  			idpEntityDescriptor  					.setEntityID("https://localhost:8443/moa-id-auth"); @@ -83,13 +98,15 @@ public class MetadataAction implements IAction {  			Signature signature = CredentialProvider  					.getIDPSignature(credential); -			idpEntityDescriptor.setSignature(signature); +			idpEntitiesDescriptor.setSignature(signature);  			IDPSSODescriptor idpSSODescriptor = SAML2Utils  					.createSAMLObject(IDPSSODescriptor.class); -			idpSSODescriptor.setWantAuthnRequestsSigned(true); - +			idpSSODescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS); +			 +			idpSSODescriptor.setWantAuthnRequestsSigned(true);			 +			  			if (PVPConfiguration.getInstance().getIDPSSOPostService() != null) {  				SingleSignOnService postSingleSignOnService = SAML2Utils  						.createSAMLObject(SingleSignOnService.class); @@ -125,6 +142,8 @@ public class MetadataAction implements IAction {  				artifactResolutionService.setLocation(PVPConfiguration  						.getInstance().getIDPResolveSOAPService()); +				artifactResolutionService.setIndex(0); +				  				idpSSODescriptor.getArtifactResolutionServices().add(  						artifactResolutionService);  			} @@ -133,6 +152,21 @@ public class MetadataAction implements IAction {  			idpSSODescriptor.getAttributes().addAll(PVPAttributeBuilder.buildSupportedEmptyAttributes()); +			NameIDFormat persistenNameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); +			persistenNameIDFormat.setFormat(NameIDType.PERSISTENT); +			 +			idpSSODescriptor.getNameIDFormats().add(persistenNameIDFormat); +			 +			NameIDFormat transientNameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); +			transientNameIDFormat.setFormat(NameIDType.TRANSIENT); +			 +			idpSSODescriptor.getNameIDFormats().add(transientNameIDFormat); +			 +			NameIDFormat unspecifiedNameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); +			unspecifiedNameIDFormat.setFormat(NameIDType.UNSPECIFIED); +			 +			idpSSODescriptor.getNameIDFormats().add(unspecifiedNameIDFormat); +			  			idpEntityDescriptor.getRoleDescriptors().add(idpSSODescriptor);  			DocumentBuilder builder; @@ -142,8 +176,8 @@ public class MetadataAction implements IAction {  			builder = factory.newDocumentBuilder();  			Document document = builder.newDocument();  			Marshaller out = Configuration.getMarshallerFactory() -					.getMarshaller(idpEntityDescriptor); -			out.marshall(idpEntityDescriptor, document); +					.getMarshaller(idpEntitiesDescriptor); +			out.marshall(idpEntitiesDescriptor, document);  			Signer.signObject(signature); 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 33c8af197..d2a3764cd 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 @@ -37,6 +37,7 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.binding.MOARequest;  import at.gv.egovernment.moa.id.protocols.pvp2x.binding.PostBinding;  import at.gv.egovernment.moa.id.protocols.pvp2x.binding.RedirectBinding;  import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.PVP2Exception;  import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;  import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerificationEngine;  import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory; @@ -195,13 +196,22 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {  		if(e instanceof NoPassivAuthenticationException) {  			statusCode.setValue(StatusCode.NO_PASSIVE_URI);  			statusMessage.setMessage(e.getLocalizedMessage());	 +		} else if(e instanceof PVP2Exception) { +			PVP2Exception ex = (PVP2Exception) e; +			statusCode.setValue(ex.getStatusCodeValue()); +			String statusMessageValue = ex.getStatusMessageValue(); +			if(statusMessageValue != null) { +				statusMessage.setMessage(statusMessageValue); +			}  		} else {  			statusCode.setValue(StatusCode.RESPONDER_URI);  			statusMessage.setMessage(e.getLocalizedMessage());  		}  		status.setStatusCode(statusCode); -		status.setStatusMessage(statusMessage); +		if(statusMessage.getMessage() != null) { +			status.setStatusMessage(statusMessage); +		}  		samlResponse.setStatus(status);  		IEncoder encoder = new RedirectBinding(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java index b818a2d8a..5875a37c7 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java @@ -1,6 +1,12 @@  package at.gv.egovernment.moa.id.protocols.pvp2x;  public interface PVPConstants { +	 +	public static final String STORK_QAA_1_1 = "http://www.ref.gv.at/ns/names/agiz/stork/qaa/1"; +	public static final String STORK_QAA_1_2 = "http://www.ref.gv.at/ns/names/agiz/stork/qaa/1-2"; +	public static final String STORK_QAA_1_3 = "http://www.ref.gv.at/ns/names/agiz/stork/qaa/1-3"; +	public static final String STORK_QAA_1_4 = "http://www.ref.gv.at/ns/names/agiz/stork/qaa/1-4"; +	  	public static final String URN_OID_PREFIX = "urn:oid:";  	public static final String PVP_VERSION_OID = "1.2.40.0.10.2.1.1.261.10"; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SAMLRequestNotSignedException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SAMLRequestNotSignedException.java deleted file mode 100644 index 40f5685ad..000000000 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SAMLRequestNotSignedException.java +++ /dev/null @@ -1,17 +0,0 @@ -package at.gv.egovernment.moa.id.protocols.pvp2x; - -import at.gv.egovernment.moa.id.MOAIDException; - -public class SAMLRequestNotSignedException extends MOAIDException { - -	public SAMLRequestNotSignedException(String messageId, Object[] parameters) { -		super(messageId, parameters); -		// TODO Auto-generated constructor stub -	} - -	/** -	 *  -	 */ -	private static final long serialVersionUID = 1L; - -} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SAMLRequestNotSupported.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SAMLRequestNotSupported.java deleted file mode 100644 index 16b388a09..000000000 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SAMLRequestNotSupported.java +++ /dev/null @@ -1,16 +0,0 @@ -package at.gv.egovernment.moa.id.protocols.pvp2x; - -import at.gv.egovernment.moa.id.MOAIDException; - -public class SAMLRequestNotSupported extends MOAIDException { - -	public SAMLRequestNotSupported(String messageId, Object[] parameters) { -		super(messageId, parameters); -	} - -	/** -	 *  -	 */ -	private static final long serialVersionUID = 1244883178458802767L; - -} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/BaseAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/BaseAttributeBuilder.java index d62cf72b1..d3c79c939 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/BaseAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/BaseAttributeBuilder.java @@ -35,6 +35,7 @@ public abstract class BaseAttributeBuilder implements PVPConstants, IAttributeBu  				SAML2Utils.createSAMLObject(Attribute.class);  		attribute.setFriendlyName(friendlyName);  		attribute.setName(name); +		attribute.setNameFormat(Attribute.URI_REFERENCE);  		attribute.getAttributeValues().add(buildAttributeStringValue(value));  		return attribute;  	} @@ -45,6 +46,7 @@ public abstract class BaseAttributeBuilder implements PVPConstants, IAttributeBu  				SAML2Utils.createSAMLObject(Attribute.class);  		attribute.setFriendlyName(friendlyName);  		attribute.setName(name); +		attribute.setNameFormat(Attribute.URI_REFERENCE);  		attribute.getAttributeValues().add(buildAttributeIntegerValue(value));  		return attribute;  	} @@ -54,6 +56,7 @@ public abstract class BaseAttributeBuilder implements PVPConstants, IAttributeBu  				SAML2Utils.createSAMLObject(Attribute.class);  		attribute.setFriendlyName(friendlyName);  		attribute.setName(name); +		attribute.setNameFormat(Attribute.URI_REFERENCE);  		return attribute;  	}  } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDCitizenQAALevelAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDCitizenQAALevelAttributeBuilder.java index 5524ed44d..d9c66e6f0 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDCitizenQAALevelAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDCitizenQAALevelAttributeBuilder.java @@ -12,7 +12,7 @@ public class EIDCitizenQAALevelAttributeBuilder extends BaseAttributeBuilder {  	public Attribute build(AuthenticationSession authSession) {  		return buildIntegerAttribute(EID_CITIZEN_QAA_LEVEL_FRIENDLY_NAME,  -				EID_CITIZEN_QAA_LEVEL_NAME, 2); +				EID_CITIZEN_QAA_LEVEL_NAME, 4);  	} 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 d38c900bc..5a054b142 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 @@ -68,6 +68,7 @@ public class PVPConfiguration {  	public static final String IDP_REDIRECT_SSO_SERVICE = "idp.sso.redirect";  	public static final String IDP_SOAP_RESOLVE_SERVICE = "idp.resolve.soap"; +	  	public static final String IDP_TRUST_STORE = "idp.truststore";  	public static final String SP_TARGET_PREFIX = "sp.target."; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/InvalidAssertionConsumerServiceException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/InvalidAssertionConsumerServiceException.java new file mode 100644 index 000000000..d8dd3729a --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/InvalidAssertionConsumerServiceException.java @@ -0,0 +1,16 @@ +package at.gv.egovernment.moa.id.protocols.pvp2x.exceptions; + +public class InvalidAssertionConsumerServiceException extends PVP2Exception { + +	public InvalidAssertionConsumerServiceException(String messageId, +			Object[] parameters) { +		super(messageId, parameters); +		// TODO Auto-generated constructor stub +	} + +	/** +	 *  +	 */ +	private static final long serialVersionUID = 7861790149343943091L; + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/NoAuthContextException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/NoAuthContextException.java new file mode 100644 index 000000000..0d464ccfa --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/NoAuthContextException.java @@ -0,0 +1,14 @@ +package at.gv.egovernment.moa.id.protocols.pvp2x.exceptions; + +public class NoAuthContextException extends PVP2Exception { + +	/** +	 *  +	 */ +	private static final long serialVersionUID = 7040652043174500992L; + +	public NoAuthContextException(String messageId, Object[] parameters) { +		super(messageId, parameters); +	} + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/PVP2Exception.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/PVP2Exception.java new file mode 100644 index 000000000..1e4cf15b8 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/PVP2Exception.java @@ -0,0 +1,37 @@ +package at.gv.egovernment.moa.id.protocols.pvp2x.exceptions; + +import org.opensaml.saml2.core.StatusCode; + +import at.gv.egovernment.moa.id.MOAIDException; + +public abstract class PVP2Exception extends MOAIDException { + +	protected String statusCodeValue = StatusCode.RESPONDER_URI; +	protected String statusMessageValue = null; +	 +	public PVP2Exception(String messageId, Object[] parameters, +			Throwable wrapped) { +		super(messageId, parameters, wrapped); +	} + +	public PVP2Exception(String messageId, Object[] parameters) { +		super(messageId, parameters); +	} +	 +	 +	public String getStatusCodeValue() { +		return (this.statusCodeValue); +	} +	 +	public String getStatusMessageValue() { +		return (this.statusMessageValue); +	} +	 +	/** +	 *  +	 */ +	private static final long serialVersionUID = 7669537952484421069L; + +	 +	 +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/ResponderErrorException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/ResponderErrorException.java new file mode 100644 index 000000000..a24320cbc --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/ResponderErrorException.java @@ -0,0 +1,22 @@ +package at.gv.egovernment.moa.id.protocols.pvp2x.exceptions; + +import org.opensaml.saml2.core.StatusCode; + +public class ResponderErrorException extends PVP2Exception { + +	/** +	 *  +	 */ +	private static final long serialVersionUID = -425416760138285446L; + +	public ResponderErrorException(String messageId, Object[] parameters, +			Throwable wrapped) { +		super(messageId, parameters, wrapped); +		this.statusCodeValue = StatusCode.RESPONDER_URI; +	} +	 +	public ResponderErrorException(String messageId, Object[] parameters) { +		super(messageId, parameters); +		this.statusCodeValue = StatusCode.RESPONDER_URI; +	} +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/SAMLRequestNotSignedException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/SAMLRequestNotSignedException.java new file mode 100644 index 000000000..871c6f4bd --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/SAMLRequestNotSignedException.java @@ -0,0 +1,17 @@ +package at.gv.egovernment.moa.id.protocols.pvp2x.exceptions; + +import org.opensaml.saml2.core.StatusCode; + +public class SAMLRequestNotSignedException extends PVP2Exception { + +	public SAMLRequestNotSignedException(String messageId, Object[] parameters) { +		super(messageId, parameters); +		this.statusCodeValue = StatusCode.REQUESTER_URI; +	} + +	/** +	 *  +	 */ +	private static final long serialVersionUID = 1L; + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/SAMLRequestNotSupported.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/SAMLRequestNotSupported.java new file mode 100644 index 000000000..99940335b --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/SAMLRequestNotSupported.java @@ -0,0 +1,18 @@ +package at.gv.egovernment.moa.id.protocols.pvp2x.exceptions; + +import org.opensaml.saml2.core.StatusCode; + + +public class SAMLRequestNotSupported extends PVP2Exception { + +	public SAMLRequestNotSupported(String messageId, Object[] parameters) { +		super(messageId, parameters); +		this.statusCodeValue = StatusCode.REQUEST_UNSUPPORTED_URI; +	} + +	/** +	 *  +	 */ +	private static final long serialVersionUID = 1244883178458802767L; + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/UnprovideableAttributeException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/UnprovideableAttributeException.java new file mode 100644 index 000000000..6aeed47d7 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/UnprovideableAttributeException.java @@ -0,0 +1,15 @@ +package at.gv.egovernment.moa.id.protocols.pvp2x.exceptions; + +import org.opensaml.saml2.core.StatusCode; + +public class UnprovideableAttributeException extends PVP2Exception { +	/** +	 *  +	 */ +	private static final long serialVersionUID = 3972197758163647157L; + +	public UnprovideableAttributeException(String attributeName) { +		super(attributeName, null); +		this.statusCodeValue = StatusCode.UNKNOWN_ATTR_PROFILE_URI; +	} +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java index 964c19208..9e795c51c 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java @@ -11,14 +11,23 @@ import org.opensaml.saml2.core.ArtifactResponse;  import org.opensaml.saml2.core.Assertion;  import org.opensaml.saml2.core.Attribute;  import org.opensaml.saml2.core.AttributeStatement; +import org.opensaml.saml2.core.Audience; +import org.opensaml.saml2.core.AudienceRestriction;  import org.opensaml.saml2.core.AuthnContext;  import org.opensaml.saml2.core.AuthnContextClassRef;  import org.opensaml.saml2.core.AuthnRequest;  import org.opensaml.saml2.core.AuthnStatement; +import org.opensaml.saml2.core.Conditions;  import org.opensaml.saml2.core.Issuer;  import org.opensaml.saml2.core.NameID; +import org.opensaml.saml2.core.RequestedAuthnContext;  import org.opensaml.saml2.core.Subject; +import org.opensaml.saml2.core.SubjectConfirmation; +import org.opensaml.saml2.core.SubjectConfirmationData; +import org.opensaml.saml2.metadata.AssertionConsumerService;  import org.opensaml.saml2.metadata.AttributeConsumingService; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.NameIDFormat;  import org.opensaml.saml2.metadata.RequestedAttribute;  import org.opensaml.saml2.metadata.SPSSODescriptor;  import org.opensaml.ws.message.encoder.MessageEncodingException; @@ -27,14 +36,21 @@ import org.opensaml.xml.security.SecurityException;  import at.gv.egovernment.moa.id.MOAIDException;  import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;  import at.gv.egovernment.moa.id.moduls.AuthenticationManager; +import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; +import at.gv.egovernment.moa.id.protocols.pvp2x.binding.ArtifactBinding;  import at.gv.egovernment.moa.id.protocols.pvp2x.binding.IEncoder;  import at.gv.egovernment.moa.id.protocols.pvp2x.binding.MOARequest;  import at.gv.egovernment.moa.id.protocols.pvp2x.binding.PostBinding; +import at.gv.egovernment.moa.id.protocols.pvp2x.binding.RedirectBinding;  import at.gv.egovernment.moa.id.protocols.pvp2x.builder.PVPAttributeBuilder;  import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.InvalidAssertionConsumerServiceException; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.NoAuthContextException; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.SAMLRequestNotSupported; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.UnprovideableAttributeException;  import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils; -public class AuthnRequestHandler implements IRequestHandler { +public class AuthnRequestHandler implements IRequestHandler, PVPConstants {  	public boolean handleObject(MOARequest obj) {  		return (obj.getSamlRequest() instanceof AuthnRequest); @@ -48,26 +64,75 @@ public class AuthnRequestHandler implements IRequestHandler {  		AuthnRequest authnRequest = (AuthnRequest)obj.getSamlRequest(); +		RequestedAuthnContext reqAuthnContext = authnRequest.getRequestedAuthnContext(); +		 +		if(reqAuthnContext == null) { +			throw new NoAuthContextException("No Authn Context provided!", null); +		} +		 +		boolean stork_qaa_1_4_found = false; +		 +		Iterator<AuthnContextClassRef> reqAuthnContextClassRefIt = reqAuthnContext.getAuthnContextClassRefs().iterator(); +		 +		while(reqAuthnContextClassRefIt.hasNext()) { +			AuthnContextClassRef authnClassRef = reqAuthnContextClassRefIt.next(); +			String[] qaa_uris = authnClassRef.getAuthnContextClassRef().split("\\s+"); +			for(int i = 0; i < qaa_uris.length; i++) { +				if(qaa_uris[i].trim().equals(STORK_QAA_1_4)) { +					stork_qaa_1_4_found = true; +					break; +				} +			} +		} +		 +		if(!stork_qaa_1_4_found) { +			throw new NoAuthContextException("QAA not available Only supported QAA: " + STORK_QAA_1_4, null); +		} +		  		Assertion assertion = SAML2Utils.createSAMLObject(Assertion.class); +		reqAuthnContextClassRefIt = reqAuthnContext.getAuthnContextClassRefs().iterator(); +		StringBuilder authContextsb = new StringBuilder(); +		while(reqAuthnContextClassRefIt.hasNext()) { +			AuthnContextClassRef authnClassRef = reqAuthnContextClassRefIt.next(); +			String[] qaa_uris = authnClassRef.getAuthnContextClassRef().split("\\s+"); +			for(int i = 0; i < qaa_uris.length; i++) { +				if(qaa_uris[i].trim().equals(STORK_QAA_1_4) || +					qaa_uris[i].trim().equals(STORK_QAA_1_3)|| +					qaa_uris[i].trim().equals(STORK_QAA_1_2)|| +					qaa_uris[i].trim().equals(STORK_QAA_1_1)) { +					authContextsb.append(qaa_uris[i].trim()); +					authContextsb.append(" "); +				} +			} + +		}  		AuthnContextClassRef authnContextClassRef = SAML2Utils.createSAMLObject(AuthnContextClassRef.class); -		authnContextClassRef.setAuthnContextClassRef(AuthnContext.SMARTCARD_PKI_AUTHN_CTX); -		 +		authnContextClassRef.setAuthnContextClassRef(authContextsb.toString());  		AuthnContext authnContext = SAML2Utils.createSAMLObject(AuthnContext.class);  		authnContext.setAuthnContextClassRef(authnContextClassRef);  		AuthnStatement authnStatement = SAML2Utils.createSAMLObject(AuthnStatement.class); -		 +		String remoteSessionID = SAML2Utils.getSecureIdentifier();  		authnStatement.setAuthnInstant(new DateTime()); +		// currently dummy id ... +		authnStatement.setSessionIndex(remoteSessionID);  		authnStatement.setAuthnContext(authnContext);  		assertion.getAuthnStatements().add(authnStatement); -		 -		SPSSODescriptor spSSODescriptor = obj.getEntityMetadata(). +		EntityDescriptor peerEntity = obj.getEntityMetadata(); +		SPSSODescriptor spSSODescriptor = peerEntity.  				getSPSSODescriptor(SAMLConstants.SAML20P_NS); +		Integer aIdx = authnRequest.getAttributeConsumingServiceIndex(); +		int idx = 0; +		 +		if(aIdx != null) { +			idx = aIdx.intValue(); +		} +		  		AttributeConsumingService attributeConsumingService = -				spSSODescriptor.getAttributeConsumingServices().iterator().next(); +				spSSODescriptor.getAttributeConsumingServices().get(idx);  		AuthenticationSession authSession = @@ -81,7 +146,7 @@ public class AuthnRequestHandler implements IRequestHandler {  			Attribute attr = PVPAttributeBuilder.buildAttribute(reqAttribut.getName(), authSession);  			if(attr == null) {  				if(reqAttribut.isRequired()) { -					throw new MOAIDException("Cannot provide requested attribute " + reqAttribut.getName(), null); +					throw new UnprovideableAttributeException(reqAttribut.getName());  				}  			} else {	  				attributeStatement.getAttributes().add(attr); @@ -94,10 +159,47 @@ public class AuthnRequestHandler implements IRequestHandler {  		Subject subject = SAML2Utils.createSAMLObject(Subject.class);  		NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class); +		boolean foundFormat = false; +		Iterator<NameIDFormat> formatIt = spSSODescriptor.getNameIDFormats().iterator(); +		while(formatIt.hasNext()) { +			if(formatIt.next().getFormat().equals(NameID.PERSISTENT)) { +				foundFormat = true; +				break; +			} +		} +		if(!foundFormat) { +			// TODO use correct exception +			throw new SAMLRequestNotSupported(NameID.PERSISTENT + " not supported by SP", null); +		}  		subjectNameID.setFormat(NameID.PERSISTENT); +		subjectNameID.setNameQualifier(authSession.getIdentityLink().getIdentificationType());  		subjectNameID.setValue(authSession.getAuthData().getIdentificationValue());  		subject.setNameID(subjectNameID); +		SubjectConfirmation subjectConfirmation = SAML2Utils.createSAMLObject(SubjectConfirmation.class); +		subjectConfirmation.setMethod(SubjectConfirmation.METHOD_BEARER); +		SubjectConfirmationData subjectConfirmationData =  +				SAML2Utils.createSAMLObject(SubjectConfirmationData.class); +		subjectConfirmationData.setInResponseTo(authnRequest.getID()); +		subjectConfirmationData.setNotOnOrAfter(new DateTime().plusMinutes(20)); +		subjectConfirmationData.setRecipient(peerEntity.getEntityID()); +		 +		subjectConfirmation.setSubjectConfirmationData(subjectConfirmationData); +		 +		subject.getSubjectConfirmations().add(subjectConfirmation); +		 +		Conditions conditions = SAML2Utils.createSAMLObject(Conditions.class); +		AudienceRestriction audienceRestriction = SAML2Utils.createSAMLObject(AudienceRestriction.class); +		Audience audience = SAML2Utils.createSAMLObject(Audience.class); +		 +		audience.setAudienceURI(peerEntity.getEntityID()); +		audienceRestriction.getAudiences().add(audience); +		conditions.setNotBefore(new DateTime()); +		conditions.setNotOnOrAfter(new DateTime().plusMinutes(20)); +		conditions.getAudienceRestrictions().add(audienceRestriction); +		 +		assertion.setConditions(conditions); +		  		//assertion.getAttributeStatements().add(CitizenTokenBuilder.buildCitizenToken(obj, authSession));  		Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class); @@ -105,6 +207,8 @@ public class AuthnRequestHandler implements IRequestHandler {  		issuer.setFormat(NameID.ENTITY);  		assertion.setIssuer(issuer);  		assertion.setSubject(subject); +		assertion.setID(SAML2Utils.getSecureIdentifier()); +		assertion.setIssueInstant(new DateTime());  		ArtifactResponse authResponse = SAML2Utils.createSAMLObject(ArtifactResponse.class); @@ -116,21 +220,41 @@ public class AuthnRequestHandler implements IRequestHandler {  		authResponse.setMessage(assertion);  		authResponse.setStatus(SAML2Utils.getSuccessStatus()); -		Integer aIdx = authnRequest.getAssertionConsumerServiceIndex(); -		int idx = 0; +		aIdx = authnRequest.getAssertionConsumerServiceIndex(); +		idx = 0;  		if(aIdx != null) {  			idx = aIdx.intValue();  		} +		AssertionConsumerService consumerService = spSSODescriptor. +				getAssertionConsumerServices().get(idx); +		 +		if(consumerService == null) { +			throw new InvalidAssertionConsumerServiceException("IDX " + idx + " is not a valid consumer service index!", null); +		} +		String oaURL = consumerService.getLocation(); +		 +		IEncoder binding = null; -		String oaURL = spSSODescriptor. -				getAssertionConsumerServices().get(idx).getLocation(); +		if(consumerService.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) { +			binding = new RedirectBinding(); +		} else if(consumerService.getBinding().equals(SAMLConstants.SAML2_ARTIFACT_BINDING_URI)) { +			// TODO: not supported YET!! +			binding = new ArtifactBinding(); +		} else if(consumerService.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI))  { +			binding = new PostBinding(); +		} + +		if(binding == null) { +			throw new InvalidAssertionConsumerServiceException("Binding " + consumerService.getBinding() + " is not supported", null); +		} -		IEncoder binding = new PostBinding();  		try {  			binding.encodeRespone(req, resp, authResponse, oaURL); +			// TODO add remoteSessionID to AuthSession ExternalPVPSessionStore  		} catch (MessageEncodingException e) { +			e.printStackTrace();  		} catch (SecurityException e) {  			// TODO Auto-generated catch block  			e.printStackTrace(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/RequestManager.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/RequestManager.java index 0e5fa9b1e..9496ecb31 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/RequestManager.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/RequestManager.java @@ -8,8 +8,8 @@ import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletResponse;  import at.gv.egovernment.moa.id.MOAIDException; -import at.gv.egovernment.moa.id.protocols.pvp2x.SAMLRequestNotSupported;  import at.gv.egovernment.moa.id.protocols.pvp2x.binding.MOARequest; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.SAMLRequestNotSupported;  public class RequestManager { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java index 0fa5a7193..7bb5b052f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java @@ -1,6 +1,7 @@  package at.gv.egovernment.moa.id.protocols.pvp2x.utils;  import java.io.IOException; +import java.security.NoSuchAlgorithmException;  import javax.xml.namespace.QName;  import javax.xml.parsers.DocumentBuilder; @@ -9,6 +10,7 @@ import javax.xml.parsers.ParserConfigurationException;  import javax.xml.transform.TransformerException;  import org.opensaml.Configuration; +import org.opensaml.common.impl.SecureRandomIdentifierGenerator;  import org.opensaml.saml2.core.Status;  import org.opensaml.saml2.core.StatusCode;  import org.opensaml.xml.XMLObject; @@ -36,6 +38,12 @@ public class SAML2Utils {  		}  	} +	public static String getSecureIdentifier() { +		return idGenerator.generateIdentifier(); +	} +	 +	private static SecureRandomIdentifierGenerator idGenerator; +	  	private static DocumentBuilder builder;  	static {  		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); @@ -46,6 +54,11 @@ public class SAML2Utils {  			// TODO Auto-generated catch block  			e.printStackTrace();  		} +		try { +			idGenerator = new SecureRandomIdentifierGenerator(); +		} catch(NoSuchAlgorithmException e) { +			e.printStackTrace(); +		}  	}  	public static Document asDOMDocument(XMLObject object) throws IOException, diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/SAMLSignatureValidator.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/SAMLSignatureValidator.java index df0fec001..3a6d15ef6 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/SAMLSignatureValidator.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/SAMLSignatureValidator.java @@ -6,7 +6,7 @@ import org.opensaml.security.SAMLSignatureProfileValidator;  import org.opensaml.xml.validation.ValidationException;  import at.gv.egovernment.moa.id.MOAIDException; -import at.gv.egovernment.moa.id.protocols.pvp2x.SAMLRequestNotSignedException; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.SAMLRequestNotSignedException;  public class SAMLSignatureValidator implements ISAMLValidator { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/EntityVerifier.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/EntityVerifier.java index 41e9b70cf..1233d8dab 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/EntityVerifier.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/EntityVerifier.java @@ -8,7 +8,7 @@ import org.opensaml.xml.signature.SignatureValidator;  import org.opensaml.xml.validation.ValidationException;  import at.gv.egovernment.moa.id.MOAIDException; -import at.gv.egovernment.moa.id.protocols.pvp2x.SAMLRequestNotSignedException; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.SAMLRequestNotSignedException;  import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialProvider;  public class EntityVerifier { | 
