Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
dariah
dariahsp
Commits
fd711f07
Commit
fd711f07
authored
Apr 13, 2017
by
Gradl, Tobias
Browse files
720: Implement attribute checker
Task-Url:
https://minfba.de.dariah.eu/mantisbt/view.php?id=720
parent
0130d5f6
Changes
9
Hide whitespace changes
Inline
Side-by-side
dariahsp-core/src/main/java/eu/dariah/de/dariahsp/saml/SAMLAuthenticationProvider.java
View file @
fd711f07
...
...
@@ -17,7 +17,7 @@ public class SAMLAuthenticationProvider extends org.springframework.security.sam
@Override
protected
Object
getUserDetails
(
SAMLCredential
credential
)
{
if
(
this
.
getAttributeAggregationService
()!=
null
)
{
this
.
getAttributeAggregationService
().
aggregateIfRequired
(
credential
);
credential
=
this
.
getAttributeAggregationService
().
aggregateIfRequired
(
credential
);
}
return
super
.
getUserDetails
(
credential
);
}
...
...
dariahsp-core/src/main/java/eu/dariah/de/dariahsp/saml/attributequery/SAMLAttributeAggregationService.java
View file @
fd711f07
package
eu.dariah.de.dariahsp.saml.attributequery
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.opensaml.saml2.core.Attribute
;
import
org.slf4j.Logger
;
...
...
@@ -14,6 +13,7 @@ import eu.dariah.de.dariahsp.saml.attributequery.options.SAMLAttributeGroup;
import
eu.dariah.de.dariahsp.saml.attributequery.options.SAMLAttributeQueryExclusionOptions
;
import
eu.dariah.de.dariahsp.saml.attributequery.options.SAMLAttributeQueryOptions
;
import
eu.dariah.de.dariahsp.saml.attributequery.options.SAMLRequiredAttributes
;
import
eu.dariah.de.dariahsp.saml.model.SAMLAggregatedCredential
;
public
class
SAMLAttributeAggregationService
{
...
...
@@ -37,10 +37,10 @@ public class SAMLAttributeAggregationService {
}
public
void
aggregateIfRequired
(
SAMLCredential
credential
)
{
public
SAMLCredential
aggregateIfRequired
(
SAMLCredential
credential
)
{
if
(!
queryOptions
.
isPerformAggregation
())
{
return
;
return
credential
;
}
boolean
queryRequired
=
true
;
...
...
@@ -60,15 +60,16 @@ public class SAMLAttributeAggregationService {
if
(
queryRequired
)
{
try
{
List
<
Attribute
>
queryReturnedAttributes
=
attributeQuery
.
queryAttributes
(
credential
,
queryOptions
);;
List
<
Attribute
>
queryReturnedAttributes
=
attributeQuery
.
queryAttributes
(
credential
,
queryOptions
);;
this
.
logAttributes
(
queryReturnedAttributes
,
" attribute(s) resolved by attribute query "
);
aggregateAttributes
(
credential
,
queryReturnedAttributes
);
return
new
SAMLAggregatedCredential
(
credential
,
queryReturnedAttributes
);
}
catch
(
Exception
e
)
{
logger
.
error
(
"An exception occured while attempting to permorm attribute query"
,
e
);
}
}
return
credential
;
}
private
void
logAttributes
(
List
<
Attribute
>
attributes
,
String
message
)
{
...
...
@@ -127,30 +128,4 @@ public class SAMLAttributeAggregationService {
}
return
true
;
}
private
void
aggregateAttributes
(
SAMLCredential
credential
,
List
<
Attribute
>
queriedAttributes
)
{
if
(
queriedAttributes
==
null
||
queriedAttributes
.
size
()==
0
)
{
return
;
}
// Take care of duplicates
List
<
Attribute
>
replacedAttributes
=
new
ArrayList
<
Attribute
>();
for
(
Attribute
queriedA
:
credential
.
getAttributes
())
{
for
(
Attribute
originalA
:
credential
.
getAttributes
())
{
if
(
originalA
.
getFriendlyName
().
equalsIgnoreCase
(
queriedA
.
getFriendlyName
())
||
originalA
.
getName
().
equalsIgnoreCase
(
queriedA
.
getName
()))
{
replacedAttributes
.
add
(
originalA
);
break
;
}
}
}
/*for (Attribute replacedA : replacedAttributes) {
credential.getAttributes().remove(replacedA);
}*/
credential
=
new
SAMLCredential
(
credential
.
getNameID
(),
credential
.
getAuthenticationAssertion
(),
credential
.
getRemoteEntityID
(),
credential
.
getRelayState
(),
queriedAttributes
,
credential
.
getLocalEntityID
());
}
}
dariahsp-core/src/main/java/eu/dariah/de/dariahsp/saml/attributequery/SAMLAttributeQueryImpl.java
View file @
fd711f07
...
...
@@ -131,7 +131,7 @@ public class SAMLAttributeQueryImpl extends WebSSOProfileConsumerImpl implements
getAttributeQueryResponse
(
context
);
// Unwrap and process response from IDP
List
<
Attribute
>
attrs
=
processResponse
(
context
,
query
);
List
<
Attribute
>
attrs
=
processResponse
(
context
,
query
,
options
);
logger
.
debug
(
"SAML AttributeQuery resulted in the retrieval of {} attributes"
,
attrs
.
size
());
...
...
@@ -164,7 +164,7 @@ public class SAMLAttributeQueryImpl extends WebSSOProfileConsumerImpl implements
}
private
List
<
Attribute
>
processResponse
(
SAMLMessageContext
context
,
AttributeQuery
query
)
throws
SAMLException
,
SecurityException
,
ValidationException
,
DecryptionException
{
private
List
<
Attribute
>
processResponse
(
SAMLMessageContext
context
,
AttributeQuery
query
,
SAMLAttributeQueryOptions
options
)
throws
SAMLException
,
SecurityException
,
ValidationException
,
DecryptionException
{
SAMLObject
message
=
context
.
getInboundSAMLMessage
();
...
...
@@ -216,6 +216,8 @@ public class SAMLAttributeQueryImpl extends WebSSOProfileConsumerImpl implements
// Verify assertions
List
<
Assertion
>
assertionList
=
response
.
getAssertions
();
List
<
EncryptedAssertion
>
encryptedAssertionList
=
response
.
getEncryptedAssertions
();
for
(
EncryptedAssertion
ea
:
encryptedAssertionList
)
{
try
{
...
...
@@ -224,7 +226,7 @@ public class SAMLAttributeQueryImpl extends WebSSOProfileConsumerImpl implements
Assertion
decryptedAssertion
=
context
.
getLocalDecrypter
().
decrypt
(
ea
);
assertionList
.
add
(
decryptedAssertion
);
}
catch
(
DecryptionException
e
)
{
logger
.
debug
(
"Decryption of received assertion failed, assertion will be skipped"
,
e
);
logger
.
warn
(
"Decryption of received assertion failed, assertion will be skipped"
,
e
);
}
}
...
...
@@ -232,24 +234,24 @@ public class SAMLAttributeQueryImpl extends WebSSOProfileConsumerImpl implements
for
(
Assertion
a
:
assertionList
)
{
try
{
// Verify that the assertion is valid
verifyAssertion
(
a
,
query
,
context
);
verifyAssertion
(
a
,
query
,
context
,
options
);
}
catch
(
AuthenticationException
e
)
{
logger
.
debug
(
"Validation of received assertion failed, assertion will be skipped"
,
e
);
logger
.
warn
(
"Validation of received assertion failed, assertion will be skipped"
,
e
);
continue
;
}
catch
(
SAMLRuntimeException
e
)
{
logger
.
debug
(
"Validation of received assertion failed, assertion will be skipped"
,
e
);
logger
.
warn
(
"Validation of received assertion failed, assertion will be skipped"
,
e
);
continue
;
}
catch
(
SAMLException
e
)
{
logger
.
debug
(
"Validation of received assertion failed, assertion will be skipped"
,
e
);
logger
.
warn
(
"Validation of received assertion failed, assertion will be skipped"
,
e
);
continue
;
}
catch
(
org
.
opensaml
.
xml
.
security
.
SecurityException
e
)
{
logger
.
debug
(
"Validation of received assertion failed, assertion will be skipped"
,
e
);
logger
.
warn
(
"Validation of received assertion failed, assertion will be skipped"
,
e
);
continue
;
}
catch
(
ValidationException
e
)
{
logger
.
debug
(
"Validation of received assertion failed, assertion will be skipped"
,
e
);
logger
.
warn
(
"Validation of received assertion failed, assertion will be skipped"
,
e
);
continue
;
}
catch
(
DecryptionException
e
)
{
logger
.
debug
(
"Validation of received assertion failed, assertion will be skipped"
,
e
);
logger
.
warn
(
"Validation of received assertion failed, assertion will be skipped"
,
e
);
continue
;
}
...
...
@@ -274,7 +276,7 @@ public class SAMLAttributeQueryImpl extends WebSSOProfileConsumerImpl implements
return
attributes
;
}
protected
void
verifyAssertion
(
Assertion
assertion
,
AttributeQuery
query
,
SAMLMessageContext
context
)
throws
AuthenticationException
,
SAMLException
,
org
.
opensaml
.
xml
.
security
.
SecurityException
,
ValidationException
,
DecryptionException
{
protected
void
verifyAssertion
(
Assertion
assertion
,
AttributeQuery
query
,
SAMLMessageContext
context
,
SAMLAttributeQueryOptions
options
)
throws
AuthenticationException
,
SAMLException
,
org
.
opensaml
.
xml
.
security
.
SecurityException
,
ValidationException
,
DecryptionException
{
// Verify storage time skew
if
(!
isDateTimeSkewValid
(
getMaxAssertionTime
(),
assertion
.
getIssueInstant
()))
{
...
...
@@ -287,8 +289,13 @@ public class SAMLAttributeQueryImpl extends WebSSOProfileConsumerImpl implements
// Verify validity of storage
// Advice is ignored, core 574
verifyIssuer
(
assertion
.
getIssuer
(),
context
);
verifyAssertionSignature
(
assertion
.
getSignature
(),
context
);
// If a signature is presented it must be verified
// otherwise we depend on the option
if
(
options
.
isSignedAssertionRequired
()
||
assertion
.
getSignature
()!=
null
)
{
verifyAssertionSignature
(
assertion
.
getSignature
(),
context
);
}
// Check subject
if
(
assertion
.
getSubject
()
!=
null
)
{
verifySubject
(
assertion
.
getSubject
(),
query
,
context
);
...
...
dariahsp-core/src/main/java/eu/dariah/de/dariahsp/saml/attributequery/options/SAMLAttributeQueryOptions.java
View file @
fd711f07
package
eu.dariah.de.dariahsp.saml.attributequery.options
;
import
java.io.IOException
;
import
java.io.Serializable
;
import
java.util.List
;
import
org.opensaml.saml2.core.impl.AttributeImpl
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.fasterxml.jackson.core.JsonParseException
;
import
com.fasterxml.jackson.core.JsonProcessingException
;
import
com.fasterxml.jackson.databind.JsonMappingException
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
eu.dariah.de.dariahsp.saml.SAMLAttribute
;
...
...
@@ -23,30 +19,41 @@ public class SAMLAttributeQueryOptions implements Serializable, Cloneable {
private
String
attributeAuthorityIDP
;
private
boolean
queryByNameID
=
true
;
private
SAMLRequiredAttributesList
requiredAttributesList
;
private
boolean
performAggregation
=
true
;
private
boolean
signedAssertionRequired
=
true
;
private
SAMLRequiredAttributesList
requiredAttributesList
;
private
List
<
SAMLAttributeQueryExclusionOptions
>
exclusionOptions
;
private
SAMLAttribute
queryAttribute
;
public
SAMLAttribute
getQueryAttribute
()
{
return
queryAttribute
;
}
public
void
setQueryAttribute
(
SAMLAttribute
queryAttribute
)
{
this
.
queryAttribute
=
queryAttribute
;
}
private
SAMLAttribute
queryAttribute
;
public
boolean
isSignedAssertionRequired
()
{
return
signedAssertionRequired
;
}
public
void
setSignedAssertionRequired
(
boolean
signedAssertionRequired
)
{
this
.
signedAssertionRequired
=
signedAssertionRequired
;
}
public
String
getAttributeAuthorityIDP
()
{
return
attributeAuthorityIDP
;
}
public
void
setAttributeAuthorityIDP
(
String
attributeAuthorityIDP
)
{
this
.
attributeAuthorityIDP
=
attributeAuthorityIDP
;
}
public
boolean
isQueryByNameID
()
{
return
queryByNameID
;
}
public
void
setQueryByNameID
(
boolean
queryByNameID
)
{
this
.
queryByNameID
=
queryByNameID
;
}
public
SAMLRequiredAttributesList
getRequiredAttributesList
()
{
return
requiredAttributesList
;
}
public
void
setRequiredAttributesList
(
SAMLRequiredAttributesList
requiredAttributesList
)
{
this
.
requiredAttributesList
=
requiredAttributesList
;
}
public
boolean
isPerformAggregation
()
{
return
performAggregation
;
}
public
void
setPerformAggregation
(
boolean
performAggregation
)
{
this
.
performAggregation
=
performAggregation
;
}
public
List
<
SAMLAttributeQueryExclusionOptions
>
getExclusionOptions
()
{
return
exclusionOptions
;
}
public
void
setExclusionOptions
(
List
<
SAMLAttributeQueryExclusionOptions
>
exclusionOptions
)
{
this
.
exclusionOptions
=
exclusionOptions
;
}
public
SAMLAttributeQueryOptions
(
ObjectMapper
objectMapper
)
{
this
.
objectMapper
=
objectMapper
;
}
public
SAMLAttribute
getQueryAttribute
()
{
return
queryAttribute
;
}
public
void
setQueryAttribute
(
SAMLAttribute
queryAttribute
)
{
this
.
queryAttribute
=
queryAttribute
;
}
public
String
getQueryAttributeAsJson
()
{
try
{
return
queryAttribute
==
null
?
null
:
objectMapper
.
writeValueAsString
(
queryAttribute
);
...
...
@@ -65,23 +72,4 @@ public class SAMLAttributeQueryOptions implements Serializable, Cloneable {
logger
.
error
(
"Failed to deserialize SAML Attribute"
,
e
);
}
}
public
String
getAttributeAuthorityIDP
()
{
return
attributeAuthorityIDP
;
}
public
void
setAttributeAuthorityIDP
(
String
attributeAuthorityIDP
)
{
this
.
attributeAuthorityIDP
=
attributeAuthorityIDP
;
}
public
boolean
isQueryByNameID
()
{
return
queryByNameID
;
}
public
void
setQueryByNameID
(
boolean
queryByNameID
)
{
this
.
queryByNameID
=
queryByNameID
;
}
public
SAMLRequiredAttributesList
getRequiredAttributesList
()
{
return
requiredAttributesList
;
}
public
void
setRequiredAttributesList
(
SAMLRequiredAttributesList
requiredAttributesList
)
{
this
.
requiredAttributesList
=
requiredAttributesList
;
}
public
boolean
isPerformAggregation
()
{
return
performAggregation
;
}
public
void
setPerformAggregation
(
boolean
performAggregation
)
{
this
.
performAggregation
=
performAggregation
;
}
public
List
<
SAMLAttributeQueryExclusionOptions
>
getExclusionOptions
()
{
return
exclusionOptions
;
}
public
void
setExclusionOptions
(
List
<
SAMLAttributeQueryExclusionOptions
>
exclusionOptions
)
{
this
.
exclusionOptions
=
exclusionOptions
;
}
}
\ No newline at end of file
dariahsp-sample/src/main/java/eu/dariah/de/dariahsp/sample/exceptions/SampleExceptionController.java
View file @
fd711f07
...
...
@@ -34,6 +34,7 @@ public class SampleExceptionController {
public
ModelAndView
renderErrorPage
(
HttpServletRequest
httpRequest
)
{
ModelAndView
errorPage
=
new
ModelAndView
(
"error"
);
String
errorMsg
=
""
;
int
httpErrorCode
=
getErrorCode
(
httpRequest
);
switch
(
httpErrorCode
)
{
...
...
@@ -70,7 +71,7 @@ public class SampleExceptionController {
}
errorPage
.
addObject
(
"errorMsg"
,
errorMsg
);
errorPage
.
addObject
(
"exception"
,
this
.
getException
(
httpRequest
));
return
errorPage
;
...
...
@@ -83,6 +84,13 @@ public class SampleExceptionController {
}
}
private
Exception
getException
(
HttpServletRequest
httpRequest
)
{
if
(
httpRequest
.
getAttribute
(
"javax.servlet.error.exception"
)==
null
)
{
return
null
;
}
return
(
Exception
)
httpRequest
.
getAttribute
(
"javax.servlet.error.exception"
);
}
private
int
getErrorCode
(
HttpServletRequest
httpRequest
)
{
if
(
httpRequest
.
getAttribute
(
"javax.servlet.error.status_code"
)==
null
)
{
return
-
1
;
...
...
dariahsp-sample/src/main/resources/dariahsp.yml
View file @
fd711f07
...
...
@@ -29,7 +29,7 @@ auth:
#requireArtifactResolveSigned: false
#requireLogoutRequestSigned: false
#requireLogoutResponseSigned: false
#
requireAttributeQuerySigned:
tru
e
requireAttributeQuerySigned
:
fals
e
maxAuthAge
:
-1
# in seconds
signMetadata
:
true
#signingAlgorithm : http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
...
...
@@ -49,6 +49,7 @@ auth:
urls
:
[
"
https://ldap-dariah-clone.esc.rzg.mpg.de/idp/shibboleth"
,
"
https://idp.de.dariah.eu/idp/shibboleth"
]
assumeAttributesComplete
:
false
queryIdp
:
https://ldap-dariah-clone.esc.rzg.mpg.de/idp/shibboleth
#queryIdp: https://idp.de.dariah.eu/idp/shibboleth
queryByNameID
:
false
queryAttribute
:
friendlyName
:
eduPersonPrincipalName
...
...
dariahsp-sample/src/main/resources/spring/security/security-context-common.xml
View file @
fd711f07
...
...
@@ -9,7 +9,7 @@
<!-- Enable auto-wiring -->
<context:annotation-config/>
<security:global-method-security
pre-post-annotations=
"enabled"
secured-annotations=
"enabled"
/>
<security:global-method-security
access-decision-manager-ref=
"accessDecisionManager"
pre-post-annotations=
"enabled"
secured-annotations=
"enabled"
/>
<!-- Unsecured pages and prefixes -->
<security:http
security=
"none"
pattern=
"/favicon.ico"
/>
...
...
@@ -18,6 +18,7 @@
<security:http
entry-point-ref=
"securityEntryPoint"
use-expressions=
"false"
access-decision-manager-ref=
"accessDecisionManager"
>
<security:intercept-url
pattern=
"/user/**"
access=
"IS_AUTHENTICATED_FULLY"
/>
<security:intercept-url
pattern=
"/protected/**"
access=
"IS_AUTHENTICATED_FULLY"
/>
<security:intercept-url
pattern=
"/overprotected/**"
access=
"ROLE_UBERROLE"
/>
...
...
dariahsp-sample/src/main/resources/spring/security/security-context-saml.xml
View file @
fd711f07
...
...
@@ -207,6 +207,7 @@
<bean
id=
"attributeQueryOptions"
class=
"eu.dariah.de.dariahsp.saml.attributequery.options.SAMLAttributeQueryOptions"
>
<constructor-arg
ref=
"objectMapper"
/>
<property
name=
"performAggregation"
value=
"${auth.saml.sp.attributeQuery.enabled:false}"
/>
<property
name=
"signedAssertionRequired"
value=
"${auth.saml.sp.requireAttributeQuerySigned:true}"
/>
<property
name=
"attributeAuthorityIDP"
value=
"${auth.saml.sp.attributeQuery.queryIdp:#{null}}"
/>
<property
name=
"queryByNameID"
value=
"${auth.saml.sp.attributeQuery.queryByNameID:false}"
/>
<property
name=
"queryAttributeAsJson"
value=
"${auth.saml.sp.attributeQuery.queryAttribute:#{null}}"
/>
...
...
@@ -290,12 +291,12 @@
<!-- SAML 2.0 WebSSO Assertion Consumer -->
<bean
id=
"webSSOprofileConsumer"
class=
"org.springframework.security.saml.websso.WebSSOProfileConsumerImpl"
>
<property
name=
"maxAuthenticationAge"
value=
"${auth.maxAuthAge:7200}"
/>
<property
name=
"maxAuthenticationAge"
value=
"${auth.
saml.sp.
maxAuthAge:7200}"
/>
</bean>
<!-- SAML 2.0 Holder-of-Key WebSSO Assertion Consumer -->
<bean
id=
"hokWebSSOprofileConsumer"
class=
"org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl"
>
<property
name=
"maxAuthenticationAge"
value=
"${auth.maxAuthAge:7200}"
/>
<property
name=
"maxAuthenticationAge"
value=
"${auth.
saml.sp.
maxAuthAge:7200}"
/>
</bean>
<!-- SAML 2.0 Web SSO profile -->
...
...
dariahsp-sample/src/main/webapp/WEB-INF/view/jsp/error.jsp
View file @
fd711f07
...
...
@@ -29,6 +29,14 @@
<p>
${errorMsg}
</p>
<pre>
Failed URL: ${url}
Exception: ${exception.message}
<c:forEach
items=
"
${
exception
.
stackTrace
}
"
var=
"ste"
>
${ste}
</c:forEach>
</pre>
</div>
</div>
</div>
...
...
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