Skip to content

Commit

Permalink
KEYCLOAK-2242
Browse files Browse the repository at this point in the history
Remove built-in admin account
  • Loading branch information
stianst committed Dec 23, 2015
1 parent b27b041 commit eddf3ee
Show file tree
Hide file tree
Showing 11 changed files with 395 additions and 200 deletions.
Expand Up @@ -130,15 +130,14 @@ cd <WILDFLY_HOME>/bin
<section> <section>
<title>Admin User</title> <title>Admin User</title>
<para> <para>
To access the admin console you need an account to login. Currently, there's a default account added To access the admin console to configure Keycloak you need an account to login. There is no built in user,
with the username <literal>admin</literal> and password <literal>admin</literal>. You will be required instead you have to first create an admin account. This can done either by opening <ulink url="http://localhost:8080/auth">http://localhost:8080/auth</ulink>
to change the password on first login. We are planning on removing the built-in account soon and will (creating a user through the browser can only be done through localhost) or you can use the add-user script from
instead have an initial step to create the user. the command-line.
</para> </para>
<para> <para>
You can also create a user with the <literal>add-user</literal> script found in <literal>bin</literal>. The <literal>add-user</literal> script creates a temporary file with the details of the user,
This script will create a temporary file with the details of the user, which are imported at startup. which are imported at startup. To add a user with this script run:
To add a user with this script run:
<programlisting><![CDATA[ <programlisting><![CDATA[
bin/add-user.[sh|bat] -r master -u <username> -p <password> bin/add-user.[sh|bat] -r master -u <username> -p <password>
]]></programlisting> ]]></programlisting>
Expand Down
Expand Up @@ -26,6 +26,28 @@
<title>Welcome to Keycloak</title> <title>Welcome to Keycloak</title>
<link rel="shortcut icon" href="welcome-content/favicon.ico" type="image/x-icon"> <link rel="shortcut icon" href="welcome-content/favicon.ico" type="image/x-icon">
<link rel="StyleSheet" href="welcome-content/keycloak.css" type="text/css"> <link rel="StyleSheet" href="welcome-content/keycloak.css" type="text/css">
<style>
label {
display: inline-block;
width: 200px;
text-align: right;
margin-right: 10px;
}
button {
margin-left: 215px;
}
form {
background-color: #eee;
border: 1px solid #666;
padding-bottom: 1em;
}
.error {
color: #a30000;
}
</style>
</head> </head>


<body> <body>
Expand All @@ -36,7 +58,41 @@
</div> </div>
<h1>Welcome to Keycloak</h1> <h1>Welcome to Keycloak</h1>


<h3>Your Keycloak is running.</h3> <#if successMessage?has_content>
<p>${successMessage}</p>
<#elseif errorMessage?has_content>
<p class="error">${errorMessage}</p>
<#elseif bootstrap>
<#if localUser>
<p>Please create an initial admin user to get started.</p>
<#else>
<p>
You need local access to create the initial admin user. Open <a href="http://localhost:8080/auth">http://localhost:8080/auth</a>
or use the add-user script.
</p>
</#if>
</#if>

<#if bootstrap && localUser>
<form method="post">
<p>
<label for="username">Username</label>
<input id="username" name="username" />
</p>

<p>
<label for="password">Password</label>
<input id="password" name="password" type="password" />
</p>

<p>
<label for="passwordConfirmation">Password confirmation</label>
<input id="passwordConfirmation" name="passwordConfirmation" type="password" />
</p>

<button id="create-button" type="submit">Create</button>
</form>
</#if>


<p><a href="http://www.keycloak.org/docs">Documentation</a> | <a href="admin/">Administration Console</a> </p> <p><a href="http://www.keycloak.org/docs">Documentation</a> | <a href="admin/">Administration Console</a> </p>


Expand Down
Expand Up @@ -2,10 +2,9 @@




import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.services.managers.ApplianceBootstrap; import java.io.IOException;


