diff options
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java')
-rw-r--r-- | id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java | 150 |
1 files changed, 137 insertions, 13 deletions
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(); |