From fba86d2577e9d6a02d25c0f4bed30ac9559369e1 Mon Sep 17 00:00:00 2001 From: shimingxy Date: Sun, 1 Mar 2020 09:56:12 +0800 Subject: [PATCH] SAML20 FIXED SAML20 FIXED --- .../org/maxkey/authn/BasicAuthentication.java | 7 + .../common/SignatureSecurityPolicyRule.java | 3 +- .../consumer/AuthnRequestGenerator.java | 2 +- .../metadata/endpoint/MetadataEndpoint.java | 6 +- .../provider/endpoint/AssertionEndpoint.java | 30 +---- .../endpoint/SingleSignOnEndpoint.java | 3 +- .../provider/xml/AssertionGenerator.java | 89 +++++++++---- .../xml/AttributeStatementGenerator.java | 60 ++++----- .../provider/xml/AuthnResponseGenerator.java | 123 ++++-------------- .../provider/xml/AuthnStatementGenerator.java | 22 ++-- .../provider/xml/ConditionsGenerator.java | 21 ++- .../saml20/provider/xml/StatusGenerator.java | 15 +-- .../saml20/provider/xml/SubjectGenerator.java | 9 +- .../authz/saml20/xml/IssuerGenerator.java | 8 +- 14 files changed, 161 insertions(+), 237 deletions(-) diff --git a/maxkey-core/src/main/java/org/maxkey/authn/BasicAuthentication.java b/maxkey-core/src/main/java/org/maxkey/authn/BasicAuthentication.java index 9b2004292..68f15d3ac 100644 --- a/maxkey-core/src/main/java/org/maxkey/authn/BasicAuthentication.java +++ b/maxkey-core/src/main/java/org/maxkey/authn/BasicAuthentication.java @@ -67,6 +67,10 @@ public class BasicAuthentication implements Authentication{ public String getJ_username() { return j_username; } + + public String getUsername() { + return j_username; + } public void setJ_username(String j_username) { this.j_username = j_username; @@ -83,6 +87,9 @@ public class BasicAuthentication implements Authentication{ public String getJ_sessionid() { return j_sessionid; } + public String getSessionid() { + return j_sessionid; + } public void setJ_sessionid(String j_sessionid) { this.j_sessionid = j_sessionid; diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml/common/SignatureSecurityPolicyRule.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml/common/SignatureSecurityPolicyRule.java index 33e01dd51..674ace1d5 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml/common/SignatureSecurityPolicyRule.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml/common/SignatureSecurityPolicyRule.java @@ -69,8 +69,9 @@ public class SignatureSecurityPolicyRule implements InitializingBean, SecurityP } SignableSAMLObject samlMessage = (SignableSAMLObject) messageContext.getInboundMessage(); - + //TODO:POST NEED Signed,but some is not if( !samlMessage.isSigned()) { + logger.debug("evaluating signature POST NEED Signed,but some is not."); throw new SecurityPolicyException("InboundMessage was not signed."); } diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/consumer/AuthnRequestGenerator.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/consumer/AuthnRequestGenerator.java index 827479cd7..027c3e1f1 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/consumer/AuthnRequestGenerator.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/consumer/AuthnRequestGenerator.java @@ -22,7 +22,7 @@ public class AuthnRequestGenerator { this.timeService = timeService; this.idService = idService; - issuerGenerator = new IssuerGenerator(issuingEntityName); + issuerGenerator = new IssuerGenerator(this.issuingEntityName); } public AuthnRequest generateAuthnRequest(String destination, String responseLocation) { diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/metadata/endpoint/MetadataEndpoint.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/metadata/endpoint/MetadataEndpoint.java index c152ed167..5530ec9c5 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/metadata/endpoint/MetadataEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/metadata/endpoint/MetadataEndpoint.java @@ -86,11 +86,11 @@ public class MetadataEndpoint { IDPSSODescriptor descriptor = metadataGenerator.buildIDPSSODescriptor(); - descriptor.getSingleSignOnServices().add(metadataGenerator.getSingleSignOnService(WebContext.getHttpContextPath()+"/saml/v20/authz/"+appId,null)); + descriptor.getSingleSignOnServices().add(metadataGenerator.getSingleSignOnService(WebContext.getHttpContextPath()+"/authz/saml20/"+appId,null)); - descriptor.getSingleSignOnServices().add(metadataGenerator.getSingleSignOnService(WebContext.getHttpContextPath()+"/saml/v20/authz/"+appId,SAMLConstants.SAML2_REDIRECT_BINDING_URI)); + descriptor.getSingleSignOnServices().add(metadataGenerator.getSingleSignOnService(WebContext.getHttpContextPath()+"/authz/saml20/"+appId,SAMLConstants.SAML2_REDIRECT_BINDING_URI)); - descriptor.getSingleSignOnServices().add(metadataGenerator.getSingleSignOnService(WebContext.getHttpContextPath()+"/saml/v20/authz/"+appId,SAMLConstants.SAML2_POST_SIMPLE_SIGN_BINDING_URI)); + descriptor.getSingleSignOnServices().add(metadataGenerator.getSingleSignOnService(WebContext.getHttpContextPath()+"/authz/saml20/"+appId,SAMLConstants.SAML2_POST_SIMPLE_SIGN_BINDING_URI)); descriptor.getSingleLogoutServices().add(metadataGenerator.getSingleLogoutService(WebContext.getHttpContextPath()+"/logout",null)); diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/endpoint/AssertionEndpoint.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/endpoint/AssertionEndpoint.java index 7d405765b..19691a260 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/endpoint/AssertionEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/endpoint/AssertionEndpoint.java @@ -1,19 +1,15 @@ package org.maxkey.authz.saml20.provider.endpoint; -import java.util.ArrayList; import java.util.HashMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.joda.time.DateTime; -import org.maxkey.authn.BasicAuthentication; import org.maxkey.authz.saml.common.AuthnRequestInfo; import org.maxkey.authz.saml.common.EndpointGenerator; import org.maxkey.authz.saml20.binding.BindingAdapter; import org.maxkey.authz.saml20.provider.xml.AuthnResponseGenerator; import org.maxkey.domain.apps.AppsSAML20Details; -import org.maxkey.web.WebContext; import org.opensaml.saml2.core.Response; import org.opensaml.saml2.metadata.Endpoint; import org.opensaml.ws.message.encoder.MessageEncodingException; @@ -21,9 +17,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @@ -59,34 +52,13 @@ public class AssertionEndpoint { logger.debug("AuthnRequestInfo: {}", authnRequestInfo); - ArrayList grantedAuthority = new ArrayList(); - grantedAuthority.add(new SimpleGrantedAuthority("ROLE_USER")); - - UsernamePasswordAuthenticationToken authToken = (UsernamePasswordAuthenticationToken)WebContext.getAuthentication(); - - for(GrantedAuthority anthGrantedAuthority: authToken.getAuthorities()){ - grantedAuthority.add(anthGrantedAuthority); - } - //TODO: - //String userName ="shimingxy@qq.com"; - String userName =((BasicAuthentication )authToken.getPrincipal()).getJ_username(); - //aly - //String userName ="admin@1729982683323703.onaliyun.com"; - DateTime authnInstant = new DateTime(request.getSession().getCreationTime()); - - String remoteAddress=WebContext.getRequestIpAddress(request); HashMap attributeMap=new HashMap(); //saml20Details Response authResponse = authnResponseGenerator.generateAuthnResponse( saml20Details, authnRequestInfo, - userName, - remoteAddress, - authnInstant, - grantedAuthority, attributeMap, - bindingAdapter.getSigningCredential(), - bindingAdapter.getSpSigningCredential()); + bindingAdapter); Endpoint endpoint = endpointGenerator.generateEndpoint(saml20Details.getSpAcsUrl()); diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/endpoint/SingleSignOnEndpoint.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/endpoint/SingleSignOnEndpoint.java index af069fd97..3a9798752 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/endpoint/SingleSignOnEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/endpoint/SingleSignOnEndpoint.java @@ -62,6 +62,7 @@ public class SingleSignOnEndpoint { HttpServletRequest request, HttpServletResponse response, @PathVariable("appid") String appId)throws Exception { + logger.debug("SAML Authorize Redirect do POST , app id is "+appId); return extractSAMLRequest(extractPostBindingAdapter,appId,request); } @@ -70,7 +71,7 @@ public class SingleSignOnEndpoint { HttpServletRequest request, HttpServletResponse response, @PathVariable("appid") String appId)throws Exception { - + logger.debug("SAML Authorize Redirect do GET , app id is "+appId); return extractSAMLRequest(extractRedirectBindingAdapter,appId,request); } diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AssertionGenerator.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AssertionGenerator.java index 5c18b3106..c69574f74 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AssertionGenerator.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AssertionGenerator.java @@ -1,12 +1,15 @@ package org.maxkey.authz.saml20.provider.xml; -import java.util.Collection; +import java.util.ArrayList; import java.util.HashMap; import org.joda.time.DateTime; import org.maxkey.authz.saml.service.IDService; import org.maxkey.authz.saml.service.TimeService; +import org.maxkey.authz.saml20.binding.BindingAdapter; import org.maxkey.authz.saml20.xml.IssuerGenerator; +import org.maxkey.domain.apps.AppsSAML20Details; +import org.maxkey.web.WebContext; import org.opensaml.Configuration; import org.opensaml.saml2.core.Assertion; import org.opensaml.saml2.core.AttributeStatement; @@ -15,12 +18,21 @@ import org.opensaml.saml2.core.Conditions; import org.opensaml.saml2.core.Issuer; import org.opensaml.saml2.core.Subject; import org.opensaml.saml2.core.impl.AssertionBuilder; -import org.opensaml.xml.XMLObjectBuilderFactory; +import org.opensaml.xml.security.BasicSecurityConfiguration; +import org.opensaml.xml.security.credential.BasicCredential; +import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorFactory; +import org.opensaml.xml.signature.Signature; +import org.opensaml.xml.signature.SignatureConstants; +import org.opensaml.xml.signature.Signer; +import org.opensaml.xml.signature.impl.SignatureBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; public class AssertionGenerator { - - private final XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory(); + private final static Logger logger = LoggerFactory.getLogger(AssertionGenerator.class); private final IssuerGenerator issuerGenerator; private final SubjectGenerator subjectGenerator; @@ -44,42 +56,75 @@ public class AssertionGenerator { } public Assertion generateAssertion( + AppsSAML20Details saml20Details, + BindingAdapter bindingAdapter, String assertionConsumerURL, - String nameIdValue, String inResponseTo, String audienceUrl, int validInSeconds, - Collection authorities, - HashMapattributeMap, - String clientAddress, - DateTime authnInstant) { + HashMapattributeMap + ) { - - AssertionBuilder assertionBuilder = (AssertionBuilder) builderFactory.getBuilder(Assertion.DEFAULT_ELEMENT_NAME); - Assertion assertion = assertionBuilder.buildObject(); - + Assertion assertion = new AssertionBuilder().buildObject();; + //Subject Subject subject = subjectGenerator.generateSubject( assertionConsumerURL, - nameIdValue, inResponseTo, - validInSeconds, - clientAddress); - + validInSeconds); assertion.setSubject(subject); - + //issuer Issuer issuer = issuerGenerator.generateIssuer(); assertion.setIssuer(issuer); - + //AuthnStatements + DateTime authnInstant = new DateTime(WebContext.getSession().getCreationTime()); AuthnStatement authnStatement = authnStatementGenerator.generateAuthnStatement(authnInstant); assertion.getAuthnStatements().add(authnStatement); - - AttributeStatement attributeStatement =attributeStatementGenerator.generateAttributeStatement(authorities, attributeMap); + //AttributeStatements + ArrayList grantedAuthoritys = new ArrayList(); + grantedAuthoritys.add(new SimpleGrantedAuthority("ROLE_USER")); + for(GrantedAuthority anthGrantedAuthority: ((UsernamePasswordAuthenticationToken)WebContext.getAuthentication()).getAuthorities()){ + grantedAuthoritys.add(anthGrantedAuthority); + } + AttributeStatement attributeStatement =attributeStatementGenerator.generateAttributeStatement( + saml20Details, grantedAuthoritys,attributeMap); assertion.getAttributeStatements().add(attributeStatement); + //ID assertion.setID(idService.generateID()); + //IssueInstant assertion.setIssueInstant(timeService.getCurrentDateTime()); - + //Conditions Conditions conditions = conditionsGenerator.generateConditions(audienceUrl,validInSeconds); assertion.setConditions(conditions); + //sign Assertion + try{ + + BasicCredential basicCredential = new BasicCredential(); + basicCredential.setPrivateKey(bindingAdapter.getSigningCredential().getPrivateKey()); + + Signature signature = new SignatureBuilder().buildObject(); + signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); + signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); + + signature.setSigningCredential(basicCredential); + KeyInfoGeneratorFactory keyInfoGeneratorFactory = Configuration + .getGlobalSecurityConfiguration() + .getKeyInfoGeneratorManager().getDefaultManager() + .getFactory(bindingAdapter.getSigningCredential()); + + signature.setKeyInfo(keyInfoGeneratorFactory.newInstance().generate(bindingAdapter.getSigningCredential())); + BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration(); + config.registerSignatureAlgorithmURI("RSA", SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); + config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256); + assertion.setSignature(signature); + + Configuration.getMarshallerFactory().getMarshaller(assertion).marshall(assertion); + Signer.signObject(signature); + + logger.debug("assertion.isSigned "+assertion.isSigned()); + }catch (Exception e) { + e.printStackTrace(); + logger.info("Unable to Signer assertion ",e); + } return assertion; } diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AttributeStatementGenerator.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AttributeStatementGenerator.java index 72684b77d..98220ffcc 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AttributeStatementGenerator.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AttributeStatementGenerator.java @@ -1,16 +1,16 @@ package org.maxkey.authz.saml20.provider.xml; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; -import org.maxkey.authz.saml20.binding.BindingAdapter; +import org.maxkey.constants.BOOLEAN; import org.maxkey.domain.ExtraAttr; import org.maxkey.domain.ExtraAttrs; import org.maxkey.domain.apps.AppsSAML20Details; -import org.maxkey.web.WebContext; import org.opensaml.Configuration; import org.opensaml.saml2.core.Attribute; import org.opensaml.saml2.core.AttributeStatement; @@ -29,40 +29,35 @@ public class AttributeStatementGenerator { private final XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory(); - public AttributeStatement generateAttributeStatement(Collection authorities) { - return generateAttributeStatement(authorities, null); + public AttributeStatement generateAttributeStatement(AppsSAML20Details saml20Details,ArrayList grantedAuthoritys) { + return generateAttributeStatement(saml20Details, grantedAuthoritys,null); } public AttributeStatement generateAttributeStatement( - Collection authorities, + AppsSAML20Details saml20Details, + ArrayList grantedAuthoritys, HashMapattributeMap) { AttributeStatementBuilder attributeStatementBuilder = (AttributeStatementBuilder) builderFactory.getBuilder(AttributeStatement.DEFAULT_ELEMENT_NAME); AttributeStatement attributeStatement = attributeStatementBuilder.buildObject(); - if(null!=authorities){ - Attribute attributeGrantedAuthority=builderGrantedAuthority(authorities); - attributeStatement.getAttributes().add(attributeGrantedAuthority); - } + + Attribute attributeGrantedAuthority=builderGrantedAuthority(grantedAuthoritys); + attributeStatement.getAttributes().add(attributeGrantedAuthority); if(null!=attributeMap){ Iterator> iterator = attributeMap.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); - String key = entry.getKey(); String value = entry.getValue(); - Attribute attribute=builderAttribute(key,value,Attribute.BASIC); - attributeStatement.getAttributes().add(attribute); - } } - BindingAdapter bindingAdapter = (BindingAdapter) WebContext.getSession().getAttribute("samlv20Adapter"); - AppsSAML20Details saml20Details = bindingAdapter.getSaml20Details(); + logger.debug("ExtendAttr "+saml20Details.getExtendAttr()); - if(saml20Details.getIsExtendAttr()==1) { + if(BOOLEAN.isTrue(saml20Details.getIsExtendAttr())) { ExtraAttrs extraAttrs=new ExtraAttrs(saml20Details.getExtendAttr()); for(ExtraAttr extraAttr : extraAttrs.getExtraAttrs()) { logger.debug("Attribute : "+extraAttr.getAttr()+" , Vale : "+extraAttr.getValue()+" , Type : "+extraAttr.getType()); @@ -79,39 +74,36 @@ public class AttributeStatementGenerator { attribute.setName(attributeName); // urn:oasis:names:tc:SAML:2.0:attrname-format:basic + if(nameFormat==null || nameFormat.equals("")) { + nameFormat=Attribute.BASIC; + } + attribute.setNameFormat(nameFormat); - - // Response/Assertion/AttributeStatement/Attribute/AttributeValue - XSStringBuilder stringBuilder = (XSStringBuilder) builderFactory.getBuilder(XSString.TYPE_NAME); - XSString stringValue = stringBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME); - stringValue.setValue(value); - - attribute.getAttributeValues().add(stringValue); + if(value!=null) { + attribute.getAttributeValues().add(builderAttributeValue(value)); + } return attribute; } public Attribute builderGrantedAuthority(Collection authorities){ // Response/Assertion/AttributeStatement/Attribute - AttributeBuilder attributeBuilder = (AttributeBuilder) builderFactory.getBuilder(Attribute.DEFAULT_ELEMENT_NAME); - Attribute attribute = attributeBuilder.buildObject(); - attribute.setName("GrantedAuthority"); - - // urn:oasis:names:tc:SAML:2.0:attrname-format:basic - attribute.setNameFormat(Attribute.BASIC); - + Attribute attribute = builderAttribute("GrantedAuthority",null,null); for (GrantedAuthority grantedAuthority : authorities) { // this was convoluted to figure out // Response/Assertion/AttributeStatement/Attribute/AttributeValue - XSStringBuilder stringBuilder = (XSStringBuilder) Configuration.getBuilderFactory().getBuilder(XSString.TYPE_NAME); - XSString stringValue = stringBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME); - stringValue.setValue(grantedAuthority.getAuthority()); - attribute.getAttributeValues().add(stringValue); + attribute.getAttributeValues().add(builderAttributeValue(grantedAuthority.getAuthority())); } return attribute; } + public XSString builderAttributeValue(String value) { + XSString xsStringValue = new XSStringBuilder().buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME); + xsStringValue.setValue(value); + return xsStringValue; + } + } diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AuthnResponseGenerator.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AuthnResponseGenerator.java index e6f52d84c..566eca790 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AuthnResponseGenerator.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AuthnResponseGenerator.java @@ -1,55 +1,35 @@ package org.maxkey.authz.saml20.provider.xml; - -import java.util.Collection; import java.util.HashMap; -import org.joda.time.DateTime; import org.maxkey.authz.saml.common.AuthnRequestInfo; import org.maxkey.authz.saml.service.IDService; import org.maxkey.authz.saml.service.TimeService; +import org.maxkey.authz.saml20.binding.BindingAdapter; import org.maxkey.authz.saml20.xml.IssuerGenerator; import org.maxkey.constants.BOOLEAN; import org.maxkey.domain.apps.AppsSAML20Details; import org.opensaml.Configuration; import org.opensaml.saml2.core.Assertion; import org.opensaml.saml2.core.EncryptedAssertion; -import org.opensaml.saml2.core.Issuer; import org.opensaml.saml2.core.Response; import org.opensaml.saml2.core.StatusCode; import org.opensaml.saml2.core.impl.ResponseBuilder; import org.opensaml.saml2.encryption.Encrypter; import org.opensaml.saml2.encryption.Encrypter.KeyPlacement; -import org.opensaml.xml.XMLObjectBuilderFactory; import org.opensaml.xml.encryption.EncryptionConstants; -import org.opensaml.xml.encryption.EncryptionException; import org.opensaml.xml.encryption.EncryptionParameters; import org.opensaml.xml.encryption.KeyEncryptionParameters; -import org.opensaml.xml.io.Marshaller; -import org.opensaml.xml.io.MarshallerFactory; -import org.opensaml.xml.io.MarshallingException; -import org.opensaml.xml.security.BasicSecurityConfiguration; -import org.opensaml.xml.security.credential.BasicCredential; -import org.opensaml.xml.security.credential.Credential; import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorFactory; -import org.opensaml.xml.signature.Signature; -import org.opensaml.xml.signature.SignatureConstants; -import org.opensaml.xml.signature.SignatureException; -import org.opensaml.xml.signature.Signer; -import org.opensaml.xml.signature.impl.SignatureBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.security.core.GrantedAuthority; public class AuthnResponseGenerator { private final static Logger logger = LoggerFactory.getLogger(AuthnResponseGenerator.class); - private final XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory(); - private String issuerName; private IDService idService; private TimeService timeService; - private AssertionGenerator assertionGenerator; private IssuerGenerator issuerGenerator; private StatusGenerator statusGenerator; @@ -58,113 +38,64 @@ public class AuthnResponseGenerator { this.issuerName = issuerName; this.idService = idService; this.timeService = timeService; - issuerGenerator = new IssuerGenerator(issuerName); + issuerGenerator = new IssuerGenerator(this.issuerName); assertionGenerator = new AssertionGenerator(issuerName, timeService, idService); statusGenerator = new StatusGenerator(); - } public Response generateAuthnResponse( AppsSAML20Details saml20Details, AuthnRequestInfo authnRequestInfo, - String nameIdValue, - String clientAddress, - DateTime authnInstant, - Collection authorities, HashMapattributeMap, - Credential signingCredential, - Credential spSigningCredential){ - - ResponseBuilder responseBuilder = (ResponseBuilder) builderFactory.getBuilder(Response.DEFAULT_ELEMENT_NAME); - Response authResponse = responseBuilder.buildObject(); - - int validInSeconds=Integer.parseInt(saml20Details.getValidityInterval()); - String audienceUrl=saml20Details.getAudience(); - String assertionConsumerURL=saml20Details.getSpAcsUrl(); - String inResponseTo=authnRequestInfo.getAuthnRequestID(); - - Issuer responseIssuer = issuerGenerator.generateIssuer(); + BindingAdapter bindingAdapter){ + Response authResponse = new ResponseBuilder().buildObject(); + //builder Assertion Assertion assertion = assertionGenerator.generateAssertion( - assertionConsumerURL, - nameIdValue, - inResponseTo, - audienceUrl, - validInSeconds, - authorities, - attributeMap, - clientAddress, - authnInstant); + saml20Details, + bindingAdapter, + saml20Details.getSpAcsUrl(), + authnRequestInfo.getAuthnRequestID(), + saml20Details.getAudience(), + Integer.parseInt(saml20Details.getValidityInterval()), + attributeMap); - try{ - - logger.debug("authResponse.isSigned "+authResponse.isSigned()); - - //assertion.setSignature(newSignature); - if(BOOLEAN.isTrue(saml20Details.getEncrypted())) { + //Encrypt + if(BOOLEAN.isTrue(saml20Details.getEncrypted())) { + logger.info("begin to encrypt assertion"); + try { // Assume this contains a recipient's RSA public - logger.info("begin to encrypt assertion"); EncryptionParameters encryptionParameters = new EncryptionParameters(); encryptionParameters.setAlgorithm(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128); logger.info("encryption assertion Algorithm : "+EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128); KeyEncryptionParameters keyEncryptionParameters = new KeyEncryptionParameters(); - keyEncryptionParameters.setEncryptionCredential(spSigningCredential); + keyEncryptionParameters.setEncryptionCredential(bindingAdapter.getSpSigningCredential()); // kekParams.setAlgorithm(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP); keyEncryptionParameters.setAlgorithm(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15); logger.info("keyEncryption Algorithm : "+EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15); KeyInfoGeneratorFactory keyInfoGeneratorFactory = Configuration .getGlobalSecurityConfiguration() .getKeyInfoGeneratorManager().getDefaultManager() - .getFactory(spSigningCredential); + .getFactory(bindingAdapter.getSpSigningCredential()); keyEncryptionParameters.setKeyInfoGenerator(keyInfoGeneratorFactory.newInstance()); Encrypter encrypter = new Encrypter(encryptionParameters, keyEncryptionParameters); encrypter.setKeyPlacement(KeyPlacement.PEER); EncryptedAssertion encryptedAssertion = encrypter.encrypt(assertion); authResponse.getEncryptedAssertions().add(encryptedAssertion); - } - - SignatureBuilder signatureBuilder = (SignatureBuilder) builderFactory.getBuilder(Signature.DEFAULT_ELEMENT_NAME); - BasicCredential basicCredential = new BasicCredential(); - basicCredential.setPrivateKey(signingCredential.getPrivateKey()); - - Signature signature = signatureBuilder.buildObject(); - signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); - signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); - - signature.setSigningCredential(basicCredential); - KeyInfoGeneratorFactory keyInfoGeneratorFactory = Configuration - .getGlobalSecurityConfiguration() - .getKeyInfoGeneratorManager().getDefaultManager() - .getFactory(signingCredential); - - signature.setKeyInfo(keyInfoGeneratorFactory.newInstance().generate(signingCredential)); - BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration(); - config.registerSignatureAlgorithmURI("RSA", SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); - config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256); - assertion.setSignature(signature); - - Configuration.getMarshallerFactory().getMarshaller(assertion).marshall(assertion); - Signer.signObject(signature); - - logger.debug("assertion.isSigned "+assertion.isSigned());; + }catch(Exception e) { + logger.info("Unable to encrypt assertion .",e); + } + }else { authResponse.getAssertions().add(assertion); - } - catch (EncryptionException e) { - logger.info("Unable to encrypt assertion ."); - e.printStackTrace(); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - authResponse.setIssuer(responseIssuer); + + authResponse.setIssuer(issuerGenerator.generateIssuer()); authResponse.setID(idService.generateID()); authResponse.setIssueInstant(timeService.getCurrentDateTime()); - authResponse.setInResponseTo(inResponseTo); - //authResponse.getAssertions().add(assertion); - authResponse.setDestination(assertionConsumerURL); + authResponse.setInResponseTo(authnRequestInfo.getAuthnRequestID()); + authResponse.setDestination(saml20Details.getSpAcsUrl()); authResponse.setStatus(statusGenerator.generateStatus(StatusCode.SUCCESS_URI)); + logger.debug("authResponse.isSigned "+authResponse.isSigned()); return authResponse; } diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AuthnStatementGenerator.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AuthnStatementGenerator.java index 66b02bb35..674b287a8 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AuthnStatementGenerator.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AuthnStatementGenerator.java @@ -2,39 +2,33 @@ package org.maxkey.authz.saml20.provider.xml; import org.joda.time.DateTime; -import org.opensaml.Configuration; import org.opensaml.saml2.core.AuthnContext; import org.opensaml.saml2.core.AuthnContextClassRef; import org.opensaml.saml2.core.AuthnStatement; import org.opensaml.saml2.core.impl.AuthnContextBuilder; import org.opensaml.saml2.core.impl.AuthnContextClassRefBuilder; import org.opensaml.saml2.core.impl.AuthnStatementBuilder; -import org.opensaml.xml.XMLObjectBuilderFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class AuthnStatementGenerator { - + private final static Logger logger = LoggerFactory.getLogger(AuthnStatementGenerator.class); - private final XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory(); - public AuthnStatement generateAuthnStatement(DateTime authnInstant) { //Response/Assertion/AuthnStatement/AuthContext/AuthContextClassRef - AuthnContextClassRefBuilder authnContextClassRefBuilder = (AuthnContextClassRefBuilder) builderFactory.getBuilder(AuthnContextClassRef.DEFAULT_ELEMENT_NAME); - AuthnContextClassRef authnContextClassRef = authnContextClassRefBuilder.buildObject(); + AuthnContextClassRef authnContextClassRef = new AuthnContextClassRefBuilder().buildObject(); //urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport - authnContextClassRef.setAuthnContextClassRef(AuthnContext.PASSWORD_AUTHN_CTX); + authnContextClassRef.setAuthnContextClassRef(AuthnContext.PPT_AUTHN_CTX); //Response/Assertion/AuthnStatement/AuthContext - AuthnContextBuilder authnContextBuilder = (AuthnContextBuilder)builderFactory.getBuilder(AuthnContext.DEFAULT_ELEMENT_NAME); - AuthnContext authnContext = authnContextBuilder.buildObject(); + AuthnContext authnContext = new AuthnContextBuilder().buildObject(); authnContext.setAuthnContextClassRef(authnContextClassRef); //Response/Assertion/AuthnStatement - AuthnStatementBuilder authnStatementBuilder = (AuthnStatementBuilder) builderFactory.getBuilder(AuthnStatement.DEFAULT_ELEMENT_NAME); - AuthnStatement authnStatement = authnStatementBuilder.buildObject(); + AuthnStatement authnStatement = new AuthnStatementBuilder().buildObject(); authnStatement.setAuthnContext(authnContext); - authnStatement.setAuthnInstant(authnInstant); - + logger.debug("generateAuthnStatement authnInstant "+authnInstant); return authnStatement; } diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/ConditionsGenerator.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/ConditionsGenerator.java index 34407b5e7..489d93995 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/ConditionsGenerator.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/ConditionsGenerator.java @@ -2,23 +2,20 @@ package org.maxkey.authz.saml20.provider.xml; import org.joda.time.DateTime; -import org.opensaml.Configuration; import org.opensaml.saml2.core.Audience; import org.opensaml.saml2.core.AudienceRestriction; import org.opensaml.saml2.core.Conditions; import org.opensaml.saml2.core.impl.AudienceBuilder; import org.opensaml.saml2.core.impl.AudienceRestrictionBuilder; import org.opensaml.saml2.core.impl.ConditionsBuilder; -import org.opensaml.xml.XMLObjectBuilderFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ConditionsGenerator { - - private final XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory(); - + private final static Logger logger = LoggerFactory.getLogger(ConditionsGenerator.class); + public Conditions generateConditions(String audienceUrl,int validInSeconds) { - ConditionsBuilder conditionsBuilder = (ConditionsBuilder) builderFactory.getBuilder(Conditions.DEFAULT_ELEMENT_NAME); - - Conditions conditions = conditionsBuilder.buildObject(); + Conditions conditions = new ConditionsBuilder().buildObject(); conditions.setNotBefore(new DateTime()); conditions.setNotOnOrAfter(new DateTime().plus(validInSeconds*1000)); @@ -29,15 +26,13 @@ public class ConditionsGenerator { } public AudienceRestriction builderAudienceRestriction(String audienceUrl){ - AudienceRestrictionBuilder audienceRestrictionBuilder = (AudienceRestrictionBuilder) builderFactory.getBuilder(AudienceRestriction.DEFAULT_ELEMENT_NAME); - AudienceRestriction audienceRestriction = audienceRestrictionBuilder.buildObject(); + AudienceRestriction audienceRestriction = new AudienceRestrictionBuilder().buildObject(); - AudienceBuilder audienceBuilder = (AudienceBuilder) builderFactory.getBuilder(Audience.DEFAULT_ELEMENT_NAME); - Audience audience = audienceBuilder.buildObject(); + Audience audience = new AudienceBuilder().buildObject(); audience.setAudienceURI(audienceUrl); audienceRestriction.getAudiences().add(audience); - + logger.debug("Audience URL "+audienceUrl); return audienceRestriction; } diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/StatusGenerator.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/StatusGenerator.java index c6836b496..2a78911fb 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/StatusGenerator.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/StatusGenerator.java @@ -1,20 +1,15 @@ package org.maxkey.authz.saml20.provider.xml; -import org.opensaml.Configuration; - import org.opensaml.saml2.core.Status; import org.opensaml.saml2.core.StatusCode; import org.opensaml.saml2.core.StatusMessage; import org.opensaml.saml2.core.impl.StatusBuilder; import org.opensaml.saml2.core.impl.StatusCodeBuilder; import org.opensaml.saml2.core.impl.StatusMessageBuilder; -import org.opensaml.xml.XMLObjectBuilderFactory; public class StatusGenerator { - private final XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory(); - public Status generateStatus( String value ) { Status status = builderStatus(); @@ -45,23 +40,19 @@ public class StatusGenerator { } public Status builderStatus(){ - StatusBuilder builder = (StatusBuilder) builderFactory.getBuilder(Status.DEFAULT_ELEMENT_NAME); - Status status = (Status) builder.buildObject(); + Status status = (Status) new StatusBuilder().buildObject(); return status; } public StatusCode builderStatusCode(String value){ - StatusCodeBuilder codeBuilder = (StatusCodeBuilder) builderFactory.getBuilder(StatusCode.DEFAULT_ELEMENT_NAME); - - StatusCode statusCode = (StatusCode) codeBuilder.buildObject(); + StatusCode statusCode = (StatusCode) new StatusCodeBuilder().buildObject(); statusCode.setValue(value); return statusCode; } public StatusMessage builderStatusMessage(String message){ - StatusMessageBuilder statusMessageBuilder = (StatusMessageBuilder) builderFactory.getBuilder(StatusMessage.DEFAULT_ELEMENT_NAME); - StatusMessage statusMessage = statusMessageBuilder.buildObject(); + StatusMessage statusMessage = new StatusMessageBuilder().buildObject(); statusMessage.setMessage(message); diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/SubjectGenerator.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/SubjectGenerator.java index 5a39c9476..95c9cf704 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/SubjectGenerator.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/SubjectGenerator.java @@ -3,6 +3,7 @@ package org.maxkey.authz.saml20.provider.xml; import org.maxkey.authz.saml.service.TimeService; +import org.maxkey.web.WebContext; import org.opensaml.saml2.core.NameID; import org.opensaml.saml2.core.NameIDType; import org.opensaml.saml2.core.Subject; @@ -25,14 +26,14 @@ public class SubjectGenerator { public Subject generateSubject( String assertionConsumerURL, - String nameIdValue, String inResponseTo, - int validInSeconds, - String clientAddress) { - + int validInSeconds) { + String nameIdValue =WebContext.getUserInfo().getUsername(); NameID nameID =builderNameID(nameIdValue,assertionConsumerURL); Subject subject =builderSubject(nameID); + + String clientAddress=WebContext.getRequestIpAddress(WebContext.getRequest()); SubjectConfirmation subjectConfirmation =builderSubjectConfirmation( assertionConsumerURL, inResponseTo, diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/xml/IssuerGenerator.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/xml/IssuerGenerator.java index f00d65615..4c445feb7 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/xml/IssuerGenerator.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/xml/IssuerGenerator.java @@ -1,15 +1,11 @@ package org.maxkey.authz.saml20.xml; -import org.opensaml.Configuration; import org.opensaml.saml2.core.Issuer; import org.opensaml.saml2.core.NameIDType; import org.opensaml.saml2.core.impl.IssuerBuilder; -import org.opensaml.xml.XMLObjectBuilderFactory; public class IssuerGenerator { - - private final XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory(); private final String issuerName; @@ -19,14 +15,12 @@ public class IssuerGenerator { public Issuer generateIssuer() { ///Issuer - IssuerBuilder issuerBuilder = (IssuerBuilder) builderFactory.getBuilder(Issuer.DEFAULT_ELEMENT_NAME); - Issuer issuer = issuerBuilder.buildObject(); + Issuer issuer = new IssuerBuilder().buildObject(); issuer.setValue(issuerName); issuer.setFormat(NameIDType.ENTITY); return issuer; - } }