/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
Expand All @@ -14,76 +13,82 @@ public class ExportImportManager {


private static final Logger logger = Logger.getLogger(ExportImportManager.class); private static final Logger logger = Logger.getLogger(ExportImportManager.class);


public void checkExportImport(KeycloakSessionFactory sessionFactory, String contextPath) { private KeycloakSession session;

private final String realmName;

private ExportProvider exportProvider;
private ImportProvider importProvider;

public ExportImportManager(KeycloakSession session) {
this.session = session;

realmName = ExportImportConfig.getRealmName();

String providerId = ExportImportConfig.getProvider();
String exportImportAction = ExportImportConfig.getAction(); String exportImportAction = ExportImportConfig.getAction();
String realmName = ExportImportConfig.getRealmName();


boolean export = false;
boolean importt = false;
if (ExportImportConfig.ACTION_EXPORT.equals(exportImportAction)) { if (ExportImportConfig.ACTION_EXPORT.equals(exportImportAction)) {
export = true; exportProvider = session.getProvider(ExportProvider.class, providerId);
if (exportProvider == null) {
throw new RuntimeException("Export provider not found");
}
} else if (ExportImportConfig.ACTION_IMPORT.equals(exportImportAction)) { } else if (ExportImportConfig.ACTION_IMPORT.equals(exportImportAction)) {
importt = true; importProvider = session.getProvider(ImportProvider.class, providerId);
if (importProvider == null) {
throw new RuntimeException("Import provider not found");
}
}
}

public boolean isRunImport() {
return importProvider != null;
}

public boolean isImportMasterIncluded() {
if (!isRunImport()) {
throw new IllegalStateException("Import not enabled");
}
try {
return importProvider.isMasterRealmExported();
} catch (IOException e) {
throw new RuntimeException(e);
} }
}

public boolean isRunExport() {
return exportProvider != null;
}


if (export || importt) { public void runImport() {
String exportImportProviderId = ExportImportConfig.getProvider(); try {
logger.debug("Will use provider: " + exportImportProviderId); Strategy strategy = ExportImportConfig.getStrategy();
KeycloakSession session = sessionFactory.create(); if (realmName == null) {

logger.infof("Full model import requested. Strategy: %s", strategy.toString());
try { importProvider.importModel(session.getKeycloakSessionFactory(), strategy);
if (export) { } else {
ExportProvider exportProvider = session.getProvider(ExportProvider.class, exportImportProviderId); logger.infof("Import of realm '%s' requested. Strategy: %s", realmName, strategy.toString());

importProvider.importRealm(session.getKeycloakSessionFactory(), realmName, strategy);
if (exportProvider == null) {
logger.errorf("Invalid Export Provider %s", exportImportProviderId);
} else {
if (realmName == null) {
logger.info("Full model export requested");
exportProvider.exportModel(sessionFactory);
} else {
logger.infof("Export of realm '%s' requested", realmName);
exportProvider.exportRealm(sessionFactory, realmName);
}
logger.info("Export finished successfully");
}
} else {
ImportProvider importProvider = session.getProvider(ImportProvider.class, exportImportProviderId);

if (importProvider == null) {
logger.errorf("Invalid Import Provider %s", exportImportProviderId);
} else {

Strategy strategy = ExportImportConfig.getStrategy();
if (realmName == null) {
logger.infof("Full model import requested. Strategy: %s", strategy.toString());

// Check if master realm was exported. If it's not, then it needs to be created before other realms are imported
if (!importProvider.isMasterRealmExported()) {
ApplianceBootstrap.setupDefaultRealm(sessionFactory, contextPath);
ApplianceBootstrap.setupDefaultUser(sessionFactory);
}

importProvider.importModel(sessionFactory, strategy);
} else {
logger.infof("Import of realm '%s' requested. Strategy: %s", realmName, strategy.toString());

if (!realmName.equals(Config.getAdminRealm())) {
// Check if master realm exists. If it's not, then it needs to be created before other realm is imported
ApplianceBootstrap.setupDefaultRealm(sessionFactory, contextPath);
ApplianceBootstrap.setupDefaultUser(sessionFactory);
}

importProvider.importRealm(sessionFactory, realmName, strategy);
}
logger.info("Import finished successfully");
}
}
} catch (Throwable ioe) {
logger.error("Error during export/import", ioe);
} finally {
session.close();
} }
logger.info("Import finished successfully");
} catch (IOException e) {
throw new RuntimeException("Failed to run import", e);
} }
} }

public void runExport() {
try {
if (realmName == null) {
logger.info("Full model export requested");
exportProvider.exportModel(session.getKeycloakSessionFactory());
} else {
logger.infof("Export of realm '%s' requested", realmName);
exportProvider.exportRealm(session.getKeycloakSessionFactory(), realmName);
}
logger.info("Export finished successfully");
} catch (IOException e) {
throw new RuntimeException("Failed to run export");
}
}

} }
Expand Up @@ -4,15 +4,7 @@
import org.keycloak.Config; import org.keycloak.Config;
import org.keycloak.common.Version; import org.keycloak.common.Version;
import org.keycloak.common.enums.SslRequired; import org.keycloak.common.enums.SslRequired;
import org.keycloak.models.AdminRoles; import org.keycloak.models.*;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.CredentialRepresentation;


Expand All @@ -23,17 +15,34 @@
public class ApplianceBootstrap { public class ApplianceBootstrap {


private static final Logger logger = Logger.getLogger(ApplianceBootstrap.class); private static final Logger logger = Logger.getLogger(ApplianceBootstrap.class);
private final KeycloakSession session;


public static boolean setupDefaultRealm(KeycloakSessionFactory sessionFactory, String contextPath) { public ApplianceBootstrap(KeycloakSession session) {
KeycloakSession session = sessionFactory.create(); this.session = session;
session.getTransaction().begin(); }

public boolean isNewInstall() {
if (session.realms().getRealms().size() > 0) {
return false;
} else {
return true;
}
}


public boolean isNoMasterUser() {
RealmModel realm = session.realms().getRealm(Config.getAdminRealm());
return session.users().getUsersCount(realm) == 0;
}

public boolean createMasterRealm(String contextPath) {
if (!isNewInstall()) {
throw new IllegalStateException("Can't create default realm as realms already exists");
}

KeycloakSession session = this.session.getKeycloakSessionFactory().create();
try { try {
session.getTransaction().begin();
String adminRealmName = Config.getAdminRealm(); String adminRealmName = Config.getAdminRealm();
if (session.realms().getRealm(adminRealmName) != null) {
return false;
}

logger.info("Initializing " + adminRealmName + " realm"); logger.info("Initializing " + adminRealmName + " realm");


RealmManager manager = new RealmManager(session); RealmManager manager = new RealmManager(session);
Expand All @@ -58,41 +67,29 @@ public static boolean setupDefaultRealm(KeycloakSessionFactory sessionFactory, S
KeycloakModelUtils.generateRealmKeys(realm); KeycloakModelUtils.generateRealmKeys(realm);


session.getTransaction().commit(); session.getTransaction().commit();
return true;
} finally { } finally {
session.close(); session.close();
} }
}


public static boolean setupDefaultUser(KeycloakSessionFactory sessionFactory) { return true;
KeycloakSession session = sessionFactory.create(); }
session.getTransaction().begin();


try { public void createMasterRealmUser(KeycloakSession session, String username, String password) {
RealmModel realm = session.realms().getRealm(Config.getAdminRealm()); RealmModel realm = session.realms().getRealm(Config.getAdminRealm());
if (session.users().getUserByUsername("admin", realm) == null) { if (session.users().getUsersCount(realm) > 0) {
UserModel adminUser = session.users().addUser(realm, "admin"); throw new IllegalStateException("Can't create initial user as users already exists");

adminUser.setEnabled(true);
UserCredentialModel usrCredModel = new UserCredentialModel();
usrCredModel.setType(UserCredentialModel.PASSWORD);
usrCredModel.setValue("admin");
session.users().updateCredential(realm, adminUser, usrCredModel);
adminUser.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);

RoleModel adminRole = realm.getRole(AdminRoles.ADMIN);
adminUser.grantRole(adminRole);

ClientModel accountApp = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
for (String r : accountApp.getDefaultRoles()) {
adminUser.grantRole(accountApp.getRole(r));
}
}
session.getTransaction().commit();
return true;
} finally {
session.close();
} }

UserModel adminUser = session.users().addUser(realm, username);
adminUser.setEnabled(true);

UserCredentialModel usrCredModel = new UserCredentialModel();
usrCredModel.setType(UserCredentialModel.PASSWORD);
usrCredModel.setValue(password);
session.users().updateCredential(realm, adminUser, usrCredModel);

RoleModel adminRole = realm.getRole(AdminRoles.ADMIN);
adminUser.grantRole(adminRole);
} }


} }

0 comments on commit eddf3ee

Please sign in to comment.