Commit 8cddb2b1 authored by Gradl, Tobias's avatar Gradl, Tobias
Browse files

Merge branch 'v2.0-dev' into 'v2.x-master'

v2.0-dev

See merge request !2
parents 8897f567 58fa7675
Pipeline #17902 passed with stage
in 1 minute and 49 seconds
......@@ -31,11 +31,11 @@ build:
- dariahsp-core/build/libs/*.jar
- dariahsp-sample-boot/build/libs/*.jar
only:
- v2.0
- v2.x-master
deploy:
stage: deploy
script:
- ./gradlew publish -x test $NEXUS_CREDENTIALS
only:
- v2.0
- v2.x-master
# dariahsp: service provider implementation for DARIAH services
This project contains the [dariahsp-core](dariahsp-core) library and the Spring Boot based [dariahsp-sample-boot](dariahsp-sample-boot) application. Implementations that are based on the core library need to include the dariahsp-core dependency and provide configuration for the primary security entry points.
This project contains the [dariahsp-core](dariahsp-core) library and the Spring Boot based [dariahsp-sample-boot](dariahsp-sample-boot) application. Implementations that are based on the core library need to include `dariahsp-core` as dependency and provide configuration for the primary security entry points.
The library is a wrapper around [Spring Security](https://spring.io/projects/spring-security), [PAC4J](https://www.pac4j.org/) and [OpenSAML 4](https://build.shibboleth.net/nexus/content/repositories/releases/org/opensaml/opensaml-core/) and implements two security methods that are commonly used in the context of DARIAH: the _local_ method is intended primarily for developer and test setups, the _saml_ method is targeted towards production environments. Both methods can easily be tested within the dariahsp-sample-boot web application. Opposed to earlier version, a choice between the methods is no longer determined by an environment flag, but by setting enabled properties within application properties. Methods can be enabled simultaneously and can work in parallel.
The library is a wrapper around [Spring Security](https://spring.io/projects/spring-security), [PAC4J](https://www.pac4j.org/) and [OpenSAML 4](https://build.shibboleth.net/nexus/content/repositories/releases/org/opensaml/opensaml-core/) and currently implements two security methods that are commonly used in the context of DARIAH: the **local** method is intended primarily for developer and test setups. The **saml** authentication method is targeted towards production environments, where federation of user accounts and single sign-on should be implemented. Both methods can easily be tested within the `dariahsp-sample-boot` web application. Setting respective configuration attributes within application properties, methods can be also be enabled simultaneously in order to work in parallel.
While still being used, the former v1.4 is discontinued and - being based on OpenSAML 2 ([also discontinued](https://wiki.shibboleth.net/confluence/display/OpenSAML/Home)) - should be replaced with a recent version.
> While still being used, the **former v1.4 is discontinued** and - being based on OpenSAML 2 ([also discontinued](https://wiki.shibboleth.net/confluence/display/OpenSAML/Home)) - should be replaced with a recent version.
## 1. Quickstart
A reference implementation and quick-start guide can be found in the [dariahsp-sample-boot](dariahsp-sample-boot) application.
## 2. Repository and dependency setup
The library and sample application are deployed to the Maven repository available at https://minfba.de.dariah.eu/nexus. Repository configuration can be included in Maven and Gradle settings and build configurations with the following snippets.
## 2. Getting the library
The library and sample application are deployed to a [Maven repository](https://minfba.de.dariah.eu/nexus).
### 2.1 Maven setup
> Information on the *latest version* of `dariahsp-core` can be found at the [respective package](https://minfba.de.dariah.eu/nexus/#browse/browse:minfba-central:eu%2Fdariah%2Fde%2Fdariahsp-core) in the Maven repository.
Please find information on the current version of dariahsp-core at the [respective package](https://minfba.de.dariah.eu/nexus/#browse/browse:minfba-central:eu%2Fdariah%2Fde%2Fdariahsp-core) in the deployment repository:
### 2.1 Maven setup
#### Repository configuration
......@@ -52,7 +52,7 @@ Include the dependency to dariahsp-core in your `pom.xml`.
<dependency>
<groupId>eu.dariah.de</groupId>
<artifactId>dariahsp-core</artifactId>
<version>2.0.0-SNAPSHOT</version>
<version>2.0.0-RELEASE</version>
</dependency>
```
......@@ -70,7 +70,7 @@ repositories {
}
```
Immediate access to either releases or snapshots can be configured based on the respective repositories.
Selective access to either releases or snapshots can be configured based on the respective repositories.
```groovy
repositories {
......@@ -90,39 +90,42 @@ repositories {
Include the dependency to dariahsp-core in your `build.gradle`.
```
implementation 'eu.dariah.de:dariahsp-core:2.0.0-SNAPSHOT'
implementation 'eu.dariah.de:dariahsp-core:2.0.0-RELEASE'
```
### 2.3 Manual download
The library and sample application can be downloaded from the:
* **[Maven repository](https://minfba.de.dariah.eu/nexus/#browse/browse:minfba-central:eu%2Fdariah%2Fde%2Fdariahsp-core)** or
* as **build artifacts** from the GitLab repository of the project. For the latest published builds see:
* [dariahsp-core](https://gitlab.rz.uni-bamberg.de/dariah/dariahsp/-/jobs/artifacts/v2.0/browse/dariahsp-core/build/libs/?job=build) and
* [dariahsp-sample-boot](https://gitlab.rz.uni-bamberg.de/dariah/dariahsp/-/jobs/artifacts/v2.0/browse/dariahsp-sample-boot/build/libs/?job=build) respectively.
## 3. Security concepts and entry points
As this library is based on Spring Security, concepts such as _Java-based configuration_, _filters_, _interceptors_ or _global method security_ can be referenced in the respective Spring documentation, e.g. the [Spring Core reference](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html), the [Spring Web reference](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html) and the [Spring Security Architecture](https://spring.io/guides/topicals/spring-security-architecture).
As this library is based on Spring Security, concepts such as _Java-based configuration_, _filters_, _interceptors_ or _global method security_ apply. They can be referenced in respective Spring documentation such as the [Spring Core reference](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html), the [Spring Web reference](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html) and the [Spring Security Architecture](https://spring.io/guides/topicals/spring-security-architecture).
Components that _only need import and activation_ in the target application:
* [`SecurityConfig`](dariahsp-core/src/main/java/eu/dariah/de/dariahsp/config/SecurityConfig.java): Main configuration contains all security-related beans and can be imported into the applications configuration
* [`AuthInfoHandlerInterceptor`](dariahsp-core/src/main/java/eu/dariah/de/dariahsp/web/AuthInfoHandlerInterceptor.java) provides access to authentication information in every view-model as `_auth` attribute
* [`DefaultFiltersConfigurerAdapter`](dariahsp-core/src/main/java/eu/dariah/de/dariahsp/config/web/DefaultFiltersConfigurerAdapter.java) provides filters for logout and intermediat-authentication callback (SAML)
* [`SAMLMetadataController`](dariahsp-core/src/main/java/eu/dariah/de/dariahsp/web/controller/SAMLMetadataController.java) provides easy web access to SAML SP metadata that can be used to register the implementing application at identity providers or federations
* [`SAMLMetadataController`](dariahsp-core/src/main/java/eu/dariah/de/dariahsp/web/controller/SAMLMetadataController.java) provides easy web access to SAML SP metadata that can be used to register the implementing application at an identity provider (IdP) or federation
* [`GlobalMethodSecurityConfig`](dariahsp-core/src/main/java/eu/dariah/de/dariahsp/config/web/GlobalMethodSecurityConfig.java) enables and configures annotation-based method security and thus simplifies security for REST controllers
One component requires _adaption_ in implementing applications:
* [`SecurityConfigurerAdapter`](dariahsp-core/src/main/java/eu/dariah/de/dariahsp/config/web/SecurityConfigurerAdapter.java) is intended to be extended by a concrete adapter that defines protected paths of the application.
## 4. Configuration
### Minimal working configuration
A minimal working configuration enables the local authentication method and provides local user accounts.
> Please see the [dariahsp-sample-boot](dariahsp-sample-boot) documentation and implementation for simple ideas on how to activate these entry points in actual implementations.
## 4. Configuration
## Local user accounts
The library supports a local authentication method that is purely based on application configuration properties. A working example including all configurable aspects:
## 4.1 Minimal working configuration
A minimal working configuration configures the **local authentication** method and defines **local user accounts**. The following configuration snippet includes an *admin* user with a specified BCrypt-encrypted password.
```yaml
#Minimal working sample configuration with local authentication enabled and one configured user
auth:
local:
enabled: true
......@@ -132,29 +135,63 @@ auth:
passhash: '$2y$10$nmTcpRxs.RFUstkJJms6U.AW61Jmr64s9VNQLuhpU8gYrgzCapwka'
```
A more sophisticated configuration of the local authentication method could involve roles and role mappings along with a configured hierarchy between the roles
In order to facilitate BCrypt encryption of passwords without having to rely on online generators, the `dariah-core` library implements a CLI-based generator. Due to required dependencies, usage of the so called *fatjar* is required, which can be downloaded from the [build artifacts](https://gitlab.rz.uni-bamberg.de/dariah/dariahsp/-/jobs/artifacts/v2.0/browse/dariahsp-core/build/libs/?job=build) or the [Maven repository](https://minfba.de.dariah.eu/nexus/#browse/browse:minfba-central:eu%2Fdariah%2Fde%2Fdariahsp-core).
```
$ java -jar dariahsp-core-2.0.0-RELEASE-fatjar.jar
CLI Tool to create BCrypt passwords to be used with a dariahsp derived application
------------------------------------------------------
Please choose rounds [4-31; default: 10]
Provide the password that you want encoded (minimum 6 characters, no leading/trailing whitespace):
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
BCrypt computation successful:
$2y$10$nmTcpRxs.RFUstkJJms6U.AW61Jmr64s9VNQLuhpU8gYrgzCapwka
```
## 4.2 Roles and mappings
Role management and configuration in the `dariahsp-core` library follows three basic concepts:
* User accounts *can provide information on roles*.
* in case of the *SAML authentication* method, these roles are managed externally by identify providers
* for *local authentication*, roles are attached as attributes to user specifications
* Due to limited control of user roles in external scenarios (SAML), roles are mapped to configured `permissionDefinitions`, which include
* an internal name of the `permissionSet` against which security can be applied
* a numeric permission `level` against which authorization be determined (e.g. level must be gte 50)
* actual mappings to (potentially external) roles; mapping configuration is specified per authentication method (currently `local` or `saml`)
* A hierarchy of permission definitions can be specified to facilitate authorize against minimal permission sets. In the sample configuration below, a security expression that checks for a permission `ROLE_CONTRIBUTOR` is satisfied by both the `admin` and `contributor` users due to the configured permission hierarchy.
> New implementations are advised to prefer hierarchy-based authorization over the level-based option due for flexibility reasons. Level-based authorization can be found in this library mainly for backwards compatibility to v1.4
```yaml
auth:
#settings under roleHierarchy and roleDefinitions apply to all supported authentication methods
rolehierarchy: ROLE_ADMINISTRATOR > ROLE_CONTRIBUTOR > ROLE_USER
roleDefinitions:
- role: ADMINISTRATOR
#settings under permissionHierarchy and permissionDefinitions apply to all supported authentication methods
permissionHierarchy: ROLE_ADMINISTRATOR > ROLE_CONTRIBUTOR > ROLE_USER
permissionDefinitions:
- permissionSet: ROLE_ADMINISTRATOR
level: 100
mappings:
local: ["application_admin"]
- role: CONTRIBUTOR
roleMappings:
local: ["application_admin"]
saml: ["application_admin"]
- permissionSet: ROLE_CONTRIBUTOR
level: 50
mappings:
roleMappings:
local: ["application_contributor"]
- role: USER
saml: ["application_contributor"]
- permissionSet: ROLE_USER
level: 10
mappings:
roleMappings:
local: ["application_user"]
saml: ["application_user"]
#Enabled local authentication method with three configured users
local:
enabled: true
authorizerName: local
#Same password for each user: 1234
users:
- username: 'admin'
......@@ -168,28 +205,106 @@ auth:
roles: ["application_user"]
```
## 4.3 SAML-based authentication
### Java Keystore
Even with the *local* authentication method, the dariahsp-sample application requires the configuration of a Java keystore (jks). This is mainly due to the SAML metadata generation functionality, which is available when local logins are used in order to help with installations of SAML service providers: starting the sample application in local authentication mode, the home screen of the application shows two links *SAML metadata...*, which support SAML metadata management (see SAML section below).
This library supports various configuration options to control SAML-related behavior. Many are set to sound defaults and not shown in the sample below. For an overview of the full set of configuration properties see [config.sample.yml](dariahsp-core/src/main/resources/config.sample.yml).
Based on a X.509 keypair and certificate chains, a keystore can easily be consolidated with `openssl` and the `keytool` (comes with Java installation). The followings steps show the commands for the example of the keystore for minfba.de.dariah.eu and the appropriate input. Please modify accordingly:
The configuration sample below shows attributes that should be adapted or evaluated in order to enable SAML-based authentication.
#### 1. Convert pem/pem keypair to p12 for easier input
For the -name argument make sure to chose as *name* the later alias of the keypair in the keystore.
```yaml
auth:
# This base URL must indicate the externally visible FQDN as this is used for callbacks from the IdP
baseUrl: http://localhost:8080
permissionHierarchy: ROLE_ADMINISTRATOR > ROLE_CONTRIBUTOR > ROLE_USER
permissionDefinitions:
- permissionSet: ROLE_ADMINISTRATOR
level: 100
roleMappings:
local: ["application_admin"]
saml: ["application_admin"]
- permissionSet: ROLE_CONTRIBUTOR
level: 50
roleMappings:
local: ["application_contributor"]
saml: ["application_contributor"]
- permissionSet: ROLE_USER
level: 10
roleMappings:
local: ["application_user"]
saml: ["application_user"]
saml:
enabled: true
keystore:
path: /path/to/keystore.jks
pass: keystore_password
alias: keypair_alias
aliaspass: private_key_password
metadata:
# URL is identical in all current DARIAH installations
url: https://aaiproxy.de.dariah.eu/idp/
sp:
# Configuration below is identical in all current DARIAH installations
attributesIncompleteRedirectUrl: "https://auth.de.dariah.eu/cgi-bin/selfservice/ldapportal.pl"
attributeGroups:
- check: AND
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
- 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
```
### 4.3.1 Java KeyStore (JKS)
This library requires an existing Java KeyStore (JKS) that contains a private/public keypair that can be used for signature and encryption purposes. Depending on the addressed IdP or proxy, different requirements on the keypair could apply. Once setup, set the appropriate configuration parameters of `saml.keystore.{path,pass,alias,aliaspass}`
> **WARNING**: Although the sample implementation includes a Java KeyStore (JKS) for development purposes, be advised to **NOT** use this keystore in productive environments.
#### Option 1: KeyStore generation
If you are setting up a DARIAH/CLARIAH service, a keystore - along with the required keypair can be created as such:
```
keytool -genkeypair -alias keypair_alias -keypass private_key_password -keystore sample_keystore.jks -storepass keystore_password -keyalg RSA -keysize 4096 -validity 3650
```
#### Option 2: Creating a KeyStore from an existing keypair
Based on a X.509 keypair and certificate chains, a keystore can easily be consolidated with `openssl` and the `keytool` (comes with Java installation). The followings steps show the commands for the example of the keystore for `minfba.de.dariah.eu` and the appropriate input. Please modify accordingly:
1. Convert pem/pem keypair to p12 for easier input
For the -name argument make sure to chose the later alias of the keypair in the keystore as *name*.
```
$ openssl pkcs12 -export -name minfba.de.dariah.eu -in minfba-de-dariah-eu.crt -inkey minfba-de-dariah-eu.key > minfba-de-dariah-eu.p12
```
#### 2. Import p12 keypair and create Java keystore
2. Import the p12 keypair and create the Java KeyStore
Specified in the following step with the -alias argument note the reuse of the same key name as above. Basically this step imports an existing PKCS based "keystore" into a newly created jks.
```
$ keytool -importkeystore -alias minfba.de.dariah.eu -srckeystore minfba-de-dariah-eu.p12 -destkeystore minfba-de-dariah-eu.jks -srcstoretype pkcs12
```
#### 3. Import required trusted ca certificates
In the particular DARIAH-DE case this means 1) the chain of our keypair and 2) the trusted SAML metadata provider keychains of the [DFN AAI](https://www.aai.dfn.de/teilnahme/metadaten/).
3. Import the required trusted ca certificates
In the particular DARIAH-DE case this means 1) the chain of our keypair and 2) the trusted SAML metadata provider keychains of the [DFN AAI](https://doku.tid.dfn.de/de:metadata).
```
$ keytool -import -trustcacerts -alias gwdg_certificate_chain_g2 -file gwdg_certificate_chain_g2.pem -keystore minfba-de-dariah-eu.jks
......@@ -197,25 +312,37 @@ $ keytool -import -trustcacerts -alias dfn-aai -file dfn-aai.pem -keystore minfb
$ keytool -import -trustcacerts -alias dfn-aai-g2 -file dfn-aai.g2.pem -keystore minfba-de-dariah-eu.jks
```
#### GUI Support for Java Keystores
A convenient GUI-based option to view and edit Java keystore can be found in the [KeyStore Explorer](http://keystore-explorer.org/)
### Local user accounts
Local user accounts are configured in the central configuration file of the sample application. Passwords are encoded as Bcrypt hashes. In order to create your own hashes a convenience method has been implemented within the dariahsp-core library. As there are some required dependencies, you can download the latest [dariahsp-core-*-jar-with-dependencies.jar](https://minfba.de.dariah.eu/artifactory/list/dariah-minfba-snapshots/eu/dariah/de/dariahsp-core/).
To then create bcrypt passwords from a shell:
```
$ java -cp dariahsp-core-0.0.4-SNAPSHOT-jar-with-dependencies.jar eu.dariah.de.dariahsp.local.BCryptPasswordCreator
```
### 4.3.2 IdP metadata
Provide the URL of the desired **IdP or metadata federation** as `auth.saml.metadata.url`. In case of DARIAH-DE/CLARIAH-DE implementations, all services currently use the URL https://aaiproxy.de.dariah.eu/idp/ of the DARIAH-DE AAI Proxy.
## dariahsp-core library
### 4.3.3 Attribute groups
#### Attribute mapping
SAML attributes can be **mapped to properties of user profiles**, that are created upon successful authentication. As such, the following configuration snipped assigns eduPersonPrincipalName values to the internal id attibute - rendering users persistently recognizable by their id.
```yaml
- 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
```
## dariahsp-sample-boot app
#### Attribute requirements
The Spring Boot based application is documented in its module: [dariahsp-sample-boot]
Requirements on the availability of SAML attributes as well as their exact values can be specified in terms of `attributeGroups`. As an example: in case of the DARIAH AAI, authentication of users can only be accepted, if they have previously accepted the *DARIAH Terms of Use*, which is attested by the presentation of the `dariahTermsOfUse` SAML attribute. The configuration snippet below ensures that both the `dariahTermsOfUse` and the `eduPersonPrincipalName` attributes are provided with a SAML authentication. The `check: OR` directive could instead specify that at least one attribute out of a defined set needs to be provided.
```yaml
- check: AND
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
- 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
```
If required attribute conditions are not satisfied, a `RequiredAttributesException` is thrown, which the [dariahsp-sample-boot](dariahsp-sample-boot) application handles by redirecting the user to the URL specified at `attributesIncompleteRedirectUrl`.
\ No newline at end of file
......@@ -5,7 +5,7 @@ plugins {
allprojects {
group = 'eu.dariah.de'
version = '2.0.0-SNAPSHOT'
version = '2.0.0-RELEASE'
repositories {
maven {
......
package eu.dariah.de.dariahsp.authentication;
import java.util.ArrayList;
import java.util.HashSet;
import org.pac4j.core.context.WebContext;
import org.pac4j.core.credentials.UsernamePasswordCredentials;
......@@ -47,7 +48,12 @@ public class LocalUsernamePasswordAuthenticator implements Authenticator<Usernam
final CommonProfile profile = new CommonProfile();
profile.setId(username);
profile.addAttribute(Pac4jConstants.USERNAME, username);
profile.setRoles(cnf.getRoles());
if (cnf.getRoles()==null) {
profile.setRoles(new HashSet<>(0));
} else {
profile.setRoles(cnf.getRoles());
}
credentials.setUserProfile(profile);
log.info("Local authentication succeeded [{}]", profile.toString());
......
......@@ -6,8 +6,8 @@ import java.util.Set;
import lombok.Data;
@Data
public class RoleDefinition {
private String role;
public class PermissionDefinition {
private String permissionSet;
private int level;
private Map<String,Set<String>> mappings;
private Map<String,Set<String>> roleMappings;
}
......@@ -48,8 +48,8 @@ public class SecurityConfig {
private final SAMLSecurity saml = new SAMLSecurity();
private String salt;
private String roleHierarchy;
private List<RoleDefinition> roleDefinitions;
private String permissionHierarchy = "";
private List<PermissionDefinition> permissionDefinitions;
private String baseUrl = "http://localhost:8080";
private String defaultLoginUrl = null;
private String defaultLogoutUrl = null;
......@@ -87,8 +87,8 @@ public class SecurityConfig {
@Bean
public RoleHierarchy roleHierarchy() {
RoleHierarchyImpl r = new RoleHierarchyImpl();
r.setHierarchy(roleHierarchy);
log.info("RoleHierarchy configured: {}", roleHierarchy);
r.setHierarchy(permissionHierarchy);
log.info("PermissionHierarchy configured: {}", permissionHierarchy);
return r;
}
......@@ -146,7 +146,13 @@ public class SecurityConfig {
cfg.setMaximumAuthenticationLifetime(saml.getSp().getMaxAuthAge());
cfg.setSignatureAlgorithms(saml.getSp().getSigningMethods());
cfg.setSignatureReferenceDigestMethods(saml.getSp().getDigestMethods());
cfg.setServiceProviderEntityId(saml.getSp().getEntityId());
if (saml.getSp().getEntityId()!=null) {
cfg.setServiceProviderEntityId(saml.getSp().getEntityId());
} else {
cfg.setServiceProviderEntityId(baseUrl);
}
cfg.setSpLogoutRequestSigned(saml.getSp().isLogoutRequestSigned());
cfg.setWantsAssertionsSigned(saml.getSp().isWantsAssertionsSigned());
cfg.setWantsResponsesSigned(saml.getSp().isWantsResponsesSigned());
......@@ -176,13 +182,13 @@ public class SecurityConfig {
private SamlProfileCreator saml2ProfileCreator() {
SamlProfileCreator saml2ProfileCreator = new SamlProfileCreator(this, saml.getAuthorizerName());
saml2ProfileCreator.setRoleDefinitions(roleDefinitions);
saml2ProfileCreator.setPermissionDefinitions(permissionDefinitions);
return saml2ProfileCreator;
}
private LocalProfileCreator localProfileCreator() {
LocalProfileCreator localProfileCreator = new LocalProfileCreator(local.getAuthorizerName());
localProfileCreator.setRoleDefinitions(roleDefinitions);
localProfileCreator.setPermissionDefinitions(permissionDefinitions);
return localProfileCreator;
}
}
......@@ -5,7 +5,7 @@ import lombok.Setter;
@Getter @Setter
public class SAMLSecurity {
private boolean enabled = true;
private boolean enabled;
private String authorizerName = "saml";
private final KeystoreProperties keystore = new KeystoreProperties();
private final MetadataProperties metadata = new MetadataProperties();
......
......@@ -23,7 +23,7 @@ public class ServiceProvider {
private int maxAuthAge = 3600;
private String entityId;
private int httpClientTimoutMs = 2000;
private boolean signMetadata;
private boolean signMetadata = true;
private List<String> signingMethods;
private List<String> digestMethods;
private List<String> supportedProtocols;
......
......@@ -8,10 +8,20 @@ import eu.dariah.de.dariahsp.web.AuthInfoHandlerInterceptor;
import eu.dariah.de.dariahsp.web.AuthInfoHelper;
import lombok.extern.slf4j.Slf4j;
/**
* WebMvcConfigurer responsible for injecting the {@link AuthInfoHandlerInterceptor} into the filter chain, an interceptor
* that is responsible for providing basic authentication and authorization information into the model.
*
* @author Tobias Gradl
*
*/
@Slf4j
public class AuthInfoConfigurer implements WebMvcConfigurer {
@Autowired private AuthInfoHelper authInfoHelper;
/**
* Adds an {@link AuthInfoHandlerInterceptor} to the {@link InterceptorRegistry}
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInfoHandlerInterceptor());
......
......@@ -5,7 +5,7 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import eu.dariah.de.dariahsp.config.RoleDefinition;
import eu.dariah.de.dariahsp.config.PermissionDefinition;
import eu.dariah.de.dariahsp.model.ExtendedUserProfile;
import lombok.Data;
......@@ -13,18 +13,18 @@ import lombok.Data;
public abstract class BaseProfileCreator {
public static final String ROLE_PREFIX = "ROLE_";
protected final String clientName;
protected List<RoleDefinition> roleDefinitions;
protected List<PermissionDefinition> permissionDefinitions;
protected Set<RoleDefinition> getMappedRoles(ExtendedUserProfile profile) {
Set<RoleDefinition> roles = new LinkedHashSet<>();
for (RoleDefinition rm : roleDefinitions) {
for (String client : rm.getMappings().keySet()) {
protected Set<PermissionDefinition> getMappedRoles(ExtendedUserProfile profile) {
Set<PermissionDefinition> roles = new LinkedHashSet<>();
for (PermissionDefinition rm : permissionDefinitions) {
for (String client : rm.getRoleMappings().keySet()) {
if (!client.equals(clientName)) {
continue;
}
for (String extRole : profile.getExternalRoles()) {
if (!extRole.trim().isEmpty() &&
rm.getMappings().get(client).contains(extRole.trim()) &&
rm.getRoleMappings().get(client).contains(extRole.trim()) &&
!roles.contains(rm)) {
roles.add(rm);
}
......@@ -37,14 +37,14 @@ public abstract class BaseProfileCreator {
protected void mapAndAssignRoles(ExtendedUserProfile profile) {
if (this.canMapRoles(profile)) {
// Determine applicable role definitions
Set<RoleDefinition> mappedDefinitions = this.getMappedRoles(profile);
Set<PermissionDefinition> mappedDefinitions = this.getMappedRoles(profile);
// Set applicable roles as Strings
profile.setRoles(mappedDefinitions.stream()
.map(mr -> ROLE_PREFIX + mr.getRole().toUpperCase())
.map(pd -> pd.getPermissionSet().toUpperCase())
.collect(Collectors.toSet()));
// Set maximum applicable level
profile.setLevel(mappedDefinitions.stream()
.mapToInt(RoleDefinition::getLevel)
.mapToInt(PermissionDefinition::getLevel)
.max().orElse(0));
}
}
......@@ -52,6 +52,6 @@ public abstract class BaseProfileCreator {
private boolean canMapRoles(ExtendedUserProfile profile) {
return clientName!=null &&
profile.getExternalRoles()!=null && !profile.getExternalRoles().isEmpty() &&
roleDefinitions!=null && !roleDefinitions.isEmpty();
permissionDefinitions!=null && !permissionDefinitions.isEmpty();
}
}
}
\ No newline at end of file
......@@ -10,6 +10,11 @@ import org.springframework.web.servlet.support.RequestContextUtils;
import eu.dariah.de.dariahsp.web.model.AuthPojo;
/**
* Interceptor that adds basic authentication and authorization information as {@link AuthPojo} to each request model
*
* @author Tobias Gradl
*/
public class AuthInfoHandlerInterceptor extends HandlerInterceptorAdapter {
private AuthInfoHelper authInfoHelper;
......@@ -17,6 +22,9 @@ public class AuthInfoHandlerInterceptor extends HandlerInterceptorAdapter {
public void setAuthInfoHelper(AuthInfoHelper authInfoHelper) { this.authInfoHelper = authInfoHelper; }
/*
* Adds the _sessionId and _auth request model attributes
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
if (modelAndView==null) {
......
# Config options of the dariahsp core library
# Commented properties reflect default values
auth:
# Base externally visible URL
#baseUrl: http://localhost:8080
# Default redirected URL post login
#defaultLoginUrl: ${auth.baseUrl}
# Default redirected URL post logout
#defaultLogoutUrl: ${auth.baseUrl}
# Salt for signing and encryption purposes
salt: Qmwp4CO7LDkOUDouAcCcUqd9ZGNbRG5Jyr5lpntOuB9
rolehierarchy: ROLE_ADMINISTRATOR > ROLE_CONTRIBUTOR > ROLE_USER
roleDefinitions:
- role: ADMINISTRATOR
# Hierarchy used in role-based authorization voting
permissionHierarchy: ROLE_ADMINISTRATOR > ROLE_CONTRIBUTOR > ROLE_USER
# Permission sets to code against and mapping to 'external' roles
permissionDefinitions:
# Name of the permission set (internal role)
- permissionSet: ROLE_ADMINISTRATOR
# Numerical authorization level allowing security expressions as level gte 50
level: 100
mappings:
roleMappings: