This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/master by this push:
new ce32533 Making Payara working again (#199)
ce32533 is described below
commit ce3253355f26507f56cea0d00bc9adf68520c508
Author: Francesco Chicchiriccò <[email protected]>
AuthorDate: Sat Jun 20 19:23:54 2020 +0200
Making Payara working again (#199)
---
.travis.yml | 6 +-
.../core/rest/cxf/batch/BatchItemRequest.java | 98 +++++++++++++++++++---
.../provisioning/java/ProvisioningContext.java | 79 ++++++++++++++++-
.../DefaultNotificationJobDelegate.java | 42 +---------
.../core/spring/security/AuthDataAccessor.java | 5 +-
.../core/spring/security/JWTAuthentication.java | 53 ++++++++++++
.../spring/security/JWTAuthenticationFilter.java | 38 ++++++---
.../spring/security/JWTAuthenticationProvider.java | 14 +---
.../UsernamePasswordAuthenticationProvider.java | 4 +-
.../core/spring/security/WebSecurityContext.java | 61 +++++---------
.../client/self/SelfKeymasterServiceOps.java | 25 +-----
.../api/service/NetworkServiceService.java | 17 ++--
.../cxf/service/NetworkServiceServiceImpl.java | 17 ++--
fit/build-tools/pom.xml | 12 +--
.../src/main/webapp/WEB-INF/payara-web.xml} | 16 ++--
fit/core-reference/pom.xml | 32 +++++--
.../src/main/webapp/WEB-INF/payara-web.xml | 3 -
.../src/main/webapp/WEB-INF/payara-web.xml} | 16 ++--
pom.xml | 2 +-
19 files changed, 348 insertions(+), 192 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 428e276..c2a2b81 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -92,9 +92,9 @@ jobs:
- stage: fit
name: "Integration Tests: Wildfly / H2 / JSON Content-Type"
script: mvn -f fit/core-reference/pom.xml -P wildfly-it
-Dinvoker.streamLogs=true -Dmodernizer.skip=true -Dianal.skip=true
-Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true
- #- stage: fit
- #name: "Integration Tests: Payara / H2 / JSON Content-Type"
- #script: mvn -f fit/core-reference/pom.xml -P payara-it
-Dinvoker.streamLogs=true -Dmodernizer.skip=true -Dianal.skip=true
-Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true
+ - stage: fit
+ name: "Integration Tests: Payara / H2 / JSON Content-Type"
+ script: mvn -f fit/core-reference/pom.xml -P payara-it
-Dinvoker.streamLogs=true -Dmodernizer.skip=true -Dianal.skip=true
-Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true
- stage: fit
name: "Integration Tests: Tomcat / PostgreSQL / JSON Content-Type"
script: mvn -f fit/core-reference/pom.xml -P postgres-it
-Dinvoker.streamLogs=true -Dmodernizer.skip=true -Dianal.skip=true
-Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true
diff --git
a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/batch/BatchItemRequest.java
b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/batch/BatchItemRequest.java
index 75002c3..c8ce65f 100644
---
a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/batch/BatchItemRequest.java
+++
b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/batch/BatchItemRequest.java
@@ -20,20 +20,30 @@ package org.apache.syncope.core.rest.cxf.batch;
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Enumeration;
+import java.util.HashSet;
import java.util.List;
+import java.util.Optional;
+import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.ws.rs.core.HttpHeaders;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
import org.apache.syncope.common.rest.api.batch.BatchRequestItem;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
public class BatchItemRequest extends HttpServletRequestWrapper {
+ private static final Logger LOG =
LoggerFactory.getLogger(BatchItemRequest.class);
+
private final String basePath;
private final BatchRequestItem batchItem;
@@ -86,6 +96,28 @@ public class BatchItemRequest extends
HttpServletRequestWrapper {
}
@Override
+ public String getServerName() {
+ try {
+ return super.getServerName();
+ } catch (Exception e) {
+ LOG.debug("While delegating to wrapped request", e);
+ return Optional.ofNullable(getHeader(HttpHeaders.HOST)).
+ map(host -> StringUtils.substringBefore(host,
":")).orElse(null);
+ }
+ }
+
+ @Override
+ public int getServerPort() {
+ try {
+ return super.getServerPort();
+ } catch (Exception e) {
+ LOG.debug("While delegating to wrapped request", e);
+ return Optional.ofNullable(getHeader(HttpHeaders.HOST)).
+ map(host ->
NumberUtils.toInt(StringUtils.substringAfter(host, ":"))).orElse(0);
+ }
+ }
+
+ @Override
public StringBuffer getRequestURL() {
return new StringBuffer(basePath).append(getRequestURI());
}
@@ -121,21 +153,65 @@ public class BatchItemRequest extends
HttpServletRequestWrapper {
@Override
public String getHeader(final String name) {
- return batchItem.getHeaders().containsKey(name)
- ? batchItem.getHeaders().get(name).get(0).toString()
- : HttpHeaders.CONTENT_TYPE.equals(name) ||
HttpHeaders.ACCEPT.equals(name)
- ? MediaType.ALL_VALUE
- : super.getHeader(name);
+ try {
+ return batchItem.getHeaders().containsKey(name)
+ ? batchItem.getHeaders().get(name).get(0).toString()
+ : HttpHeaders.CONTENT_TYPE.equals(name) ||
HttpHeaders.ACCEPT.equals(name)
+ ? MediaType.ALL_VALUE
+ : super.getHeader(name);
+ } catch (Exception e) {
+ LOG.debug("While delegating to wrapped request", e);
+ return null;
+ }
}
@Override
public Enumeration<String> getHeaders(final String name) {
- return batchItem.getHeaders().containsKey(name)
- ? Collections.enumeration(
-
batchItem.getHeaders().get(name).stream().map(Object::toString).collect(Collectors.toList()))
- : HttpHeaders.CONTENT_TYPE.equals(name) ||
HttpHeaders.ACCEPT.equals(name)
- ? Collections.enumeration(List.of(MediaType.ALL_VALUE))
- : super.getHeaders(name);
+ try {
+ return batchItem.getHeaders().containsKey(name)
+ ?
Collections.enumeration(batchItem.getHeaders().get(name).stream().
+ map(Object::toString).collect(Collectors.toList()))
+ : HttpHeaders.CONTENT_TYPE.equals(name) ||
HttpHeaders.ACCEPT.equals(name)
+ ? Collections.enumeration(List.of(MediaType.ALL_VALUE))
+ : super.getHeaders(name);
+ } catch (Exception e) {
+ LOG.debug("While delegating to wrapped request", e);
+ return Collections.emptyEnumeration();
+ }
+ }
+
+ @Override
+ public Enumeration<String> getHeaderNames() {
+ try {
+ return super.getHeaderNames();
+ } catch (Exception e) {
+ LOG.debug("While delegating to wrapped request", e);
+
+ Set<String> names = new HashSet<>(batchItem.getHeaders().keySet());
+ names.add(HttpHeaders.CONTENT_TYPE);
+ names.add(HttpHeaders.ACCEPT);
+ return Collections.enumeration(names);
+ }
+ }
+
+ @Override
+ public Object getAttribute(final String name) {
+ try {
+ return super.getAttribute(name);
+ } catch (Exception e) {
+ LOG.debug("While delegating to wrapped request", e);
+ return null;
+ }
+ }
+
+ @Override
+ public String getCharacterEncoding() {
+ try {
+ return super.getCharacterEncoding();
+ } catch (Exception e) {
+ LOG.debug("While delegating to wrapped request", e);
+ return StandardCharsets.UTF_8.name();
+ }
}
@Override
diff --git
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java
index bad7363..b83c66f 100644
---
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java
+++
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java
@@ -18,13 +18,23 @@
*/
package org.apache.syncope.core.provisioning.java;
+import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
+import java.util.Enumeration;
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import javax.annotation.Resource;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.naming.NamingException;
import javax.sql.DataSource;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.LogOutputStream;
+import org.apache.syncope.common.lib.PropertyUtils;
import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
import org.apache.syncope.core.provisioning.api.AuditManager;
import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
@@ -41,6 +51,8 @@ import
org.apache.syncope.core.provisioning.java.job.JobManagerImpl;
import org.apache.syncope.core.provisioning.java.job.SchedulerDBInit;
import org.apache.syncope.core.provisioning.java.job.SchedulerShutdown;
import
org.apache.syncope.core.provisioning.java.propagation.PropagationManagerImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationContext;
@@ -55,6 +67,7 @@ import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
+import org.springframework.jndi.JndiObjectFactoryBean;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.scheduling.annotation.AsyncConfigurer;
@@ -74,6 +87,8 @@ import
org.springframework.transaction.PlatformTransactionManager;
@Configuration
public class ProvisioningContext implements EnvironmentAware, AsyncConfigurer {
+ private static final Logger LOG =
LoggerFactory.getLogger(ProvisioningContext.class);
+
@Resource(name = "MasterDataSource")
private DataSource masterDataSource;
@@ -188,14 +203,74 @@ public class ProvisioningContext implements
EnvironmentAware, AsyncConfigurer {
@ConditionalOnMissingBean
@Bean
- public JavaMailSender mailSender() {
- JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
+ public JavaMailSender mailSender() throws IllegalArgumentException,
NamingException {
+ JavaMailSenderImpl mailSender = new JavaMailSenderImpl() {
+
+ @Override
+ protected Transport connectTransport() throws MessagingException {
+ // ensure that no auth means no auth
+ if (StringUtils.isBlank(getUsername())) {
+ Transport transport = getTransport(getSession());
+ transport.connect(getHost(), getPort(), null, null);
+ return transport;
+ }
+
+ return super.connectTransport();
+ }
+ };
mailSender.setDefaultEncoding(env.getProperty("smtpEncoding"));
mailSender.setHost(env.getProperty("smtpHost"));
mailSender.setPort(env.getProperty("smtpPort", Integer.class));
mailSender.setUsername(env.getProperty("smtpUsername"));
mailSender.setPassword(env.getProperty("smtpPassword"));
mailSender.setProtocol(env.getProperty("smtpProtocol"));
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("[Mail] host:port = {}:{}", mailSender.getHost(),
mailSender.getPort());
+ LOG.debug("[Mail] protocol = {}", mailSender.getProtocol());
+ LOG.debug("[Mail] username = {}", mailSender.getUsername());
+ LOG.debug("[Mail] default encoding = {}",
mailSender.getDefaultEncoding());
+ }
+
+ JndiObjectFactoryBean mailSession = new JndiObjectFactoryBean();
+ mailSession.setJndiName("mail/syncopeNotification");
+ try {
+ mailSession.afterPropertiesSet();
+ } catch (NamingException e) {
+ LOG.debug("While looking up JNDI for mail session", e);
+ }
+
+ Session session = (Session) mailSession.getObject();
+ if (session == null) {
+ Properties javaMailProperties = mailSender.getJavaMailProperties();
+
+ Properties props = PropertyUtils.read(ProvisioningContext.class,
"mail.properties", "conf.directory");
+ for (Enumeration<?> e = props.propertyNames();
e.hasMoreElements();) {
+ String prop = (String) e.nextElement();
+ if (prop.startsWith("mail.smtp.")) {
+ javaMailProperties.setProperty(prop,
props.getProperty(prop));
+ }
+ }
+
+ if (StringUtils.isNotBlank(mailSender.getUsername())) {
+ javaMailProperties.setProperty("mail.smtp.auth", "true");
+ }
+
+ if (LOG.isDebugEnabled()) {
+ mailSender.getJavaMailProperties().
+ forEach((key, value) -> LOG.debug("[Mail] property: {}
= {}", key, value));
+ }
+
+ String mailDebug = props.getProperty("mail.debug", "false");
+ if (BooleanUtils.toBoolean(mailDebug)) {
+ session = mailSender.getSession();
+ session.setDebug(true);
+ session.setDebugOut(new PrintStream(new LogOutputStream(LOG)));
+ }
+ } else {
+ mailSender.setSession(session);
+ }
+
return mailSender;
}
diff --git
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/DefaultNotificationJobDelegate.java
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/DefaultNotificationJobDelegate.java
index 6c5ff84..13a700b 100644
---
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/DefaultNotificationJobDelegate.java
+++
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/DefaultNotificationJobDelegate.java
@@ -18,18 +18,11 @@
*/
package org.apache.syncope.core.provisioning.java.job.notification;
-import java.io.PrintStream;
import java.util.Date;
-import java.util.Enumeration;
import java.util.List;
-import java.util.Properties;
import java.util.concurrent.atomic.AtomicReference;
-import javax.mail.Session;
import javax.mail.internet.MimeMessage;
-import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.LogOutputStream;
-import org.apache.syncope.common.lib.PropertyUtils;
import org.apache.syncope.common.lib.types.AuditElements;
import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.common.lib.types.TraceLevel;
@@ -42,20 +35,17 @@ import
org.apache.syncope.core.provisioning.api.AuditManager;
import
org.apache.syncope.core.provisioning.api.notification.NotificationJobDelegate;
import
org.apache.syncope.core.provisioning.api.notification.NotificationManager;
import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.apache.syncope.core.spring.security.Encryptor;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
-import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
-public class DefaultNotificationJobDelegate implements InitializingBean,
NotificationJobDelegate {
+public class DefaultNotificationJobDelegate implements NotificationJobDelegate
{
private static final Logger LOG =
LoggerFactory.getLogger(NotificationJobDelegate.class);
@@ -81,36 +71,6 @@ public class DefaultNotificationJobDelegate implements
InitializingBean, Notific
private boolean interrupted;
@Override
- public void afterPropertiesSet() throws Exception {
- if (mailSender instanceof JavaMailSenderImpl) {
- JavaMailSenderImpl javaMailSender = (JavaMailSenderImpl)
mailSender;
-
- Properties javaMailProperties =
javaMailSender.getJavaMailProperties();
-
- Properties props = PropertyUtils.read(Encryptor.class,
"mail.properties", "conf.directory");
- for (Enumeration<?> e = props.propertyNames();
e.hasMoreElements();) {
- String prop = (String) e.nextElement();
- if (prop.startsWith("mail.smtp.")) {
- javaMailProperties.setProperty(prop,
props.getProperty(prop));
- }
- }
-
- if (StringUtils.isNotBlank(javaMailSender.getUsername())) {
- javaMailProperties.setProperty("mail.smtp.auth", "true");
- }
-
- javaMailSender.setJavaMailProperties(javaMailProperties);
-
- String mailDebug = props.getProperty("mail.debug", "false");
- if (BooleanUtils.toBoolean(mailDebug)) {
- Session session = javaMailSender.getSession();
- session.setDebug(true);
- session.setDebugOut(new PrintStream(new LogOutputStream(LOG)));
- }
- }
- }
-
- @Override
public String currentStatus() {
return status.get();
}
diff --git
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
index 4d00c99..125b5f6 100644
---
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
+++
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
@@ -244,7 +244,7 @@ public class AuthDataAccessor {
Optional<String> connObjectKeyValue =
mappingManager.getConnObjectKeyValue(user, provision.get());
if (connObjectKeyValue.isEmpty()) {
throw new AccountNotFoundException(
- "Unable to locate conn object key value for " +
userType.getKey());
+ "Unable to locate conn object key value for " +
userType.getKey());
}
connObjectKey = connObjectKeyValue.get();
Uid uid =
connFactory.getConnector(resource).authenticate(connObjectKey, password, null);
@@ -405,8 +405,7 @@ public class AuthDataAccessor {
if (BooleanUtils.isTrue(user.isMustChangePassword())) {
LOG.debug("User {} must change password, resetting
authorities", username);
- authorities = Set.of(
- new
SyncopeGrantedAuthority(IdRepoEntitlement.MUST_CHANGE_PASSWORD));
+ authorities = Set.of(new
SyncopeGrantedAuthority(IdRepoEntitlement.MUST_CHANGE_PASSWORD));
}
}
diff --git
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthentication.java
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthentication.java
index ab9f3d2..846693c 100644
---
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthentication.java
+++
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthentication.java
@@ -22,7 +22,10 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
import org.springframework.security.core.Authentication;
@@ -92,4 +95,54 @@ public class JWTAuthentication implements Authentication {
public String getName() {
return Optional.ofNullable(username).orElseGet(claims::getSubject);
}
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().
+ append(claims).
+ append(details).
+ append(username).
+ append(authorities).
+ append(authenticated).
+ build();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final JWTAuthentication other = (JWTAuthentication) obj;
+ return new EqualsBuilder().
+ append(claims, other.claims).
+ append(details, other.details).
+ append(username, other.username).
+ append(authorities, other.authorities).
+ append(authenticated, other.authenticated).
+ build();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(super.toString()).append(": ");
+ sb.append("Principal: ").append(this.getPrincipal()).append("; ");
+ sb.append("Authenticated: ").append(this.isAuthenticated()).append(";
");
+ sb.append("Details: ").append(this.getDetails()).append("; ");
+
+ if (!authorities.isEmpty()) {
+ sb.append("Granted Authorities: ");
+
sb.append(authorities.stream().map(SyncopeGrantedAuthority::toString).collect(Collectors.joining(",
")));
+ } else {
+ sb.append("Not granted any authorities");
+ }
+
+ return sb.toString();
+ }
}
diff --git
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationFilter.java
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationFilter.java
index e82f294..e78c494 100644
---
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationFilter.java
+++
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationFilter.java
@@ -20,16 +20,17 @@ package org.apache.syncope.core.spring.security;
import java.io.IOException;
import java.util.Optional;
+import java.util.Set;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.HttpHeaders;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.cxf.rs.security.jose.jws.JwsException;
import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
@@ -45,20 +46,26 @@ public class JWTAuthenticationFilter extends
BasicAuthenticationFilter {
private static final Logger LOG =
LoggerFactory.getLogger(JWTAuthenticationFilter.class);
- @Autowired
- private AuthenticationEntryPoint authenticationEntryPoint;
+ private final AuthenticationEntryPoint authenticationEntryPoint;
- @Autowired
- private SyncopeAuthenticationDetailsSource authenticationDetailsSource;
+ private final SyncopeAuthenticationDetailsSource
authenticationDetailsSource;
- @Autowired
- private AuthDataAccessor dataAccessor;
+ private final AuthDataAccessor dataAccessor;
- @Autowired
- private DefaultCredentialChecker credentialChecker;
+ private final DefaultCredentialChecker credentialChecker;
+
+ public JWTAuthenticationFilter(
+ final AuthenticationManager authenticationManager,
+ final AuthenticationEntryPoint authenticationEntryPoint,
+ final SyncopeAuthenticationDetailsSource
authenticationDetailsSource,
+ final AuthDataAccessor dataAccessor,
+ final DefaultCredentialChecker credentialChecker) {
- public JWTAuthenticationFilter(final AuthenticationManager
authenticationManager) {
super(authenticationManager);
+ this.authenticationEntryPoint = authenticationEntryPoint;
+ this.authenticationDetailsSource = authenticationDetailsSource;
+ this.dataAccessor = dataAccessor;
+ this.credentialChecker = credentialChecker;
}
@Override
@@ -87,8 +94,15 @@ public class JWTAuthenticationFilter extends
BasicAuthenticationFilter {
throw new BadCredentialsException("Invalid signature found in
JWT");
}
- SecurityContextHolder.getContext().setAuthentication(
- new JWTAuthentication(consumer.getJwtClaims(),
authenticationDetailsSource.buildDetails(request)));
+ JWTAuthentication jwtAuthentication =
+ new JWTAuthentication(consumer.getJwtClaims(),
authenticationDetailsSource.buildDetails(request));
+
AuthContextUtils.callAsAdmin(jwtAuthentication.getDetails().getDomain(), () -> {
+ Pair<String, Set<SyncopeGrantedAuthority>> authenticated =
dataAccessor.authenticate(jwtAuthentication);
+ jwtAuthentication.setUsername(authenticated.getLeft());
+
jwtAuthentication.getAuthorities().addAll(authenticated.getRight());
+ return null;
+ });
+
SecurityContextHolder.getContext().setAuthentication(jwtAuthentication);
chain.doFilter(request, response);
} catch (JwsException e) {
diff --git
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationProvider.java
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationProvider.java
index c8fb6fb..9580070 100644
---
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationProvider.java
+++
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationProvider.java
@@ -18,9 +18,6 @@
*/
package org.apache.syncope.core.spring.security;
-import java.util.Date;
-import java.util.Set;
-import org.apache.commons.lang3.tuple.Pair;
import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
@@ -39,17 +36,10 @@ public class JWTAuthenticationProvider implements
AuthenticationProvider {
@Override
public Authentication authenticate(final Authentication authentication)
throws AuthenticationException {
- final JWTAuthentication jwtAuthentication = (JWTAuthentication)
authentication;
-
-
AuthContextUtils.callAsAdmin(jwtAuthentication.getDetails().getDomain(), () -> {
- Pair<String, Set<SyncopeGrantedAuthority>> authenticated =
dataAccessor.authenticate(jwtAuthentication);
- jwtAuthentication.setUsername(authenticated.getLeft());
-
jwtAuthentication.getAuthorities().addAll(authenticated.getRight());
- return null;
- });
+ JWTAuthentication jwtAuthentication = (JWTAuthentication)
authentication;
JwtClaims claims = jwtAuthentication.getClaims();
- Long referenceTime = new Date().getTime();
+ Long referenceTime = System.currentTimeMillis();
Long expiryTime = claims.getExpiryTime();
if (expiryTime == null || (expiryTime * 1000L) < referenceTime) {
diff --git
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java
index 9e7f712..76313ec 100644
---
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java
+++
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java
@@ -211,7 +211,7 @@ public class UsernamePasswordAuthenticationProvider
implements AuthenticationPro
}
@Override
- public boolean supports(final Class<? extends Object> type) {
- return type.equals(UsernamePasswordAuthenticationToken.class);
+ public boolean supports(final Class<?> authentication) {
+ return
UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}
diff --git
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/WebSecurityContext.java
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/WebSecurityContext.java
index 05dfc94..f421dd6 100644
---
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/WebSecurityContext.java
+++
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/WebSecurityContext.java
@@ -19,7 +19,9 @@
package org.apache.syncope.core.spring.security;
import javax.annotation.Resource;
+import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import
org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import
org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
@@ -29,13 +31,10 @@ import
org.springframework.security.config.annotation.web.configuration.EnableWe
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import
org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import
org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.context.NullSecurityContextRepository;
-import
org.springframework.security.web.context.SecurityContextPersistenceFilter;
-import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.security.web.firewall.DefaultHttpFirewall;
import org.springframework.security.web.firewall.HttpFirewall;
@@ -46,6 +45,9 @@ public class WebSecurityContext extends
WebSecurityConfigurerAdapter {
@Resource(name = "anonymousUser")
private String anonymousUser;
+ @Autowired
+ private ApplicationContext ctx;
+
public WebSecurityContext() {
super(true);
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
@@ -82,58 +84,39 @@ public class WebSecurityContext extends
WebSecurityConfigurerAdapter {
}
@Bean
- public SecurityContextRepository securityContextRepository() {
- return new NullSecurityContextRepository();
- }
-
- @Bean
- public SecurityContextPersistenceFilter securityContextPersistenceFilter()
{
- return new
SecurityContextPersistenceFilter(securityContextRepository());
+ public AccessDeniedHandler accessDeniedHandler() {
+ return new SyncopeAccessDeniedHandler();
}
- @Bean
- public AuthenticationEntryPoint basicAuthenticationEntryPoint() {
+ @Override
+ protected void configure(final HttpSecurity http) throws Exception {
SyncopeBasicAuthenticationEntryPoint basicAuthenticationEntryPoint =
new SyncopeBasicAuthenticationEntryPoint();
basicAuthenticationEntryPoint.setRealmName("Apache Syncope
authentication");
- return basicAuthenticationEntryPoint;
- }
- @Bean
- public SyncopeAuthenticationDetailsSource authenticationDetailsSource() {
- return new SyncopeAuthenticationDetailsSource();
- }
+ SyncopeAuthenticationDetailsSource authenticationDetailsSource = new
SyncopeAuthenticationDetailsSource();
- @Bean
- public AccessDeniedHandler accessDeniedHandler() {
- return new SyncopeAccessDeniedHandler();
- }
-
- @Bean
- public JWTAuthenticationFilter jwtAuthenticationFilter() throws Exception {
- return new JWTAuthenticationFilter(authenticationManager());
- }
+ JWTAuthenticationFilter jwtAuthenticationFilter = new
JWTAuthenticationFilter(
+ authenticationManager(),
+ basicAuthenticationEntryPoint,
+ authenticationDetailsSource,
+ ctx.getBean(AuthDataAccessor.class),
+ ctx.getBean(DefaultCredentialChecker.class));
- @Bean
- public MustChangePasswordFilter mustChangePasswordFilter() {
- return new MustChangePasswordFilter();
- }
-
- @Override
- protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests().
antMatchers("/**").permitAll().and().
sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().
-
securityContext().securityContextRepository(securityContextRepository()).and().
+ securityContext().securityContextRepository(new
NullSecurityContextRepository()).and().
anonymous().principal(anonymousUser).and().
-
httpBasic().authenticationEntryPoint(basicAuthenticationEntryPoint()).
-
authenticationDetailsSource(authenticationDetailsSource()).and().
+
httpBasic().authenticationEntryPoint(basicAuthenticationEntryPoint).
+ authenticationDetailsSource(authenticationDetailsSource).and().
exceptionHandling().accessDeniedHandler(accessDeniedHandler()).and().
- addFilterBefore(jwtAuthenticationFilter(),
BasicAuthenticationFilter.class).
- addFilterBefore(mustChangePasswordFilter(),
FilterSecurityInterceptor.class).
+ addFilterBefore(jwtAuthenticationFilter,
BasicAuthenticationFilter.class).
+ addFilterBefore(new MustChangePasswordFilter(),
FilterSecurityInterceptor.class).
headers().disable().
csrf().disable();
}
+ @ConditionalOnMissingBean
@Bean
public AuthDataAccessor authDataAccessor() {
return new AuthDataAccessor();
diff --git
a/ext/self-keymaster/client/src/main/java/org/apache/syncope/common/keymaster/client/self/SelfKeymasterServiceOps.java
b/ext/self-keymaster/client/src/main/java/org/apache/syncope/common/keymaster/client/self/SelfKeymasterServiceOps.java
index 99d3b64..d52abea 100644
---
a/ext/self-keymaster/client/src/main/java/org/apache/syncope/common/keymaster/client/self/SelfKeymasterServiceOps.java
+++
b/ext/self-keymaster/client/src/main/java/org/apache/syncope/common/keymaster/client/self/SelfKeymasterServiceOps.java
@@ -21,7 +21,6 @@ package org.apache.syncope.common.keymaster.client.self;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletionStage;
-import javax.ws.rs.HttpMethod;
import javax.ws.rs.Path;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
@@ -31,6 +30,7 @@ import
org.apache.syncope.common.keymaster.client.api.KeymasterException;
import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
import org.apache.syncope.common.keymaster.client.api.ServiceOps;
import org.apache.syncope.ext.self.keymaster.api.service.NetworkServiceService;
+import
org.apache.syncope.ext.self.keymaster.api.service.NetworkServiceService.Action;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.backoff.BackOffExecution;
@@ -38,12 +38,6 @@ import org.springframework.util.backoff.ExponentialBackOff;
public class SelfKeymasterServiceOps extends SelfKeymasterOps implements
ServiceOps {
- private enum Action {
- register,
- unregister
-
- }
-
private static final Logger LOG =
LoggerFactory.getLogger(ServiceOps.class);
private final int maxRetries;
@@ -129,22 +123,7 @@ public class SelfKeymasterServiceOps extends
SelfKeymasterOps implements Service
}
private CompletionStage<Response> completionStage(final Action action,
final NetworkService service) {
- CompletionStage<Response> completionStage = null;
- switch (action) {
- case register:
- completionStage = rx(path).
- post(Entity.entity(service,
MediaType.APPLICATION_JSON));
- break;
-
- case unregister:
- completionStage = rx(path).
- method(HttpMethod.DELETE, Entity.entity(service,
MediaType.APPLICATION_JSON));
- break;
-
- default:
- }
-
- return completionStage;
+ return rx(path + "?action=" +
action.name()).post(Entity.entity(service, MediaType.APPLICATION_JSON));
}
@Override
diff --git
a/ext/self-keymaster/rest-api/src/main/java/org/apache/syncope/ext/self/keymaster/api/service/NetworkServiceService.java
b/ext/self-keymaster/rest-api/src/main/java/org/apache/syncope/ext/self/keymaster/api/service/NetworkServiceService.java
index d7d1845..aade9af 100644
---
a/ext/self-keymaster/rest-api/src/main/java/org/apache/syncope/ext/self/keymaster/api/service/NetworkServiceService.java
+++
b/ext/self-keymaster/rest-api/src/main/java/org/apache/syncope/ext/self/keymaster/api/service/NetworkServiceService.java
@@ -23,12 +23,12 @@ import java.util.List;
import java.util.concurrent.CompletableFuture;
import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
@@ -39,6 +39,12 @@ import
org.apache.syncope.common.keymaster.client.api.model.NetworkService;
@Path("networkServices")
public interface NetworkServiceService extends Serializable {
+ enum Action {
+ register,
+ unregister
+
+ }
+
@GET
@Path("{serviceType}")
@Produces({ MediaType.APPLICATION_JSON })
@@ -52,10 +58,7 @@ public interface NetworkServiceService extends Serializable {
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
- CompletableFuture<Response> register(@NotNull NetworkService
networkService);
-
- @DELETE
- @Consumes({ MediaType.APPLICATION_JSON })
- @Produces({ MediaType.APPLICATION_JSON })
- CompletableFuture<Response> unregister(@NotNull NetworkService
networkService);
+ CompletableFuture<Response> action(
+ @NotNull NetworkService networkService,
+ @QueryParam("action") Action action);
}
diff --git
a/ext/self-keymaster/rest-cxf/src/main/java/org/apache/syncope/ext/self/keymaster/cxf/service/NetworkServiceServiceImpl.java
b/ext/self-keymaster/rest-cxf/src/main/java/org/apache/syncope/ext/self/keymaster/cxf/service/NetworkServiceServiceImpl.java
index 8bf3ed8..e04c350 100644
---
a/ext/self-keymaster/rest-cxf/src/main/java/org/apache/syncope/ext/self/keymaster/cxf/service/NetworkServiceServiceImpl.java
+++
b/ext/self-keymaster/rest-cxf/src/main/java/org/apache/syncope/ext/self/keymaster/cxf/service/NetworkServiceServiceImpl.java
@@ -48,18 +48,13 @@ public class NetworkServiceServiceImpl implements
NetworkServiceService {
@PreAuthorize("@environment.getProperty('keymaster.username') ==
authentication.name and not(isAnonymous())")
@Override
- public CompletableFuture<Response> register(final NetworkService
networkService) {
+ public CompletableFuture<Response> action(final NetworkService
networkService, final Action action) {
return CompletableFuture.supplyAsync(() -> {
- logic.register(networkService);
- return Response.noContent().build();
- });
- }
-
- @PreAuthorize("@environment.getProperty('keymaster.username') ==
authentication.name and not(isAnonymous())")
- @Override
- public CompletableFuture<Response> unregister(final NetworkService
networkService) {
- return CompletableFuture.supplyAsync(() -> {
- logic.unregister(networkService);
+ if (action == Action.unregister) {
+ logic.unregister(networkService);
+ } else {
+ logic.register(networkService);
+ }
return Response.noContent().build();
});
}
diff --git a/fit/build-tools/pom.xml b/fit/build-tools/pom.xml
index e823618..bf3e431 100644
--- a/fit/build-tools/pom.xml
+++ b/fit/build-tools/pom.xml
@@ -371,11 +371,6 @@ under the License.
<artifactId>jakarta.faces</artifactId>
<version>${javax.faces.version}</version>
</dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.dataformat</groupId>
- <artifactId>jackson-dataformat-xml</artifactId>
- </dependency>
</dependencies>
<build>
@@ -383,6 +378,13 @@ under the License.
<plugins>
<plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <packagingExcludes>WEB-INF/lib/bval-*.jar</packagingExcludes>
+ </configuration>
+ </plugin>
+
+ <plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<inherited>true</inherited>
diff --git a/fit/enduser-reference/src/main/webapp/WEB-INF/glassfish-web.xml
b/fit/console-reference/src/main/webapp/WEB-INF/payara-web.xml
similarity index 62%
rename from fit/enduser-reference/src/main/webapp/WEB-INF/glassfish-web.xml
rename to fit/console-reference/src/main/webapp/WEB-INF/payara-web.xml
index 6400bc2..6b646d0 100644
--- a/fit/enduser-reference/src/main/webapp/WEB-INF/glassfish-web.xml
+++ b/fit/console-reference/src/main/webapp/WEB-INF/payara-web.xml
@@ -16,10 +16,16 @@ software distributed under the License is distributed on an
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-
-->
-<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD
-GlassFish Application Server 3.1 Servlet 3.0//EN"
"http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
-<glassfish-web-app error-url="">
+<!DOCTYPE payara-web-app PUBLIC "-//Payara.fish//DTD Payara Server 4 Servlet
3.0//EN" "https://docs.payara.fish/schemas/payara-web-app_4.dtd">
+<payara-web-app error-url="">
+ <!-- Uncomment this when using JNDI DataSource -->
+ <!--<resource-ref>
+ <res-ref-name>jdbc/syncopeMasterDataSource</res-ref-name>
+ <jndi-name>jdbc/syncopeMasterDataSource</jndi-name>
+ </resource-ref>-->
<class-loader delegate="false"/>
-</glassfish-web-app>
+ <jsp-config>
+ <property name="httpMethods" value="GET,POST,HEAD,PUT,DELETE"/>
+ </jsp-config>
+</payara-web-app>
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index f6c3a15..eb6ff13 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -1519,7 +1519,6 @@ under the License.
</build>
</profile>
- <!-- Running IT with this profile requires prior build of ../build-tools
with -Ppayara -->
<profile>
<id>payara-it</id>
@@ -1541,11 +1540,6 @@ under the License.
<artifactId>jakarta.faces</artifactId>
<version>${javax.faces.version}</version>
</dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.dataformat</groupId>
- <artifactId>jackson-dataformat-xml</artifactId>
- </dependency>
</dependencies>
<build>
@@ -1553,6 +1547,30 @@ under the License.
<plugins>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <inherited>true</inherited>
+ <executions>
+ <execution>
+ <id>adjust-buildtools-for-payara</id>
+ <phase>prepare-package</phase>
+ <configuration>
+ <target>
+ <unzip
src="${settings.localRepository}/org/apache/syncope/fit/syncope-fit-build-tools/${project.version}/syncope-fit-build-tools-${project.version}.war"
+
dest="${project.build.outputDirectory}/syncope-fit-buildtools"/>
+ <delete
file="${project.build.outputDirectory}/syncope-fit-buildtools/WEB-INF/lib/bval-jsr-${bval.version}.jar"/>
+ <copy
file="${settings.localRepository}/org/glassfish/jakarta.faces/${javax.faces.version}/jakarta.faces-${javax.faces.version}.jar"
+
todir="${project.build.outputDirectory}/syncope-fit-buildtools/WEB-INF/lib"/>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<inherited>true</inherited>
@@ -1582,7 +1600,7 @@ under the License.
</configuration>
<deployables>
<deployable>
-
<location>${basedir}/../build-tools/target/syncope-fit-build-tools-${project.version}</location>
+
<location>${project.build.outputDirectory}/syncope-fit-buildtools</location>
<properties>
<context>syncope-fit-build-tools</context>
</properties>
diff --git a/fit/core-reference/src/main/webapp/WEB-INF/payara-web.xml
b/fit/core-reference/src/main/webapp/WEB-INF/payara-web.xml
index a32bda0..6b646d0 100644
--- a/fit/core-reference/src/main/webapp/WEB-INF/payara-web.xml
+++ b/fit/core-reference/src/main/webapp/WEB-INF/payara-web.xml
@@ -25,9 +25,6 @@ under the License.
<jndi-name>jdbc/syncopeMasterDataSource</jndi-name>
</resource-ref>-->
<class-loader delegate="false"/>
- <scanning-exclude>*</scanning-exclude>
- <scanning-exclude>*</scanning-exclude>
- <jaxrs-roles-allowed-enabled>false</jaxrs-roles-allowed-enabled>
<jsp-config>
<property name="httpMethods" value="GET,POST,HEAD,PUT,DELETE"/>
</jsp-config>
diff --git a/fit/console-reference/src/main/webapp/WEB-INF/glassfish-web.xml
b/fit/enduser-reference/src/main/webapp/WEB-INF/payara-web.xml
similarity index 62%
rename from fit/console-reference/src/main/webapp/WEB-INF/glassfish-web.xml
rename to fit/enduser-reference/src/main/webapp/WEB-INF/payara-web.xml
index 6400bc2..6b646d0 100644
--- a/fit/console-reference/src/main/webapp/WEB-INF/glassfish-web.xml
+++ b/fit/enduser-reference/src/main/webapp/WEB-INF/payara-web.xml
@@ -16,10 +16,16 @@ software distributed under the License is distributed on an
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-
-->
-<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD
-GlassFish Application Server 3.1 Servlet 3.0//EN"
"http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
-<glassfish-web-app error-url="">
+<!DOCTYPE payara-web-app PUBLIC "-//Payara.fish//DTD Payara Server 4 Servlet
3.0//EN" "https://docs.payara.fish/schemas/payara-web-app_4.dtd">
+<payara-web-app error-url="">
+ <!-- Uncomment this when using JNDI DataSource -->
+ <!--<resource-ref>
+ <res-ref-name>jdbc/syncopeMasterDataSource</res-ref-name>
+ <jndi-name>jdbc/syncopeMasterDataSource</jndi-name>
+ </resource-ref>-->
<class-loader delegate="false"/>
-</glassfish-web-app>
+ <jsp-config>
+ <property name="httpMethods" value="GET,POST,HEAD,PUT,DELETE"/>
+ </jsp-config>
+</payara-web-app>
diff --git a/pom.xml b/pom.xml
index fdb48fa..1eb67bf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -509,7 +509,7 @@ under the License.
<tomcat.version>9.0.36</tomcat.version>
<wildfly.version>20.0.0.Final</wildfly.version>
- <payara.version>5.201</payara.version>
+ <payara.version>5.2020.2</payara.version>
<javax.faces.version>2.3.14</javax.faces.version>
<docker.postgresql.version>12</docker.postgresql.version>