Added example for AuthenticationProvider SPI

This commit is contained in:
mposolda 2014-05-27 21:29:47 +02:00
parent 5b431338c2
commit a903eb7605
7 changed files with 206 additions and 0 deletions

View file

@ -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" .

View file

@ -0,0 +1,45 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>examples-providers-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-beta-1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<name>Properties Authentication Provider Example</name>
<description/>
<modelVersion>4.0.0</modelVersion>
<artifactId>authentication-properties-example</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authentication-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>authentication-properties-example</finalName>
</build>
</project>

View file

@ -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 <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
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<String> getAvailableOptions() {
return Collections.emptyList();
}
@Override
public AuthUser getUser(RealmModel realm, Map<String, String> 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<String, String> configuration, String username) throws AuthenticationProviderException {
// Registration ignored
return username;
}
@Override
public AuthProviderStatus validatePassword(RealmModel realm, Map<String, String> 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<String, String> 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() {
}
}

View file

@ -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 <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
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";
}
}

View file

@ -0,0 +1 @@
org.keycloak.examples.providers.authentication.PropertiesAuthenticationProviderFactory

View file

@ -0,0 +1,2 @@
joe=password1
james=password2

View file

@ -35,5 +35,6 @@
<modules>
<module>audit-listener-sysout</module>
<module>audit-provider-mem</module>
<module>authentication-properties</module>
</modules>
</project>