Skip to content

Commit 531b182

Browse files
authored
Merge pull request #138 from Paul-Blanchaert/enable-pac4j-basicauth
Enable basic auth from configured user/password
2 parents 8c2b789 + 8e8f238 commit 531b182

File tree

4 files changed

+57
-10
lines changed

4 files changed

+57
-10
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package modules
2+
3+
import org.pac4j.core.context.WebContext
4+
import org.pac4j.core.context.session.SessionStore
5+
import org.pac4j.core.credentials.{Credentials, UsernamePasswordCredentials}
6+
import org.pac4j.core.credentials.authenticator.Authenticator
7+
import org.pac4j.core.exception.CredentialsException
8+
import org.pac4j.core.profile.CommonProfile
9+
import org.pac4j.core.util.{CommonHelper, Pac4jConstants}
10+
11+
12+
case class ConfiguredBasicAuthAuthenticator(validUserId: String, validPassword: String) extends Authenticator {
13+
14+
override def validate(credentials: Credentials, context: WebContext, sessionStore: SessionStore): Unit = {
15+
if (credentials == null) throw new CredentialsException("No credential")
16+
val userCredentials = credentials.asInstanceOf[UsernamePasswordCredentials]
17+
val username = userCredentials.getUsername()
18+
val password = userCredentials.getPassword()
19+
if (CommonHelper.isBlank(username)) throw new CredentialsException("Username cannot be blank")
20+
if (CommonHelper.isBlank(password)) throw new CredentialsException("Password cannot be blank")
21+
if (CommonHelper.areNotEquals(username, validUserId)) throw new CredentialsException("Username : '" + username + "' does not match valid user")
22+
if (CommonHelper.areNotEquals(password, validPassword)) throw new CredentialsException("Password does not match valid password")
23+
val profile = new CommonProfile
24+
profile.setId(username)
25+
profile.addAttribute(Pac4jConstants.USERNAME, username)
26+
userCredentials.setUserProfile(profile)
27+
}
28+
29+
}
30+

app/modules/SecurityModule.scala

+18-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package modules
22

33
import com.google.inject.{AbstractModule, Provides}
4-
import org.pac4j.core.client.Clients
4+
import org.pac4j.core.client.{Client, Clients}
55
import org.pac4j.core.client.direct.AnonymousClient
66
import org.pac4j.core.config.Config
77
import org.pac4j.core.context.session.SessionStore
88
import org.pac4j.core.profile.CommonProfile
9+
import org.pac4j.http.client.direct.DirectBasicAuthClient
910
import org.pac4j.play.scala.{DefaultSecurityComponents, Pac4jScalaTemplateHelper, SecurityComponents}
1011
import org.pac4j.play.store.{PlayCookieSessionStore, ShiroAesDataEncrypter}
1112
import org.pac4j.play.{CallbackController, LogoutController}
@@ -43,16 +44,21 @@ class SecurityModule(environment: Environment, configuration: Configuration) ext
4344
@Provides
4445
def provideConfig(): Config = {
4546
val maybeConfiguredClientName = configuration.getOptional[String](ConfigKeyAuthClient).filter(_.nonEmpty)
46-
val authClientOpt = maybeConfiguredClientName.map {
47-
case "SAML2Client" => createSaml2Client(s"$ConfigKeyPrefixClientConfig.SAML2Client")
47+
val config: Option[Config] = maybeConfiguredClientName.map {
48+
case "DirectBasicAuthClient" => createConfiguredDirectBasicAuthConfig(s"$ConfigKeyPrefixClientConfig.ConfiguredDirectBasicAuthClient")
49+
case "SAML2Client" => createSaml2Config(s"$ConfigKeyPrefixClientConfig.SAML2Client")
4850
case other => throw new RuntimeException(s"Unsupported auth client config value: $other")
4951
}
50-
val allClients = authClientOpt.toSeq :+ new AnonymousClient()
51-
// callback URL path as configured in `routes`
52-
val clients = new Clients(s"$baseUrl/callback", allClients:_*)
53-
new Config(clients)
52+
config.getOrElse(new Config())
53+
}
54+
55+
private def createConfiguredDirectBasicAuthConfig(keyPrefix: String): Config = {
56+
val username = configuration.get[String](s"$keyPrefix.username")
57+
val password = configuration.get[String](s"$keyPrefix.password")
58+
new Config(new DirectBasicAuthClient(ConfiguredBasicAuthAuthenticator(username, password)))
5459
}
55-
private def createSaml2Client(keyPrefix: String): SAML2Client = {
60+
61+
private def createSaml2Config(keyPrefix: String): Config = {
5662
val cfg = new SAML2Configuration(
5763
configuration.get[String](s"$keyPrefix.keystore"),
5864
configuration.get[String](s"$keyPrefix.keystorePassword"),
@@ -62,7 +68,10 @@ class SecurityModule(environment: Environment, configuration: Configuration) ext
6268
cfg.setServiceProviderEntityId(configuration.get[String](s"$keyPrefix.serviceProviderEntityId"))
6369
cfg.setServiceProviderMetadataPath(configuration.get[String](s"$keyPrefix.serviceProviderMetadataPath"))
6470
cfg.setMaximumAuthenticationLifetime(configuration.get[Long](s"$keyPrefix.maximumAuthenticationLifetime"))
65-
new SAML2Client(cfg)
71+
val allClients = Option(new SAML2Client(cfg)).toSeq :+ new AnonymousClient()
72+
// callback URL path as configured in `routes`
73+
val clients = new Clients(s"$baseUrl/callback", allClients:_*)
74+
new Config(clients)
6675
}
6776

6877
}

build.sbt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import com.typesafe.sbt.GitBranchPrompt
22

33
name := "search-management-ui"
4-
version := "4.0.6"
4+
version := "4.0.7"
55
maintainer := "Contact productful.io <hello@productful.io>"
66

77
scalaVersion := "2.12.17"

conf/application.conf

+8
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ play.http.session.maxAge = ${?SMUI_SESSION_MAXAGE}
173173

174174
# This defines the pac4j client to use for authentication. Uses the well-defined pac4j names (OidcClient,
175175
# DirectBasicAuthClient...), currently supported:
176+
# - DirectBasicAuthClient
176177
# - SAML2Client
177178
# If no or empty value is set, no authentication is used.
178179
smui.auth.client = ""
@@ -218,6 +219,13 @@ smui.auth.clients.SAML2Client {
218219
maximumAuthenticationLifetime = ${?SMUI_SAML_MAXIMUM_AUTHENTICATION_LIFETIME}
219220
}
220221

222+
# The DirectBasicAuthClient configuration which is used *only* when the DirectBasicAuthClient is configured as smui.auth.client
223+
smui.auth.clients.ConfiguredDirectBasicAuthClient {
224+
username = "smui_user"
225+
username = ${?SMUI_BASIC_AUTH_PASS}
226+
password = "smui_pass"
227+
password = ${?SMUI_BASIC_AUTH_PASS}
228+
}
221229

222230
# pac4j rules for configuring the pac4j SecurityFilter
223231
pac4j.security.rules = [

0 commit comments

Comments
 (0)