Skip to content
GitLab
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
250d3274
Commit
250d3274
authored
Nov 09, 2020
by
Gradl, Tobias
Browse files
10: Work with SAML attributes
Task-Url:
#10
parent
e8e57493
Pipeline
#17793
passed with stage
in 1 minute and 57 seconds
Changes
9
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
dariahsp-core/src/main/java/eu/dariah/de/dariahsp/Constants.java
View file @
250d3274
package
eu.dariah.de.dariahsp
;
public
class
Constants
{
public
enum
AUTHENTICATION_STAGE
{
AUTHENTICATION
,
ATTRIBUTES
}
public
enum
REQUIRED_ATTRIBUTE_CHECKLOGIC
{
AND
,
OR
,
OPTIONAL
}
public
final
static
String
URN_SAML2_NAMEID_TRANSIENT
=
"urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
;
...
...
dariahsp-core/src/main/java/eu/dariah/de/dariahsp/config/ConditionalAttributeGroup.java
View file @
250d3274
...
...
@@ -10,4 +10,8 @@ import lombok.Setter;
public
class
ConditionalAttributeGroup
{
private
REQUIRED_ATTRIBUTE_CHECKLOGIC
check
;
private
List
<
Attribute
>
attributes
;
public
boolean
isRequired
()
{
return
check
.
equals
(
REQUIRED_ATTRIBUTE_CHECKLOGIC
.
AND
)
||
check
.
equals
(
REQUIRED_ATTRIBUTE_CHECKLOGIC
.
OR
);
}
}
dariahsp-core/src/main/java/eu/dariah/de/dariahsp/config/ConditionalAttributeSet.java
deleted
100644 → 0
View file @
e8e57493
package
eu.dariah.de.dariahsp.config
;
import
java.util.List
;
import
eu.dariah.de.dariahsp.Constants.AUTHENTICATION_STAGE
;
import
lombok.Getter
;
import
lombok.Setter
;
@Getter
@Setter
public
class
ConditionalAttributeSet
{
private
boolean
required
;
private
AUTHENTICATION_STAGE
stage
;
private
List
<
ConditionalAttributeGroup
>
attributeGroup
;
}
dariahsp-core/src/main/java/eu/dariah/de/dariahsp/config/model/SamlSpConfigProperties.java
View file @
250d3274
...
...
@@ -14,7 +14,6 @@ import org.pac4j.saml.util.SAML2HttpClientBuilder;
import
eu.dariah.de.dariahsp.config.Attribute
;
import
eu.dariah.de.dariahsp.config.ConditionalAttributeGroup
;
import
eu.dariah.de.dariahsp.config.ConditionalAttributeSet
;
import
lombok.Getter
;
import
lombok.Setter
;
...
...
@@ -34,7 +33,8 @@ public class SamlSpConfigProperties {
private
boolean
logoutRequestSigned
=
false
;
private
boolean
wantsAssertionsSigned
=
true
;
private
boolean
wantsResponsesSigned
=
true
;
private
List
<
ConditionalAttributeSet
>
attributeConfig
;
private
String
attributesIncompleteRedirectUrl
;
private
List
<
ConditionalAttributeGroup
>
attributeGroups
;
// ------------------------------------------
// Custom getters for complex default values
...
...
@@ -57,11 +57,18 @@ public class SamlSpConfigProperties {
return
httpClient
.
build
();
}
public
List
<
ConditionalAttributeGroup
>
getRequiredAttributeGroups
()
{
if
(
attributeGroups
!=
null
)
{
return
attributeGroups
.
stream
()
.
filter
(
ConditionalAttributeGroup:
:
isRequired
)
.
collect
(
Collectors
.
toList
());
}
return
new
ArrayList
<>(
0
);
}
public
Attribute
getAttributeByMappedName
(
String
mappedName
)
{
if
(
attributeConfig
!=
null
)
{
return
attributeConfig
.
stream
()
.
map
(
ConditionalAttributeSet:
:
getAttributeGroup
)
.
flatMap
(
Collection:
:
stream
)
if
(
attributeGroups
!=
null
)
{
return
attributeGroups
.
stream
()
.
map
(
ConditionalAttributeGroup:
:
getAttributes
)
.
flatMap
(
Collection:
:
stream
)
.
filter
(
a
->
a
.
getMappedAttribute
().
equals
(
mappedName
))
...
...
@@ -73,10 +80,8 @@ public class SamlSpConfigProperties {
public
Map
<
String
,
String
>
getMappedAttributesNameMap
()
{
Map
<
String
,
String
>
result
=
new
HashMap
<>();
if
(
attributeConfig
!=
null
)
{
return
attributeConfig
.
stream
()
.
map
(
ConditionalAttributeSet:
:
getAttributeGroup
)
.
flatMap
(
Collection:
:
stream
)
if
(
attributeGroups
!=
null
)
{
return
attributeGroups
.
stream
()
.
map
(
ConditionalAttributeGroup:
:
getAttributes
)
.
flatMap
(
Collection:
:
stream
)
.
filter
(
a
->
a
.
getMappedAttribute
()!=
null
)
...
...
dariahsp-core/src/main/java/eu/dariah/de/dariahsp/error/RequiredAttributesException.java
0 → 100644
View file @
250d3274
package
eu.dariah.de.dariahsp.error
;
public
class
RequiredAttributesException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
613886651543572109L
;
public
RequiredAttributesException
(
final
String
message
)
{
super
(
message
);
}
public
RequiredAttributesException
(
final
Throwable
t
)
{
super
(
t
);
}
public
RequiredAttributesException
(
String
message
,
Throwable
t
)
{
super
(
message
,
t
);
}
}
dariahsp-core/src/main/java/eu/dariah/de/dariahsp/saml/SAML2RequiredAttributeAuthenticator.java
View file @
250d3274
package
eu.dariah.de.dariahsp.saml
;
import
java.util.List
;
import
java.util.Map
;
import
org.pac4j.core.context.WebContext
;
import
org.pac4j.core.exception.CredentialsException
;
import
org.pac4j.saml.credentials.SAML2Credentials
;
import
org.pac4j.saml.credentials.SAML2Credentials.SAMLAttribute
;
import
org.pac4j.saml.credentials.authenticator.SAML2Authenticator
;
import
eu.dariah.de.dariahsp.Constants.REQUIRED_ATTRIBUTE_CHECKLOGIC
;
import
eu.dariah.de.dariahsp.config.Attribute
;
import
eu.dariah.de.dariahsp.config.ConditionalAttributeGroup
;
import
eu.dariah.de.dariahsp.config.model.SamlSpConfigProperties
;
import
eu.dariah.de.dariahsp.error.RequiredAttributesException
;
import
lombok.extern.slf4j.Slf4j
;
@Slf4j
...
...
@@ -28,9 +35,51 @@ public class SAML2RequiredAttributeAuthenticator extends SAML2Authenticator {
public
void
validate
(
final
SAML2Credentials
credentials
,
final
WebContext
context
)
{
super
.
validate
(
credentials
,
context
);
log
.
debug
(
"Validated profile: {}"
,
credentials
.
getUserProfile
());
// TODO: Perform required attributes checking
boolean
hasAllAttributes
=
this
.
hasAllRequiredAttributes
(
credentials
.
getAttributes
());
if
(
hasAllAttributes
)
{
log
.
debug
(
"Profile validated: {}"
,
credentials
.
getUserProfile
());
}
else
{
log
.
warn
(
"Profile misses required attributes: {}"
,
credentials
.
getUserProfile
());
throw
new
RequiredAttributesException
(
"Profile missing required attributes"
);
}
}
public
boolean
hasAllRequiredAttributes
(
List
<
SAMLAttribute
>
providedAttributes
)
{
List
<
ConditionalAttributeGroup
>
reqAttrGroups
=
spConfigProperties
.
getRequiredAttributeGroups
();
if
(
reqAttrGroups
.
isEmpty
())
{
return
true
;
}
else
if
(
providedAttributes
==
null
||
providedAttributes
.
isEmpty
())
{
return
false
;
}
for
(
ConditionalAttributeGroup
attrGroup
:
reqAttrGroups
)
{
boolean
orMatch
=
false
;
if
(
attrGroup
.
getAttributes
()!=
null
)
{
for
(
Attribute
reqAttr
:
attrGroup
.
getAttributes
())
{
boolean
match
=
false
;
for
(
SAMLAttribute
attr
:
providedAttributes
)
{
if
(
attr
.
getNameFormat
().
equals
(
reqAttr
.
getNameFormat
())
&&
attr
.
getName
().
equals
(
reqAttr
.
getName
())
&&
(
(
reqAttr
.
getValue
()!=
null
&&
attr
.
getAttributeValues
().
contains
(
reqAttr
.
getValue
()))
||
reqAttr
.
getValue
()==
null
)
)
{
match
=
true
;
orMatch
=
true
;
break
;
}
}
// TODO: Value checks
if
(!
match
&&
attrGroup
.
getCheck
().
equals
(
REQUIRED_ATTRIBUTE_CHECKLOGIC
.
AND
))
{
return
false
;
}
if
(
orMatch
&&
attrGroup
.
getCheck
().
equals
(
REQUIRED_ATTRIBUTE_CHECKLOGIC
.
OR
))
{
break
;
}
}
}
if
(!
orMatch
&&
attrGroup
.
getCheck
().
equals
(
REQUIRED_ATTRIBUTE_CHECKLOGIC
.
OR
))
{
return
false
;
}
}
return
true
;
}
}
dariahsp-core/src/main/resources/config.sample.yml
View file @
250d3274
...
...
@@ -59,43 +59,31 @@ auth:
wantsAssertionsSigned
:
true
wantsResponsesSigned
:
false
httpClientTimoutMs
:
2000
attributeConfig
:
-
stage
:
ATTRIBUTES
required
:
true
attributeGroup
:
-
check
:
OR
attributes
:
-
friendlyName
:
dariahTermsOfUse
name
:
urn:oid:1.3.6.1.4.1.10126.1.52.4.15
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
value
:
Terms_of_Use_v5.pdf
-
friendlyName
:
dariahTermsOfUse
name
:
urn:oid:1.3.6.1.4.1.10126.1.52.4.15
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
value
:
foobar-service-agreement_version1.pdf
-
stage
:
AUTHENTICATION
required
:
true
attributeGroup
:
-
check
:
AND
attributes
:
-
friendlyName
:
eduPersonPrincipalName
mappedAttribute
:
id
name
:
urn:oid:1.3.6.1.4.1.5923.1.1.1.6
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
stage
:
AUTHENTICATION
required
:
false
attributeGroup
:
-
check
:
OPTIONAL
attributes
:
-
friendlyName
:
mail
mappedAttribute
:
email
name
:
urn:oid:0.9.2342.19200300.100.1.3
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
friendlyName
:
displayName
mappedAttribute
:
display_name
name
:
urn:oid:2.16.840.1.113730.3.1.241
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
friendlyName
:
isMemberOf
mappedAttribute
:
externalRoles
name
:
urn:oid:1.3.6.1.4.1.5923.1.5.1.1
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
\ No newline at end of file
attributesIncompleteRedirectUrl
:
https://auth.de.dariah.eu/cgi-bin/selfservice/ldapportal.pl
attributeGroups
:
-
check
:
AND
attributes
:
-
friendlyName
:
mail
name
:
urn:oid:0.9.2342.19200300.100.1.3
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
friendlyName
:
dariahTermsOfUse
name
:
urn:oid:1.3.6.1.4.1.10126.1.52.4.15
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
#value: Terms_of_Use_germ_engl_v6.pdf
-
friendlyName
:
eduPersonPrincipalName
mappedAttribute
:
id
name
:
urn:oid:1.3.6.1.4.1.5923.1.1.1.6
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
check
:
OPTIONAL
attributes
:
-
friendlyName
:
mail
name
:
urn:oid:0.9.2342.19200300.100.1.3
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
friendlyName
:
displayName
mappedAttribute
:
username
name
:
urn:oid:2.16.840.1.113730.3.1.241
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
friendlyName
:
isMemberOf
mappedAttribute
:
externalRoles
name
:
urn:oid:1.3.6.1.4.1.5923.1.5.1.1
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
\ No newline at end of file
dariahsp-sample-boot/src/main/java/eu/dariah/de/dariahsp/sample/controller/ErrorController.java
View file @
250d3274
...
...
@@ -2,6 +2,7 @@ package eu.dariah.de.dariahsp.sample.controller;
import
java.util.Map
;
import
javax.servlet.RequestDispatcher
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
...
...
@@ -16,6 +17,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.servlet.ModelAndView
;
import
eu.dariah.de.dariahsp.config.SecurityConfig
;
import
eu.dariah.de.dariahsp.error.RequiredAttributesException
;
@Controller
@RequestMapping
({
"${server.error.path:${error.path:/error}}"
})
...
...
@@ -31,9 +33,27 @@ public class ErrorController extends BasicErrorController {
@RequestMapping
(
produces
=
{
"text/html"
})
public
ModelAndView
errorHtml
(
HttpServletRequest
request
,
HttpServletResponse
response
)
{
Map
<
String
,
Object
>
attr
=
getErrorAttributes
(
request
,
getErrorAttributeOptions
(
request
,
MediaType
.
ALL
));
final
HttpStatus
status
=
getStatus
(
request
);
HttpStatus
status
=
getStatus
(
request
);
this
.
assembleMap
(
attr
,
status
);
// This is an error that needs special treatment in DARIAH/CLARIAH
Object
ex
=
request
.
getAttribute
(
RequestDispatcher
.
ERROR_EXCEPTION
);
if
(
ex
!=
null
&&
RequiredAttributesException
.
class
.
isAssignableFrom
(
ex
.
getClass
()))
{
StringBuilder
errorStrBldr
=
new
StringBuilder
();
errorStrBldr
.
append
(
"Your IdP did not provide all required attributes. "
);
if
(
securityConfig
.
getSaml
().
getSp
().
getAttributesIncompleteRedirectUrl
()!=
null
)
{
errorStrBldr
.
append
(
"Please visit "
)
.
append
(
"<a href='"
).
append
(
securityConfig
.
getSaml
().
getSp
().
getAttributesIncompleteRedirectUrl
()).
append
(
"'>"
)
.
append
(
securityConfig
.
getSaml
().
getSp
().
getAttributesIncompleteRedirectUrl
())
.
append
(
"</a> to validate your profile setup."
);
}
attr
.
put
(
"message"
,
errorStrBldr
.
toString
());
attr
.
put
(
"error"
,
HttpStatus
.
FORBIDDEN
);
}
return
new
ModelAndView
(
"index"
,
attr
);
}
...
...
dariahsp-sample-boot/src/main/resources/application.yml
View file @
250d3274
...
...
@@ -71,50 +71,31 @@ auth:
wantsAssertionsSigned
:
true
wantsResponsesSigned
:
false
httpClientTimoutMs
:
2000
attributeConfig
:
-
stage
:
ATTRIBUTES
required
:
true
attributeGroup
:
-
check
:
AND
attributes
:
-
friendlyName
:
mail
name
:
urn:oid:0.9.2342.19200300.100.1.3
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
stage
:
ATTRIBUTES
required
:
true
attributeGroup
:
-
check
:
OR
attributes
:
-
friendlyName
:
dariahTermsOfUse
name
:
urn:oid:1.3.6.1.4.1.10126.1.52.4.15
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
value
:
Terms_of_Use_v5.pdf
-
friendlyName
:
dariahTermsOfUse
name
:
urn:oid:1.3.6.1.4.1.10126.1.52.4.15
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
value
:
foobar-service-agreement_version1.pdf
-
stage
:
AUTHENTICATION
required
:
true
attributeGroup
:
-
check
:
AND
attributes
:
-
friendlyName
:
eduPersonPrincipalName
mappedAttribute
:
id
name
:
urn:oid:1.3.6.1.4.1.5923.1.1.1.6
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
stage
:
AUTHENTICATION
required
:
false
attributeGroup
:
-
check
:
OPTIONAL
attributes
:
-
friendlyName
:
mail
name
:
urn:oid:0.9.2342.19200300.100.1.3
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
friendlyName
:
displayName
mappedAttribute
:
username
name
:
urn:oid:2.16.840.1.113730.3.1.241
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
friendlyName
:
isMemberOf
mappedAttribute
:
externalRoles
name
:
urn:oid:1.3.6.1.4.1.5923.1.5.1.1
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
\ No newline at end of file
attributesIncompleteRedirectUrl
:
https://auth.de.dariah.eu/cgi-bin/selfservice/ldapportal.pl
attributeGroups
:
-
check
:
AND
attributes
:
-
friendlyName
:
mail
name
:
urn:oid:0.9.2342.19200300.100.1.3
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
friendlyName
:
dariahTermsOfUse
name
:
urn:oid:1.3.6.1.4.1.10126.1.52.4.15
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
#value: Terms_of_Use_germ_engl_v6.pdf
-
friendlyName
:
eduPersonPrincipalName
mappedAttribute
:
id
name
:
urn:oid:1.3.6.1.4.1.5923.1.1.1.6
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
check
:
OPTIONAL
attributes
:
-
friendlyName
:
mail
name
:
urn:oid:0.9.2342.19200300.100.1.3
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
friendlyName
:
displayName
mappedAttribute
:
username
name
:
urn:oid:2.16.840.1.113730.3.1.241
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
-
friendlyName
:
isMemberOf
mappedAttribute
:
externalRoles
name
:
urn:oid:1.3.6.1.4.1.5923.1.5.1.1
nameFormat
:
urn:oasis:names:tc:SAML:2.0:attrname-format:uri
\ No newline at end of file
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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