diff --git a/examples/providers/authentication-properties/README.md b/examples/providers/authentication-properties/README.md new file mode 100644 index 0000000000..b55db4c6b3 --- /dev/null +++ b/examples/providers/authentication-properties/README.md @@ -0,0 +1,20 @@ +Example Authentication Provider based on property file values +============================================================= + +* To deploy copy "target/authentication-properties-example.jar" to "standalone/deployments/auth-server.war/WEB-INF/lib" . Then edit "standalone/configuration/keycloak-server.json" and add this: +````shell + "authentication": { + "properties": { + "propertiesFileLocation": "users.properties" + } + } +```` + +* Then start (or restart)the server. Once started open the admin console, select your realm, then click on "Authentication" and then "Add provider" and select "properties" from the list. +This will mean that realm will use PropertiesAuthenticationProvider for authentication. + +* Once you try to login to realm, you can login with username/password like "joe/password1" or "james/password2" . Once joe is authenticated, +you can see in Keycloak admin console in "Users" list that user "joe" was added to the list. + +* You can try to login as joe and then go to [http://localhost:8080/auth/realms/keycloak-admin/account/password](http://localhost:8080/auth/realms/keycloak-admin/account/password) and change the password. +You will then be able to logout and login with new password because properties were updated. But this is just in memory-properties, so after server restart the password will be again "password1" . diff --git a/examples/providers/authentication-properties/pom.xml b/examples/providers/authentication-properties/pom.xml new file mode 100644 index 0000000000..844566b480 --- /dev/null +++ b/examples/providers/authentication-properties/pom.xml @@ -0,0 +1,45 @@ + + + examples-providers-pom + org.keycloak + 1.0-beta-1-SNAPSHOT + ../pom.xml + + Properties Authentication Provider Example + + 4.0.0 + + authentication-properties-example + jar + + + + org.keycloak + keycloak-core + ${project.version} + provided + + + org.keycloak + keycloak-model-api + ${project.version} + provided + + + org.keycloak + keycloak-authentication-api + ${project.version} + provided + + + org.jboss.logging + jboss-logging + provided + + + + + authentication-properties-example + + diff --git a/examples/providers/authentication-properties/src/main/java/org/keycloak/examples/providers/authentication/PropertiesAuthenticationProvider.java b/examples/providers/authentication-properties/src/main/java/org/keycloak/examples/providers/authentication/PropertiesAuthenticationProvider.java new file mode 100644 index 0000000000..87d0b8e064 --- /dev/null +++ b/examples/providers/authentication-properties/src/main/java/org/keycloak/examples/providers/authentication/PropertiesAuthenticationProvider.java @@ -0,0 +1,75 @@ +package org.keycloak.examples.providers.authentication; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.jboss.logging.Logger; +import org.keycloak.authentication.AuthProviderStatus; +import org.keycloak.authentication.AuthUser; +import org.keycloak.authentication.AuthenticationProvider; +import org.keycloak.authentication.AuthenticationProviderException; +import org.keycloak.models.RealmModel; + +/** + * @author Marek Posolda + */ +public class PropertiesAuthenticationProvider implements AuthenticationProvider { + + private static final Logger log = Logger.getLogger(PropertiesAuthenticationProvider.class); + + private final Properties properties; + + public PropertiesAuthenticationProvider(Properties properties) { + this.properties = properties; + } + + @Override + public String getName() { + return "properties"; + } + + @Override + public List getAvailableOptions() { + return Collections.emptyList(); + } + + @Override + public AuthUser getUser(RealmModel realm, Map configuration, String username) throws AuthenticationProviderException { + if (properties.getProperty(username) != null) { + return new AuthUser(username, username, getName()); + } else { + return null; + } + } + + @Override + public String registerUser(RealmModel realm, Map configuration, String username) throws AuthenticationProviderException { + // Registration ignored + return username; + } + + @Override + public AuthProviderStatus validatePassword(RealmModel realm, Map configuration, String username, String password) throws AuthenticationProviderException { + String propertyFilePassword = properties.getProperty(username); + if (propertyFilePassword != null && propertyFilePassword.equals(password)) { + return AuthProviderStatus.SUCCESS; + } else { + return AuthProviderStatus.INVALID_CREDENTIALS; + } + } + + @Override + public boolean updateCredential(RealmModel realm, Map configuration, String username, String password) throws AuthenticationProviderException { + // Just update in memory (Won't survive restart) + log.info("Going to update password for user " + username + " in PropertiesAuthenticationProvider"); + properties.put(username, password); + return true; + } + + @Override + public void close() { + } + +} diff --git a/examples/providers/authentication-properties/src/main/java/org/keycloak/examples/providers/authentication/PropertiesAuthenticationProviderFactory.java b/examples/providers/authentication-properties/src/main/java/org/keycloak/examples/providers/authentication/PropertiesAuthenticationProviderFactory.java new file mode 100644 index 0000000000..b0aef64a84 --- /dev/null +++ b/examples/providers/authentication-properties/src/main/java/org/keycloak/examples/providers/authentication/PropertiesAuthenticationProviderFactory.java @@ -0,0 +1,62 @@ +package org.keycloak.examples.providers.authentication; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import org.jboss.logging.Logger; +import org.keycloak.Config; +import org.keycloak.authentication.AuthenticationProvider; +import org.keycloak.authentication.AuthenticationProviderFactory; +import org.keycloak.provider.ProviderSession; + +/** + * @author Marek Posolda + */ +public class PropertiesAuthenticationProviderFactory implements AuthenticationProviderFactory { + + private static final Logger log = Logger.getLogger(PropertiesAuthenticationProviderFactory.class); + + private Properties properties; + + @Override + public AuthenticationProvider create(ProviderSession providerSession) { + return new PropertiesAuthenticationProvider(properties); + } + + @Override + public void init(Config.Scope config) { + String propsFileLocation = config.get("propertiesFileLocation"); + if (propsFileLocation == null) { + throw new IllegalStateException("Properties file location is not configured in PropertiesAuthenticationProviderFactory"); + } else { + log.info("Using properties file: " + propsFileLocation); + } + + this.properties = new Properties(); + InputStream propertiesStream = null; + try { + propertiesStream = getClass().getClassLoader().getResourceAsStream(propsFileLocation); + this.properties.load(propertiesStream); + } catch (IOException ioException) { + throw new RuntimeException(ioException); + } finally { + if (propertiesStream != null) { + try { + propertiesStream.close(); + } catch (IOException e) { + log.error("Error when closing InputStream", e); + } + } + } + } + + @Override + public void close() { + } + + @Override + public String getId() { + return "properties"; + } +} diff --git a/examples/providers/authentication-properties/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticationProviderFactory b/examples/providers/authentication-properties/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticationProviderFactory new file mode 100644 index 0000000000..0e35fee25f --- /dev/null +++ b/examples/providers/authentication-properties/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticationProviderFactory @@ -0,0 +1 @@ +org.keycloak.examples.providers.authentication.PropertiesAuthenticationProviderFactory \ No newline at end of file diff --git a/examples/providers/authentication-properties/src/main/resources/users.properties b/examples/providers/authentication-properties/src/main/resources/users.properties new file mode 100644 index 0000000000..6e1b8cd8d9 --- /dev/null +++ b/examples/providers/authentication-properties/src/main/resources/users.properties @@ -0,0 +1,2 @@ +joe=password1 +james=password2 diff --git a/examples/providers/pom.xml b/examples/providers/pom.xml index ff0cf917f5..223736ac23 100755 --- a/examples/providers/pom.xml +++ b/examples/providers/pom.xml @@ -35,5 +35,6 @@ audit-listener-sysout audit-provider-mem + authentication-properties