From c3f6b6ac27e794022c324de78a78465a88d00e59 Mon Sep 17 00:00:00 2001 From: Mingela Date: Fri, 19 Apr 2019 11:12:11 +0300 Subject: [PATCH 1/2] Added pac4j basic auth for rest --- brvs-core/build.gradle | 3 + .../java/iroha/validation/Application.java | 23 +++++++ .../iroha/validation/rest/RestService.java | 2 + .../security/BrvsAuthenticator.java | 65 +++++++++++++++++++ config/context/application.properties | 2 + config/context/spring-context.xml | 6 ++ 6 files changed, 101 insertions(+) create mode 100644 brvs-core/src/main/java/iroha/validation/security/BrvsAuthenticator.java diff --git a/brvs-core/build.gradle b/brvs-core/build.gradle index af48a96..893bc17 100644 --- a/brvs-core/build.gradle +++ b/brvs-core/build.gradle @@ -7,6 +7,9 @@ dependencies { compile('org.glassfish.jersey.containers:jersey-container-grizzly2-http:2.28') compile('org.glassfish.jersey.inject:jersey-hk2:2.28') compile('org.glassfish.jersey.media:jersey-media-json-jackson:2.28') + // Security + compile('org.pac4j:jersey-pac4j:3.0.0') + compile('org.pac4j:pac4j-http:3.6.1') // unit tests testCompile('org.junit.jupiter:junit-jupiter-api:5.4.0') diff --git a/brvs-core/src/main/java/iroha/validation/Application.java b/brvs-core/src/main/java/iroha/validation/Application.java index f9389fa..ab6630f 100644 --- a/brvs-core/src/main/java/iroha/validation/Application.java +++ b/brvs-core/src/main/java/iroha/validation/Application.java @@ -1,5 +1,6 @@ package iroha.validation; +import iroha.validation.security.BrvsAuthenticator; import iroha.validation.service.ValidationService; import iroha.validation.transactions.provider.RegistrationProvider; import iroha.validation.transactions.provider.impl.util.CacheProvider; @@ -10,6 +11,13 @@ import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.ServerProperties; +import org.pac4j.core.authorization.authorizer.IsAuthenticatedAuthorizer; +import org.pac4j.core.config.Config; +import org.pac4j.core.credentials.UsernamePasswordCredentials; +import org.pac4j.http.client.direct.DirectBasicAuthClient; +import org.pac4j.jax.rs.features.JaxRsConfigProvider; +import org.pac4j.jax.rs.features.Pac4JSecurityFeature; +import org.pac4j.jax.rs.grizzly.features.GrizzlyJaxRsContextFactoryProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.support.AbstractApplicationContext; @@ -44,6 +52,12 @@ protected void configure() { }); resourceConfig.property(ServerProperties.OUTBOUND_CONTENT_LENGTH_BUFFER, 0); + Config securityConfig = getSecurityConfig(context.getBean(UsernamePasswordCredentials.class)); + resourceConfig + .register(new JaxRsConfigProvider(securityConfig)) + .register(new GrizzlyJaxRsContextFactoryProvider()) + .register(new Pac4JSecurityFeature()); + int port = getPort(context); logger.info("Going to establish HTTP server on port " + port); GrizzlyHttpServerFactory @@ -62,4 +76,13 @@ private static int getPort(AbstractApplicationContext context) { } return portBean; } + + private static Config getSecurityConfig(UsernamePasswordCredentials credentials) { + DirectBasicAuthClient basicAuthClient = new DirectBasicAuthClient( + new BrvsAuthenticator(credentials) + ); + Config config = new Config(basicAuthClient); + config.addAuthorizer("brvs", new IsAuthenticatedAuthorizer()); + return config; + } } diff --git a/brvs-core/src/main/java/iroha/validation/rest/RestService.java b/brvs-core/src/main/java/iroha/validation/rest/RestService.java index 2eafa4e..f657936 100644 --- a/brvs-core/src/main/java/iroha/validation/rest/RestService.java +++ b/brvs-core/src/main/java/iroha/validation/rest/RestService.java @@ -26,9 +26,11 @@ import javax.ws.rs.core.StreamingOutput; import jp.co.soramitsu.iroha.java.IrohaAPI; import jp.co.soramitsu.iroha.java.Utils; +import org.pac4j.jax.rs.annotations.Pac4JSecurity; @Singleton @Path("") +@Pac4JSecurity(authorizers = "isAuthenticated") public class RestService { private final static Printer printer = JsonFormat.printer() diff --git a/brvs-core/src/main/java/iroha/validation/security/BrvsAuthenticator.java b/brvs-core/src/main/java/iroha/validation/security/BrvsAuthenticator.java new file mode 100644 index 0000000..4296a2d --- /dev/null +++ b/brvs-core/src/main/java/iroha/validation/security/BrvsAuthenticator.java @@ -0,0 +1,65 @@ +package iroha.validation.security; + +import com.google.common.base.Strings; +import java.util.Objects; +import org.pac4j.core.context.Pac4jConstants; +import org.pac4j.core.context.WebContext; +import org.pac4j.core.credentials.UsernamePasswordCredentials; +import org.pac4j.core.credentials.authenticator.Authenticator; +import org.pac4j.core.exception.CredentialsException; +import org.pac4j.core.profile.CommonProfile; +import org.pac4j.core.util.CommonHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BrvsAuthenticator implements Authenticator { + + private static final Logger logger = LoggerFactory.getLogger(BrvsAuthenticator.class); + + private final String correctUsername; + + private final String correctPassword; + + public BrvsAuthenticator(String username, String password) { + if (Strings.isNullOrEmpty(username)) { + throw new IllegalArgumentException("Username must not be null nor empty"); + } + if (Strings.isNullOrEmpty(password)) { + throw new IllegalArgumentException("Password must not be null nor empty"); + } + this.correctUsername = username; + this.correctPassword = password; + } + + public BrvsAuthenticator(UsernamePasswordCredentials credentials) { + Objects.requireNonNull(credentials, "Credentials must not be null"); + this.correctUsername = credentials.getUsername(); + this.correctPassword = credentials.getPassword(); + } + + @Override + public void validate(UsernamePasswordCredentials credentials, WebContext context) { + if (credentials == null) { + logger.error("No credentials provided to the authenticator."); + throw new CredentialsException("No credential"); + } + String username = credentials.getUsername(); + String password = credentials.getPassword(); + if (CommonHelper.isBlank(username) || CommonHelper.isBlank(password)) { + logger.error("Malformed credentials provided to the authenticator."); + throw new CredentialsException("Username or password cannot be blank"); + } + if (CommonHelper.areNotEquals(username, correctUsername)) { + logger.error("Username : '" + username + "' is unknown."); + throw new CredentialsException("Username : '" + username + "' is unknown."); + } + if (CommonHelper.areNotEquals(password, correctPassword)) { + logger.error("Username : '" + username + "' provided invalid password."); + throw new CredentialsException("Username : '" + username + "' provided invalid password."); + } + final CommonProfile profile = new CommonProfile(); + profile.setId(username); + profile.addAttribute(Pac4jConstants.USERNAME, username); + credentials.setUserProfile(profile); + } +} diff --git a/config/context/application.properties b/config/context/application.properties index 5d2e447..1b2bed2 100644 --- a/config/context/application.properties +++ b/config/context/application.properties @@ -6,6 +6,8 @@ brvs.userKeysCount=10 brvs.localhostname=localhost brvs.userDomains=clients brvs.port=8080 +rest.username=brvs +rest.password=brvs quorum.key=user_quorum accounts.holder=client_accounts@notary iroha.host=brvs-iroha diff --git a/config/context/spring-context.xml b/config/context/spring-context.xml index cbe71bd..f82c25d 100755 --- a/config/context/spring-context.xml +++ b/config/context/spring-context.xml @@ -19,6 +19,12 @@ + + + + + + From 31512733e99920f37d4f8c440d5a49eb314a83a3 Mon Sep 17 00:00:00 2001 From: Mingela Date: Fri, 19 Apr 2019 11:56:44 +0300 Subject: [PATCH 2/2] Refactored authenticator instantiation --- .../main/java/iroha/validation/Application.java | 2 +- .../validation/security/BrvsAuthenticator.java | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/brvs-core/src/main/java/iroha/validation/Application.java b/brvs-core/src/main/java/iroha/validation/Application.java index ab6630f..b393395 100644 --- a/brvs-core/src/main/java/iroha/validation/Application.java +++ b/brvs-core/src/main/java/iroha/validation/Application.java @@ -79,7 +79,7 @@ private static int getPort(AbstractApplicationContext context) { private static Config getSecurityConfig(UsernamePasswordCredentials credentials) { DirectBasicAuthClient basicAuthClient = new DirectBasicAuthClient( - new BrvsAuthenticator(credentials) + BrvsAuthenticator.getInstance(credentials) ); Config config = new Config(basicAuthClient); config.addAuthorizer("brvs", new IsAuthenticatedAuthorizer()); diff --git a/brvs-core/src/main/java/iroha/validation/security/BrvsAuthenticator.java b/brvs-core/src/main/java/iroha/validation/security/BrvsAuthenticator.java index 4296a2d..fec7623 100644 --- a/brvs-core/src/main/java/iroha/validation/security/BrvsAuthenticator.java +++ b/brvs-core/src/main/java/iroha/validation/security/BrvsAuthenticator.java @@ -20,21 +20,24 @@ public class BrvsAuthenticator implements Authenticator