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: ...@@ -31,11 +31,11 @@ build:
- dariahsp-core/build/libs/*.jar - dariahsp-core/build/libs/*.jar
- dariahsp-sample-boot/build/libs/*.jar - dariahsp-sample-boot/build/libs/*.jar
only: only:
- v2.0 - v2.x-master
deploy: deploy:
stage: deploy stage: deploy
script: script:
- ./gradlew publish -x test $NEXUS_CREDENTIALS - ./gradlew publish -x test $NEXUS_CREDENTIALS
only: only:
- v2.0 - v2.x-master
This diff is collapsed.
...@@ -5,7 +5,7 @@ plugins { ...@@ -5,7 +5,7 @@ plugins {
allprojects { allprojects {
group = 'eu.dariah.de' group = 'eu.dariah.de'
version = '2.0.0-SNAPSHOT' version = '2.0.0-RELEASE'
repositories { repositories {
maven { maven {
......
package eu.dariah.de.dariahsp.authentication; package eu.dariah.de.dariahsp.authentication;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import org.pac4j.core.context.WebContext; import org.pac4j.core.context.WebContext;
import org.pac4j.core.credentials.UsernamePasswordCredentials; import org.pac4j.core.credentials.UsernamePasswordCredentials;
...@@ -47,7 +48,12 @@ public class LocalUsernamePasswordAuthenticator implements Authenticator<Usernam ...@@ -47,7 +48,12 @@ public class LocalUsernamePasswordAuthenticator implements Authenticator<Usernam
final CommonProfile profile = new CommonProfile(); final CommonProfile profile = new CommonProfile();
profile.setId(username); profile.setId(username);
profile.addAttribute(Pac4jConstants.USERNAME, 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); credentials.setUserProfile(profile);
log.info("Local authentication succeeded [{}]", profile.toString()); log.info("Local authentication succeeded [{}]", profile.toString());
......
...@@ -6,8 +6,8 @@ import java.util.Set; ...@@ -6,8 +6,8 @@ import java.util.Set;
import lombok.Data; import lombok.Data;
@Data @Data
public class RoleDefinition { public class PermissionDefinition {
private String role; private String permissionSet;
private int level; private int level;
private Map<String,Set<String>> mappings; private Map<String,Set<String>> roleMappings;
} }
...@@ -48,8 +48,8 @@ public class SecurityConfig { ...@@ -48,8 +48,8 @@ public class SecurityConfig {
private final SAMLSecurity saml = new SAMLSecurity(); private final SAMLSecurity saml = new SAMLSecurity();
private String salt; private String salt;
private String roleHierarchy; private String permissionHierarchy = "";
private List<RoleDefinition> roleDefinitions; private List<PermissionDefinition> permissionDefinitions;
private String baseUrl = "http://localhost:8080"; private String baseUrl = "http://localhost:8080";
private String defaultLoginUrl = null; private String defaultLoginUrl = null;
private String defaultLogoutUrl = null; private String defaultLogoutUrl = null;
...@@ -87,8 +87,8 @@ public class SecurityConfig { ...@@ -87,8 +87,8 @@ public class SecurityConfig {
@Bean @Bean
public RoleHierarchy roleHierarchy() { public RoleHierarchy roleHierarchy() {
RoleHierarchyImpl r = new RoleHierarchyImpl(); RoleHierarchyImpl r = new RoleHierarchyImpl();
r.setHierarchy(roleHierarchy); r.setHierarchy(permissionHierarchy);
log.info("RoleHierarchy configured: {}", roleHierarchy); log.info("PermissionHierarchy configured: {}", permissionHierarchy);
return r; return r;
} }
...@@ -146,7 +146,13 @@ public class SecurityConfig { ...@@ -146,7 +146,13 @@ public class SecurityConfig {
cfg.setMaximumAuthenticationLifetime(saml.getSp().getMaxAuthAge()); cfg.setMaximumAuthenticationLifetime(saml.getSp().getMaxAuthAge());
cfg.setSignatureAlgorithms(saml.getSp().getSigningMethods()); cfg.setSignatureAlgorithms(saml.getSp().getSigningMethods());
cfg.setSignatureReferenceDigestMethods(saml.getSp().getDigestMethods()); 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.setSpLogoutRequestSigned(saml.getSp().isLogoutRequestSigned());
cfg.setWantsAssertionsSigned(saml.getSp().isWantsAssertionsSigned()); cfg.setWantsAssertionsSigned(saml.getSp().isWantsAssertionsSigned());
cfg.setWantsResponsesSigned(saml.getSp().isWantsResponsesSigned()); cfg.setWantsResponsesSigned(saml.getSp().isWantsResponsesSigned());
...@@ -176,13 +182,13 @@ public class SecurityConfig { ...@@ -176,13 +182,13 @@ public class SecurityConfig {
private SamlProfileCreator saml2ProfileCreator() { private SamlProfileCreator saml2ProfileCreator() {
SamlProfileCreator saml2ProfileCreator = new SamlProfileCreator(this, saml.getAuthorizerName()); SamlProfileCreator saml2ProfileCreator = new SamlProfileCreator(this, saml.getAuthorizerName());
saml2ProfileCreator.setRoleDefinitions(roleDefinitions); saml2ProfileCreator.setPermissionDefinitions(permissionDefinitions);
return saml2ProfileCreator; return saml2ProfileCreator;
} }
private LocalProfileCreator localProfileCreator() { private LocalProfileCreator localProfileCreator() {
LocalProfileCreator localProfileCreator = new LocalProfileCreator(local.getAuthorizerName()); LocalProfileCreator localProfileCreator = new LocalProfileCreator(local.getAuthorizerName());
localProfileCreator.setRoleDefinitions(roleDefinitions); localProfileCreator.setPermissionDefinitions(permissionDefinitions);
return localProfileCreator; return localProfileCreator;
} }
} }
...@@ -5,7 +5,7 @@ import lombok.Setter; ...@@ -5,7 +5,7 @@ import lombok.Setter;
@Getter @Setter @Getter @Setter
public class SAMLSecurity { public class SAMLSecurity {
private boolean enabled = true; private boolean enabled;
private String authorizerName = "saml"; private String authorizerName = "saml";
private final KeystoreProperties keystore = new KeystoreProperties(); private final KeystoreProperties keystore = new KeystoreProperties();
private final MetadataProperties metadata = new MetadataProperties(); private final MetadataProperties metadata = new MetadataProperties();
......
...@@ -23,7 +23,7 @@ public class ServiceProvider { ...@@ -23,7 +23,7 @@ public class ServiceProvider {
private int maxAuthAge = 3600; private int maxAuthAge = 3600;
private String entityId; private String entityId;
private int httpClientTimoutMs = 2000; private int httpClientTimoutMs = 2000;
private boolean signMetadata; private boolean signMetadata = true;
private List<String> signingMethods; private List<String> signingMethods;
private List<String> digestMethods; private List<String> digestMethods;
private List<String> supportedProtocols; private List<String> supportedProtocols;
......
...@@ -8,10 +8,20 @@ import eu.dariah.de.dariahsp.web.AuthInfoHandlerInterceptor; ...@@ -8,10 +8,20 @@ import eu.dariah.de.dariahsp.web.AuthInfoHandlerInterceptor;
import eu.dariah.de.dariahsp.web.AuthInfoHelper; import eu.dariah.de.dariahsp.web.AuthInfoHelper;
import lombok.extern.slf4j.Slf4j; 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 @Slf4j
public class AuthInfoConfigurer implements WebMvcConfigurer { public class AuthInfoConfigurer implements WebMvcConfigurer {
@Autowired private AuthInfoHelper authInfoHelper; @Autowired private AuthInfoHelper authInfoHelper;
/**
* Adds an {@link AuthInfoHandlerInterceptor} to the {@link InterceptorRegistry}
*/
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInfoHandlerInterceptor()); registry.addInterceptor(authInfoHandlerInterceptor());
......
...@@ -5,7 +5,7 @@ import java.util.List; ...@@ -5,7 +5,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; 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 eu.dariah.de.dariahsp.model.ExtendedUserProfile;
import lombok.Data; import lombok.Data;
...@@ -13,18 +13,18 @@ import lombok.Data; ...@@ -13,18 +13,18 @@ import lombok.Data;
public abstract class BaseProfileCreator { public abstract class BaseProfileCreator {
public static final String ROLE_PREFIX = "ROLE_"; public static final String ROLE_PREFIX = "ROLE_";
protected final String clientName; protected final String clientName;
protected List<RoleDefinition> roleDefinitions; protected List<PermissionDefinition> permissionDefinitions;
protected Set<RoleDefinition> getMappedRoles(ExtendedUserProfile profile) { protected Set<PermissionDefinition> getMappedRoles(ExtendedUserProfile profile) {
Set<RoleDefinition> roles = new LinkedHashSet<>(); Set<PermissionDefinition> roles = new LinkedHashSet<>();
for (RoleDefinition rm : roleDefinitions) { for (PermissionDefinition rm : permissionDefinitions) {
for (String client : rm.getMappings().keySet()) { for (String client : rm.getRoleMappings().keySet()) {
if (!client.equals(clientName)) { if (!client.equals(clientName)) {
continue; continue;
} }
for (String extRole : profile.getExternalRoles()) { for (String extRole : profile.getExternalRoles()) {
if (!extRole.trim().isEmpty() && if (!extRole.trim().isEmpty() &&
rm.getMappings().get(client).contains(extRole.trim()) && rm.getRoleMappings().get(client).contains(extRole.trim()) &&
!roles.contains(rm)) { !roles.contains(rm)) {
roles.add(rm); roles.add(rm);
} }
...@@ -37,14 +37,14 @@ public abstract class BaseProfileCreator { ...@@ -37,14 +37,14 @@ public abstract class BaseProfileCreator {
protected void mapAndAssignRoles(ExtendedUserProfile profile) { protected void mapAndAssignRoles(ExtendedUserProfile profile) {
if (this.canMapRoles(profile)) { if (this.canMapRoles(profile)) {
// Determine applicable role definitions // Determine applicable role definitions
Set<RoleDefinition> mappedDefinitions = this.getMappedRoles(profile); Set<PermissionDefinition> mappedDefinitions = this.getMappedRoles(profile);
// Set applicable roles as Strings // Set applicable roles as Strings
profile.setRoles(mappedDefinitions.stream() profile.setRoles(mappedDefinitions.stream()
.map(mr -> ROLE_PREFIX + mr.getRole().toUpperCase()) .map(pd -> pd.getPermissionSet().toUpperCase())
.collect(Collectors.toSet())); .collect(Collectors.toSet()));
// Set maximum applicable level // Set maximum applicable level
profile.setLevel(mappedDefinitions.stream() profile.setLevel(mappedDefinitions.stream()
.mapToInt(RoleDefinition::getLevel) .mapToInt(PermissionDefinition::getLevel)
.max().orElse(0)); .max().orElse(0));
} }
} }
...@@ -52,6 +52,6 @@ public abstract class BaseProfileCreator { ...@@ -52,6 +52,6 @@ public abstract class BaseProfileCreator {
private boolean canMapRoles(ExtendedUserProfile profile) { private boolean canMapRoles(ExtendedUserProfile profile) {
return clientName!=null && return clientName!=null &&
profile.getExternalRoles()!=null && !profile.getExternalRoles().isEmpty() && 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; ...@@ -10,6 +10,11 @@ import org.springframework.web.servlet.support.RequestContextUtils;
import eu.dariah.de.dariahsp.web.model.AuthPojo; 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 { public class AuthInfoHandlerInterceptor extends HandlerInterceptorAdapter {
private AuthInfoHelper authInfoHelper; private AuthInfoHelper authInfoHelper;
...@@ -17,6 +22,9 @@ public class AuthInfoHandlerInterceptor extends HandlerInterceptorAdapter { ...@@ -17,6 +22,9 @@ public class AuthInfoHandlerInterceptor extends HandlerInterceptorAdapter {
public void setAuthInfoHelper(AuthInfoHelper authInfoHelper) { this.authInfoHelper = authInfoHelper; } public void setAuthInfoHelper(AuthInfoHelper authInfoHelper) { this.authInfoHelper = authInfoHelper; }
/*
* Adds the _sessionId and _auth request model attributes
*/
@Override @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
if (modelAndView==null) { if (modelAndView==null) {
......
# Config options of the dariahsp core library # Config options of the dariahsp core library
# Commented properties reflect default values # Commented properties reflect default values
auth: auth:
# Base externally visible URL
#baseUrl: http://localhost:8080 #baseUrl: http://localhost:8080
# Default redirected URL post login
#defaultLoginUrl: ${auth.baseUrl} #defaultLoginUrl: ${auth.baseUrl}
# Default redirected URL post logout
#defaultLogoutUrl: ${auth.baseUrl} #defaultLogoutUrl: ${auth.baseUrl}
# Salt for signing and encryption purposes
salt: Qmwp4CO7LDkOUDouAcCcUqd9ZGNbRG5Jyr5lpntOuB9 salt: Qmwp4CO7LDkOUDouAcCcUqd9ZGNbRG5Jyr5lpntOuB9
rolehierarchy: ROLE_ADMINISTRATOR > ROLE_CONTRIBUTOR > ROLE_USER # Hierarchy used in role-based authorization voting
roleDefinitions: permissionHierarchy: ROLE_ADMINISTRATOR > ROLE_CONTRIBUTOR > ROLE_USER
- role: ADMINISTRATOR # 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 level: 100
mappings: roleMappings:
# Role mapping to locally configured roles
local: ["application_admin"] local: ["application_admin"]
# Role mapping to SAML (typically memberOf) roles
saml: ["application_admin"] saml: ["application_admin"]
- role: CONTRIBUTOR - permissionSet: ROLE_CONTRIBUTOR
level: 50 level: 50
mappings: roleMappings:
local: ["application_contributor"] local: ["application_contributor"]
saml: ["application_contributor"] saml: ["application_contributor"]
- role: USER - permissionSet: ROLE_USER
level: 10 level: 10
mappings: roleMappings:
local: ["application_user"] local: ["application_user"]
saml: ["application_user"] saml: ["application_user"]
local: local:
# Enable local authentication
enabled: true enabled: true
authorizerName: local # Name of the method
#authorizerName: local
# Same password for each user: 1234 # Same password for each user: 1234
users: users:
# Username
- username: 'admin' - username: 'admin'
# BCrypt hashed password
passhash: '$2y$10$nmTcpRxs.RFUstkJJms6U.AW61Jmr64s9VNQLuhpU8gYrgzCapwka' passhash: '$2y$10$nmTcpRxs.RFUstkJJms6U.AW61Jmr64s9VNQLuhpU8gYrgzCapwka'
# Pseudo-external role
roles: ["application_admin"] roles: ["application_admin"]
- username: 'contributor' - username: 'contributor'
passhash: '$2y$10$nmTcpRxs.RFUstkJJms6U.AW61Jmr64s9VNQLuhpU8gYrgzCapwka' passhash: '$2y$10$nmTcpRxs.RFUstkJJms6U.AW61Jmr64s9VNQLuhpU8gYrgzCapwka'
...@@ -37,43 +52,57 @@ auth: ...@@ -37,43 +52,57 @@ auth:
passhash: '$2y$10$nmTcpRxs.RFUstkJJms6U.AW61Jmr64s9VNQLuhpU8gYrgzCapwka' passhash: '$2y$10$nmTcpRxs.RFUstkJJms6U.AW61Jmr64s9VNQLuhpU8gYrgzCapwka'
roles: ["application_user"] roles: ["application_user"]
saml: saml:
# Enable SAML authentication
enabled: false enabled: false
authorizerName: saml # Name of the method
#authorizerName: saml
# Java KeyStore configuration
keystore: keystore:
path: /data/_srv/dariahsp/c105-229.cloud.gwdg.de.jks path: /path/to/keystore.jks
pass: clariah pass: keystore_password
alias: c105-229.cloud.gwdg.de alias: keypair_alias
aliaspass: clariah6 aliaspass: private_key_password
# IdP configuration
metadata: metadata:
# URL of IdP metadata
url: https://aaiproxy.de.dariah.eu/idp/ url: https://aaiproxy.de.dariah.eu/idp/
# Hosted SP configuration
sp: sp:
# Metadata in filesystem (if available, otherwise generated)
#metadataResource: /data/_srv/dariahsp/sp_metadata.xml #metadataResource: /data/_srv/dariahsp/sp_metadata.xml
maxAuthAge: -1 # Maximum authentication lifetime in seconds
# maxAuthAge: 3600
#entityId: ${baseUrl} #entityId: ${baseUrl}
signMetadata: true # Signature configuration
#signMetadata: true
#signingMethods: "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" #signingMethods: "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
#digestMethods: http://www.w3.org/2001/04/xmlenc#sha256, http://www.w3.org/2001/04/xmlenc#sha512 #digestMethods: http://www.w3.org/2001/04/xmlenc#sha256, http://www.w3.org/2001/04/xmlenc#sha512
#authnRequestSigned: true
#logoutRequestSigned: true
#wantsAssertionsSigned: true
#wantsResponsesSigned: false
# SAML SP protocol configuration
#supportedProtocols: urn:oasis:names:tc:SAML:2.0:protocol #supportedProtocols: urn:oasis:names:tc:SAML:2.0:protocol
authnRequestSigned: truevv # Timeout for interaction with configured IdP
logoutRequestSigned: true #httpClientTimoutMs: 2000
wantsAssertionsSigned: true # URL for redirection after RequiredAttributesException is raised
wantsResponsesSigned: false
httpClientTimoutMs: 2000
attributesIncompleteRedirectUrl: https://auth.de.dariah.eu/cgi-bin/selfservice/ldapportal.pl attributesIncompleteRedirectUrl: https://auth.de.dariah.eu/cgi-bin/selfservice/ldapportal.pl
# Attribute groups for attribute mapping and required attribute definition
attributeGroups: attributeGroups:
# All attributes are required
- check: AND - check: AND
attributes: 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 - friendlyName: dariahTermsOfUse
name: urn:oid:1.3.6.1.4.1.10126.1.52.4.15 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 nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
# A required value of the attribute can be defined
#value: Terms_of_Use_germ_engl_v6.pdf #value: Terms_of_Use_germ_engl_v6.pdf
- friendlyName: eduPersonPrincipalName - friendlyName: eduPersonPrincipalName
mappedAttribute: id mappedAttribute: id
name: urn:oid:1.3.6.1.4.1.5923.1.1.1.6 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 nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
# Optional attributes are typically used for mapping SAML attributes to ExtendedUserProfile propeties
# like username, externalRoles below
- check: OPTIONAL - check: OPTIONAL
attributes: attributes:
- friendlyName: mail - friendlyName: mail
......
## DARIAHSP - Sample boot app ## DARIAHSP - Sample boot app
\ No newline at end of file
This Spring Boot application serves as simple reference implementation of the [dariahsp-core](../dariashp-core) library. The sample is based on Java ServerPages (JSP) for view rendering and presents itself with login, logout and protected areas.
> See the JavaDoc for further explanation on the components of the sample application
### Initialization
1. [`SampleApplication`](/src/main/java/eu/dariah/de/dariahsp/sample/SampleApplication.java) is the Spring Boot application class and handles initialization
### Configuration
2. [`SampleConfig`](/src/main/java/eu/dariah/de/dariahsp/sample/config/SampleApplication.java) serves as primary application configuration class; it defines the beans of
* `profileActionPostprocessor` (optional) for processing of login and logout activity,
* `samlMetadataController`, a controller bean that facilitates access to metadata of the SP and
* `webServerFactoryCustomizer` for changing the context path of the application
> With a optional custom implementation of the `profileActionPostprocessor`, the `SampleConfig` class can be used as a starting point for configuring futher aspects of the implementing application
3. [`SampleSecurityConfig`](/src/main/java/eu/dariah/de/dariahsp/sample/config/SampleSecurityConfig.java) - by extending the basic `SecurityConfig` class - imports the beans and configuration of the core library; it further imports configuration of the `AuthInfoConfigurer` class; The `@ConfigurationProperties(prefix = "auth")` annotation provides all configuration properties to the implemented `dariahsp-core` configuration
> The `SampleSecurityConfig` can be used 'as is' in other implementations as all security-related beans are soundly configured
4. [`SampleWebSecurityConfig`](/src/main/java/eu/dariah/de/dariahsp/sample/config/SampleWebSecurityConfig.java) is the basic `WebSecurityConfigurerAdapter` of the sample application and specifies URL and authorization patterns that are specific to the sample application
> The `SampleWebSecurityConfig` can be used as a starting point for configuring protected areas of the implementing application, but will probably require adaption to existing requirements
### Controllers
5. The [`SampleController`](/src/main/java/eu/dariah/de/dariahsp/sample/controller/SampleController.java) configures the request mappings and views of the sample application
6. [`ErrorController`](/src/main/java/eu/dariah/de/dariahsp/sample/controller/ErrorController.java) as implementation of Spring's `BasicErrorController` configures handling of exceptions that could occur in the application. For the sample application, all errors (e.g. 403 errors attempting to access protected areas) are dispatched to the `index` view, providing error messages
### Profile actions
7. [`SampleProfileActionHandler`](/src/main/java/eu/dariah/de/dariahsp/sample/profiles/SampleProfileActionHandler.java) is an empty implementation of the `ProfileActionHandler` interface - a bean provided that is setup in [`SampleConfig`](/src/main/java/eu/dariah/de/dariahsp/sample/config/SampleApplication.java). Customize behavior upon login and logout e.g. to persist user information in a database or to load save custom attributes of users and adding them to the attribute set of the handled `ExtendedUserProfile`
### Resources
8. [`application.yml`](/src/main/resources/application.yml) is a sample application configuration provided with this application
9. [`logback.xml`](/src/main/resources/application.yml) customizes logging through [logback](http://logback.qos.ch/)
10. [`sample_keystore.jks`](/src/main/resources/application.yml) is an example Java KeyStore that can be used for initial testing
### JSP views
11. [`index.jsp`](/src/main/webapp/WEB-INF/views/index.jsp) is the main view of the sample application that serves all succeeding and error requests.
12. [`login.jsp`](/src/main/webapp/WEB-INF/views/login.jsp) is the form for querying username and passwords of `local` logins.
\ No newline at end of file
...@@ -6,19 +6,7 @@ dependencies { ...@@ -6,19 +6,7 @@ dependencies {
implementation 'org.apache.tomcat.embed:tomcat-embed-jasper' implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
implementation "javax.servlet:jstl" implementation "javax.servlet:jstl"
//providedCompile "javax.servlet:javax.servlet-api"
//providedCompile "javax.servlet.jsp:javax.servlet.jsp-api:$jspApiVersion"
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools' developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
//providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation librarySets.commonTest
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
} }