Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
reg-app
Regapp
Commits
6936fed1
Commit
6936fed1
authored
Nov 14, 2019
by
michael.simon
Browse files
Assertion encryption working
parent
7085d715
Changes
1
Show whitespace changes
Inline
Side-by-side
bwreg-webapp/src/main/java/edu/kit/scc/webreg/sec/Saml2IdpRedirectResponseHandler.java
View file @
6936fed1
...
@@ -10,10 +10,15 @@
...
@@ -10,10 +10,15 @@
******************************************************************************/
******************************************************************************/
package
edu.kit.scc.webreg.sec
;
package
edu.kit.scc.webreg.sec
;
import
java.io.ByteArrayInputStream
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.net.URL
;
import
java.net.URL
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.NoSuchProviderException
;
import
java.security.PrivateKey
;
import
java.security.PrivateKey
;
import
java.security.cert.CertificateException
;
import
java.security.cert.CertificateFactory
;
import
java.security.cert.X509Certificate
;
import
java.security.cert.X509Certificate
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
...
@@ -24,6 +29,7 @@ import javax.servlet.ServletException;
...
@@ -24,6 +29,7 @@ import javax.servlet.ServletException;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.servlet.http.HttpServletResponse
;
import
org.apache.commons.codec.binary.Base64
;
import
org.apache.velocity.app.VelocityEngine
;
import
org.apache.velocity.app.VelocityEngine
;
import
org.joda.time.DateTime
;
import
org.joda.time.DateTime
;
import
org.opensaml.core.xml.io.MarshallingException
;
import
org.opensaml.core.xml.io.MarshallingException
;
...
@@ -31,6 +37,7 @@ import org.opensaml.core.xml.schema.XSString;
...
@@ -31,6 +37,7 @@ import org.opensaml.core.xml.schema.XSString;
import
org.opensaml.messaging.context.MessageContext
;
import
org.opensaml.messaging.context.MessageContext
;
import
org.opensaml.messaging.decoder.MessageDecodingException
;
import
org.opensaml.messaging.decoder.MessageDecodingException
;
import
org.opensaml.messaging.encoder.MessageEncodingException
;
import
org.opensaml.messaging.encoder.MessageEncodingException
;
import
org.opensaml.profile.context.ProfileRequestContext
;
import
org.opensaml.saml.common.SAMLObject
;
import
org.opensaml.saml.common.SAMLObject
;
import
org.opensaml.saml.common.messaging.SAMLMessageSecuritySupport
;
import
org.opensaml.saml.common.messaging.SAMLMessageSecuritySupport
;
import
org.opensaml.saml.common.messaging.context.SAMLEndpointContext
;
import
org.opensaml.saml.common.messaging.context.SAMLEndpointContext
;
...
@@ -50,28 +57,56 @@ import org.opensaml.saml.saml2.core.AuthnRequest;
...
@@ -50,28 +57,56 @@ import org.opensaml.saml.saml2.core.AuthnRequest;
import
org.opensaml.saml.saml2.core.AuthnStatement
;
import
org.opensaml.saml.saml2.core.AuthnStatement
;
import
org.opensaml.saml.saml2.core.Condition
;
import
org.opensaml.saml.saml2.core.Condition
;
import
org.opensaml.saml.saml2.core.Conditions
;
import
org.opensaml.saml.saml2.core.Conditions
;
import
org.opensaml.saml.saml2.core.EncryptedAssertion
;
import
org.opensaml.saml.saml2.core.NameID
;
import
org.opensaml.saml.saml2.core.NameID
;
import
org.opensaml.saml.saml2.core.Response
;
import
org.opensaml.saml.saml2.core.Response
;
import
org.opensaml.saml.saml2.core.impl.RequestedAuthnContextBuilder
;
import
org.opensaml.saml.saml2.encryption.Decrypter
;
import
org.opensaml.saml.saml2.encryption.Encrypter
;
import
org.opensaml.saml.saml2.metadata.AssertionConsumerService
;
import
org.opensaml.saml.saml2.metadata.AssertionConsumerService
;
import
org.opensaml.saml.saml2.metadata.EntityDescriptor
;
import
org.opensaml.saml.saml2.metadata.KeyDescriptor
;
import
org.opensaml.saml.saml2.metadata.SPSSODescriptor
;
import
org.opensaml.saml.saml2.profile.context.EncryptionContext
;
import
org.opensaml.saml.security.impl.MetadataCredentialResolver
;
import
org.opensaml.saml.security.impl.SAMLMetadataEncryptionParametersResolver
;
import
org.opensaml.saml.security.impl.SAMLMetadataSignatureSigningParametersResolver
;
import
org.opensaml.saml.security.impl.SAMLMetadataSignatureSigningParametersResolver
;
import
org.opensaml.security.SecurityException
;
import
org.opensaml.security.SecurityException
;
import
org.opensaml.security.credential.BasicCredential
;
import
org.opensaml.security.credential.Credential
;
import
org.opensaml.security.credential.Credential
;
import
org.opensaml.security.credential.CredentialResolver
;
import
org.opensaml.security.credential.UsageType
;
import
org.opensaml.security.x509.BasicX509Credential
;
import
org.opensaml.security.x509.BasicX509Credential
;
import
org.opensaml.xmlsec.EncryptionParameters
;
import
org.opensaml.xmlsec.SignatureSigningParameters
;
import
org.opensaml.xmlsec.SignatureSigningParameters
;
import
org.opensaml.xmlsec.algorithm.AlgorithmSupport
;
import
org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap
;
import
org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap
;
import
org.opensaml.xmlsec.context.SecurityParametersContext
;
import
org.opensaml.xmlsec.context.SecurityParametersContext
;
import
org.opensaml.xmlsec.criterion.SignatureSigningConfigurationCriterion
;
import
org.opensaml.xmlsec.criterion.SignatureSigningConfigurationCriterion
;
import
org.opensaml.xmlsec.encryption.support.DataEncryptionParameters
;
import
org.opensaml.xmlsec.encryption.support.EncryptionConstants
;
import
org.opensaml.xmlsec.encryption.support.EncryptionException
;
import
org.opensaml.xmlsec.encryption.support.InlineEncryptedKeyResolver
;
import
org.opensaml.xmlsec.encryption.support.KeyEncryptionParameters
;
import
org.opensaml.xmlsec.impl.BasicEncryptionConfiguration
;
import
org.opensaml.xmlsec.impl.BasicSignatureSigningConfiguration
;
import
org.opensaml.xmlsec.impl.BasicSignatureSigningConfiguration
;
import
org.opensaml.xmlsec.keyinfo.KeyInfoCredentialResolver
;
import
org.opensaml.xmlsec.keyinfo.impl.BasicKeyInfoGeneratorFactory
;
import
org.opensaml.xmlsec.keyinfo.impl.StaticKeyInfoCredentialResolver
;
import
org.opensaml.xmlsec.signature.KeyInfo
;
import
org.opensaml.xmlsec.signature.X509Data
;
import
org.opensaml.xmlsec.signature.support.SignatureException
;
import
org.opensaml.xmlsec.signature.support.SignatureException
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
edu.kit.scc.webreg.bootstrap.ApplicationConfig
;
import
edu.kit.scc.webreg.bootstrap.ApplicationConfig
;
import
edu.kit.scc.webreg.drools.KnowledgeSessionService
;
import
edu.kit.scc.webreg.drools.KnowledgeSessionService
;
import
edu.kit.scc.webreg.entity.SamlAAConfigurationEntity
;
import
edu.kit.scc.webreg.entity.SamlAAConfigurationEntity
;
import
edu.kit.scc.webreg.entity.SamlSpMetadataEntity
;
import
edu.kit.scc.webreg.entity.UserEntity
;
import
edu.kit.scc.webreg.entity.UserEntity
;
import
edu.kit.scc.webreg.exc.SamlAuthenticationException
;
import
edu.kit.scc.webreg.exc.SamlAuthenticationException
;
import
edu.kit.scc.webreg.service.SamlAAConfigurationService
;
import
edu.kit.scc.webreg.service.SamlAAConfigurationService
;
import
edu.kit.scc.webreg.service.SamlIdpMetadataService
;
import
edu.kit.scc.webreg.service.SamlIdpMetadataService
;
import
edu.kit.scc.webreg.service.SamlSpMetadataService
;
import
edu.kit.scc.webreg.service.UserService
;
import
edu.kit.scc.webreg.service.UserService
;
import
edu.kit.scc.webreg.service.saml.CryptoHelper
;
import
edu.kit.scc.webreg.service.saml.CryptoHelper
;
import
edu.kit.scc.webreg.service.saml.Saml2AssertionService
;
import
edu.kit.scc.webreg.service.saml.Saml2AssertionService
;
...
@@ -111,6 +146,9 @@ public class Saml2IdpRedirectResponseHandler {
...
@@ -111,6 +146,9 @@ public class Saml2IdpRedirectResponseHandler {
@Inject
@Inject
private
SamlAAConfigurationService
aaConfigService
;
private
SamlAAConfigurationService
aaConfigService
;
@Inject
private
SamlSpMetadataService
spService
;
@Inject
@Inject
private
ApplicationConfig
appConfig
;
private
ApplicationConfig
appConfig
;
...
@@ -132,9 +170,11 @@ public class Saml2IdpRedirectResponseHandler {
...
@@ -132,9 +170,11 @@ public class Saml2IdpRedirectResponseHandler {
UserEntity
user
=
userService
.
findById
(
session
.
getUserId
());
UserEntity
user
=
userService
.
findById
(
session
.
getUserId
());
AuthnRequest
authnRequest
=
samlIdpService
.
resumeAuthnRequest
(
session
.
getAuthnRequestId
());
AuthnRequest
authnRequest
=
samlIdpService
.
resumeAuthnRequest
(
session
.
getAuthnRequestId
());
logger
.
debug
(
"Authn request reloaded: {}"
,
samlHelper
.
prettyPrint
(
authnRequest
));
logger
.
debug
(
"Authn request reloaded: {}"
,
samlHelper
.
prettyPrint
(
authnRequest
));
SamlSpMetadataEntity
spMetadata
=
spService
.
findByEntityId
(
authnRequest
.
getIssuer
().
getValue
());
logger
.
debug
(
"Corresponding SP found in Metadata: {}"
,
spMetadata
.
getEntityId
());
Response
samlResponse
=
ssoHelper
.
buildAuthnResponse
(
authnRequest
,
"https://bwidm.scc.kit.edu/saml/idp/metadata"
);
Response
samlResponse
=
ssoHelper
.
buildAuthnResponse
(
authnRequest
,
"https://bwidm.scc.kit.edu/saml/idp/metadata"
);
Audience
audience
=
samlHelper
.
create
(
Audience
.
class
,
Audience
.
DEFAULT_ELEMENT_NAME
);
Audience
audience
=
samlHelper
.
create
(
Audience
.
class
,
Audience
.
DEFAULT_ELEMENT_NAME
);
...
@@ -164,42 +204,24 @@ public class Saml2IdpRedirectResponseHandler {
...
@@ -164,42 +204,24 @@ public class Saml2IdpRedirectResponseHandler {
assertion
.
setConditions
(
conditions
);
assertion
.
setConditions
(
conditions
);
assertion
.
getAttributeStatements
().
add
(
buildAttributeStatement
(
user
));
assertion
.
getAttributeStatements
().
add
(
buildAttributeStatement
(
user
));
assertion
.
getAuthnStatements
().
add
(
as
);
assertion
.
getAuthnStatements
().
add
(
as
);
samlResponse
.
getAssertions
().
add
(
assertion
);
PrivateKey
privateKey
;
X509Certificate
publicKey
;
try
{
privateKey
=
cryptoHelper
.
getPrivateKey
(
aaConfig
.
getPrivateKey
());
publicKey
=
cryptoHelper
.
getCertificate
(
aaConfig
.
getCertificate
());
}
catch
(
IOException
e
)
{
throw
new
ServletException
(
"Private key is not set up properly"
,
e
);
}
BasicX509Credential
credential
=
new
BasicX509Credential
(
publicKey
,
privateKey
);
List
<
Credential
>
credentialList
=
new
ArrayList
<
Credential
>();
credentialList
.
add
(
credential
);
BasicSignatureSigningConfiguration
ssConfig
=
DefaultSecurityConfigurationBootstrap
.
buildDefaultSignatureSigningConfiguration
();
SecurityParametersContext
securityContext
=
buildSecurityContext
(
aaConfig
);
ssConfig
.
setSigningCredentials
(
credentialList
);
HTTPPostEncoder
postEncoder
=
new
HTTPPostEncoder
();
CriteriaSet
criteriaSet
=
new
CriteriaSet
();
postEncoder
.
setHttpServletResponse
(
response
);
criteriaSet
.
add
(
new
SignatureSigningConfigurationCriterion
(
ssConfig
));
MessageContext
<
SAMLObject
>
messageContext
=
new
MessageContext
<
SAMLObject
>();
SAMLMetadataSignatureSigningParametersResolver
smsspr
=
new
SAMLMetadataSignatureSigningParametersResolver
();
SignatureSigningParameters
ssp
;
try
{
try
{
s
sp
=
smsspr
.
resolveSingle
(
criteriaSet
);
s
amlResponse
.
getEncryptedAssertions
().
add
(
encryptAssertion
(
assertion
,
spMetadata
,
messageContext
)
);
}
catch
(
Resolver
Exception
e
)
{
}
catch
(
SamlAuthentication
Exception
e
)
{
throw
new
ServletException
(
e
);
throw
new
ServletException
(
e
);
}
}
logger
.
debug
(
"Resolved algo {} for signing"
,
ssp
.
getSignatureAlgorithm
());
// samlResponse.getAssertions().add(assertion);
SecurityParametersContext
securityContext
=
new
SecurityParametersContext
();
securityContext
.
setSignatureSigningParameters
(
ssp
);
HTTPPostEncoder
postEncoder
=
new
HTTPPostEncoder
();
postEncoder
.
setHttpServletResponse
(
response
);
MessageContext
<
SAMLObject
>
messageContext
=
new
MessageContext
<
SAMLObject
>();
messageContext
.
setMessage
(
samlResponse
);
messageContext
.
setMessage
(
samlResponse
);
/*
* signing response
*/
messageContext
.
addSubcontext
(
securityContext
);
messageContext
.
addSubcontext
(
securityContext
);
SAMLPeerEntityContext
entityContext
=
new
SAMLPeerEntityContext
();
SAMLPeerEntityContext
entityContext
=
new
SAMLPeerEntityContext
();
...
@@ -262,4 +284,97 @@ public class Saml2IdpRedirectResponseHandler {
...
@@ -262,4 +284,97 @@ public class Saml2IdpRedirectResponseHandler {
return
attribute
;
return
attribute
;
}
}
private
SecurityParametersContext
buildSecurityContext
(
SamlAAConfigurationEntity
aaConfig
)
throws
ServletException
{
PrivateKey
privateKey
;
X509Certificate
publicKey
;
try
{
privateKey
=
cryptoHelper
.
getPrivateKey
(
aaConfig
.
getPrivateKey
());
publicKey
=
cryptoHelper
.
getCertificate
(
aaConfig
.
getCertificate
());
}
catch
(
IOException
e
)
{
throw
new
ServletException
(
"Private key is not set up properly"
,
e
);
}
BasicX509Credential
credential
=
new
BasicX509Credential
(
publicKey
,
privateKey
);
List
<
Credential
>
credentialList
=
new
ArrayList
<
Credential
>();
credentialList
.
add
(
credential
);
BasicSignatureSigningConfiguration
ssConfig
=
DefaultSecurityConfigurationBootstrap
.
buildDefaultSignatureSigningConfiguration
();
ssConfig
.
setSigningCredentials
(
credentialList
);
CriteriaSet
criteriaSet
=
new
CriteriaSet
();
criteriaSet
.
add
(
new
SignatureSigningConfigurationCriterion
(
ssConfig
));
SAMLMetadataSignatureSigningParametersResolver
smsspr
=
new
SAMLMetadataSignatureSigningParametersResolver
();
SignatureSigningParameters
ssp
;
try
{
ssp
=
smsspr
.
resolveSingle
(
criteriaSet
);
}
catch
(
ResolverException
e
)
{
throw
new
ServletException
(
e
);
}
logger
.
debug
(
"Resolved algo {} for signing"
,
ssp
.
getSignatureAlgorithm
());
SecurityParametersContext
securityContext
=
new
SecurityParametersContext
();
securityContext
.
setSignatureSigningParameters
(
ssp
);
return
securityContext
;
}
private
EncryptedAssertion
encryptAssertion
(
Assertion
assertion
,
SamlSpMetadataEntity
spMetadata
,
MessageContext
<?>
messageContext
)
throws
SamlAuthenticationException
{
EntityDescriptor
ed
=
samlHelper
.
unmarshal
(
spMetadata
.
getEntityDescriptor
(),
EntityDescriptor
.
class
);
KeyDescriptor
keyDescriptor
=
null
;
SPSSODescriptor
spsso
=
ed
.
getSPSSODescriptor
(
SAMLConstants
.
SAML20P_NS
);
for
(
KeyDescriptor
kd
:
spsso
.
getKeyDescriptors
())
{
if
(
kd
.
getUse
()
==
null
||
kd
.
getUse
().
equals
(
UsageType
.
ENCRYPTION
))
{
keyDescriptor
=
kd
;
break
;
}
}
if
(
keyDescriptor
==
null
)
{
return
null
;
}
KeyInfo
keyInfo
=
keyDescriptor
.
getKeyInfo
();
X509Data
x509Data
=
keyInfo
.
getX509Datas
().
get
(
0
);
org
.
opensaml
.
xmlsec
.
signature
.
X509Certificate
x509cert
=
x509Data
.
getX509Certificates
().
get
(
0
);
String
cert
=
x509cert
.
getValue
();
Encrypter
enc
=
buildEncrypter
(
cert
,
messageContext
,
spMetadata
.
getEntityId
());
try
{
return
enc
.
encrypt
(
assertion
);
}
catch
(
EncryptionException
e
)
{
throw
new
SamlAuthenticationException
(
"exception"
,
e
);
}
}
private
Encrypter
buildEncrypter
(
String
cert
,
MessageContext
<?>
messageContext
,
String
spEntityId
)
throws
SamlAuthenticationException
{
try
{
byte
[]
decodedCert
=
Base64
.
decodeBase64
(
cert
);
CertificateFactory
certFactory
=
CertificateFactory
.
getInstance
(
"X.509"
);
InputStream
in
=
new
ByteArrayInputStream
(
decodedCert
);
X509Certificate
certificate
=
(
X509Certificate
)
certFactory
.
generateCertificate
(
in
);
BasicCredential
encryptCredential
=
new
BasicCredential
(
certificate
.
getPublicKey
());
final
BasicKeyInfoGeneratorFactory
generator
=
new
BasicKeyInfoGeneratorFactory
();
generator
.
setEmitPublicKeyValue
(
true
);
EncryptionParameters
encParams
=
new
EncryptionParameters
();
encParams
.
setDataEncryptionAlgorithm
(
EncryptionConstants
.
ALGO_ID_BLOCKCIPHER_AES128
);
encParams
.
setDataKeyInfoGenerator
(
generator
.
newInstance
());
encParams
.
setKeyTransportEncryptionAlgorithm
(
EncryptionConstants
.
ALGO_ID_KEYTRANSPORT_RSAOAEP
);
encParams
.
setKeyTransportEncryptionCredential
(
encryptCredential
);
encParams
.
setKeyTransportKeyInfoGenerator
(
generator
.
newInstance
());
messageContext
.
getSubcontext
(
EncryptionContext
.
class
,
true
)
.
setAssertionEncryptionParameters
(
encParams
);
Encrypter
encrypter
=
new
Encrypter
(
new
DataEncryptionParameters
(
encParams
),
new
KeyEncryptionParameters
(
encParams
,
spEntityId
));
return
encrypter
;
}
catch
(
CertificateException
e
)
{
throw
new
SamlAuthenticationException
(
"Certificate cannot be read"
,
e
);
}
}
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment