mirror of
https://gitee.com/dromara/MaxKey.git
synced 2025-12-06 17:08:29 +08:00
SAML20 FIXED
SAML20 FIXED
This commit is contained in:
parent
ac9e2dd7ba
commit
fba86d2577
@ -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;
|
||||
|
||||
@ -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.");
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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));
|
||||
|
||||
|
||||
@ -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> grantedAuthority = new ArrayList<GrantedAuthority>();
|
||||
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 <String,String>attributeMap=new HashMap<String,String>();
|
||||
//saml20Details
|
||||
Response authResponse = authnResponseGenerator.generateAuthnResponse(
|
||||
saml20Details,
|
||||
authnRequestInfo,
|
||||
userName,
|
||||
remoteAddress,
|
||||
authnInstant,
|
||||
grantedAuthority,
|
||||
attributeMap,
|
||||
bindingAdapter.getSigningCredential(),
|
||||
bindingAdapter.getSpSigningCredential());
|
||||
bindingAdapter);
|
||||
|
||||
Endpoint endpoint = endpointGenerator.generateEndpoint(saml20Details.getSpAcsUrl());
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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<GrantedAuthority> authorities,
|
||||
HashMap<String,String>attributeMap,
|
||||
String clientAddress,
|
||||
DateTime authnInstant) {
|
||||
HashMap<String,String>attributeMap
|
||||
) {
|
||||
|
||||
|
||||
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<GrantedAuthority> grantedAuthoritys = new ArrayList<GrantedAuthority>();
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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<GrantedAuthority> authorities) {
|
||||
return generateAttributeStatement(authorities, null);
|
||||
public AttributeStatement generateAttributeStatement(AppsSAML20Details saml20Details,ArrayList<GrantedAuthority> grantedAuthoritys) {
|
||||
return generateAttributeStatement(saml20Details, grantedAuthoritys,null);
|
||||
|
||||
}
|
||||
|
||||
public AttributeStatement generateAttributeStatement(
|
||||
Collection<GrantedAuthority> authorities,
|
||||
AppsSAML20Details saml20Details,
|
||||
ArrayList<GrantedAuthority> grantedAuthoritys,
|
||||
HashMap<String,String>attributeMap) {
|
||||
|
||||
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<Entry<String, String>> iterator = attributeMap.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, String> entry = (Map.Entry<String, String>) 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<GrantedAuthority> 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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<GrantedAuthority> authorities,
|
||||
HashMap<String,String>attributeMap,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user