Updates to keycloak.js

This commit is contained in:
Stian Thorgersen 2014-03-15 12:53:52 +00:00
parent 331ab71427
commit 2d5e6520db
8 changed files with 514 additions and 243 deletions

View file

@ -0,0 +1,73 @@
{
"realm": "example",
"enabled": true,
"sslNotRequired": true,
"registrationAllowed": true,
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"requiredCredentials": [ "password" ],
"users" : [
{
"username" : "user",
"enabled": true,
"email" : "sample-user@example",
"firstName": "Sample",
"lastName": "User",
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
}
],
"roles" : {
"realm" : [
{
"name": "user",
"description": "User privileges"
},
{
"name": "admin",
"description": "Administrator privileges"
}
]
},
"roleMappings": [
{
"username": "user",
"roles": ["user"]
}
],
"scopeMappings": [
{
"client": "js-console",
"roles": ["user"]
}
],
"applications": [
{
"name": "js-console",
"enabled": true,
"publicClient": true,
"baseUrl": "http://localhost:8080/js-console",
"redirectUris": [
"http://localhost:8080/js-console/*"
]
}
],
"applicationRoleMappings": {
"account": [
{
"username": "user",
"roles": ["view-profile", "manage-account"]
}
]
},
"applicationScopeMappings": {
"account": [
{
"client": "js-console",
"roles": ["view-profile"]
}
]
}
}

42
examples/js-console/pom.xml Executable file
View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-beta-1-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak.example.demo</groupId>
<artifactId>js-console</artifactId>
<packaging>war</packaging>
<name>JS Console</name>
<description/>
<build>
<finalName>js-console</finalName>
<plugins>
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.4.Final</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,97 @@
<html>
<head>
<script src="http://localhost:8080/auth/js/keycloak.js"></script>
</head>
<body>
<div>
<button onclick="keycloak.login()">Login</button>
<button onclick="keycloak.logout()">Logout</button>
<button onclick="refreshToken()">Refresh Token</button>
<button onclick="refreshToken(30)">Refresh Token (if <30s validity)</button>
<button onclick="loadProfile()">Get Profile</button>
<button onclick="output(keycloak.tokenParsed)">Show Token</button>
<button onclick="output(keycloak.refreshTokenParsed)">Show Refresh Token</button>
<button onclick="showExpires()">Show Expires</button>
<button onclick="output(keycloak.idToken)">Show ID Token</button>
<button onclick="output(keycloak)">Show Details</button>
<button onclick="output(keycloak.createLoginUrl())">Show Login URL</button>
<button onclick="output(keycloak.createLogoutUrl())">Show Logout URL</button>
</div>
<h2>Result</h2>
<pre style="background-color: #ddd; border: 1px solid #ccc; padding: 10px;" id="output"></pre>
<h2>Events</h2>
<pre style="background-color: #ddd; border: 1px solid #ccc; padding: 10px;" id="events"></pre>
<script>
function loadProfile() {
keycloak.loadUserProfile().success(function(profile) {
output(profile);
}).error(function() {
output('Failed to load profile');
});
}
function refreshToken(minValidity) {
keycloak.refreshAccessToken(minValidity).success(function(refreshed) {
if (refreshed) {
output(keycloak.tokenParsed);
} else {
output('Token not refreshed, valid for ' + Math.round(keycloak.tokenParsed.exp - new Date().getTime() / 1000) + ' seconds');
}
}).error(function() {
output('Failed to refresh token');
});
}
function showExpires() {
var o = 'Token Expires:\t\t' + new Date(keycloak.tokenParsed.exp * 1000).toLocaleString() + '\n';
o += 'Token Expires in:\t' + Math.round(keycloak.tokenParsed.exp - new Date().getTime() / 1000) + ' seconds\n';
o += 'Refresh Token Expires:\t' + new Date(keycloak.refreshTokenParsed.exp * 1000).toLocaleString() + '\n';
o += 'Refresh Expires in:\t' + Math.round(keycloak.refreshTokenParsed.exp - new Date().getTime() / 1000) + ' seconds';
output(o);
}
function output(data) {
if (typeof data === 'object') {
data = JSON.stringify(data, null, ' ');
}
document.getElementById('output').innerText = data;
}
function event(event) {
var e = document.getElementById('events').innerText;
document.getElementById('events').innerText = new Date().toLocaleString() + "\t" + event + "\n" + e;
}
var keycloak = Keycloak();
keycloak.onAuthSuccess = function () {
event('Auth Success');
};
keycloak.onAuthError = function () {
event('Auth Error');
};
keycloak.onAuthRefreshSuccess = function () {
event('Auth Refresh Success');
};
keycloak.onAuthRefreshError = function () {
event('Auth Refresh Error');
};
keycloak.init().success(function(authenticated) {
output('Init Success (' + (authenticated ? 'Authenticated' : 'Not Authenticated') + ')');
}).error(function() {
output('Init Error');
});
</script>
</body>
</html>

View file

@ -0,0 +1,8 @@
{
"realm" : "example",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url" : "http://localhost:8080/auth",
"ssl-not-required" : true,
"resource" : "js-console",
"public-client" : true
}

View file

@ -1,27 +0,0 @@
{
"id": "test",
"realm": "test",
"enabled": true,
"sslNotRequired": true,
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"requiredCredentials": [ "password" ],
"users" : [
{
"username" : "test",
"enabled": true,
"email" : "test-user@localhost",
"credentials" : [
{ "type" : "password",
"value" : "test" }
]
}
],
"applications": [
{
"name": "test",
"enabled": true,
"secret": "password"
}
]
}

View file

@ -1,58 +1,108 @@
var Keycloak = function (options) {
options = options || {};
var Keycloak = function (config) {
if (!(this instanceof Keycloak)) {
return new Keycloak(options);
return new Keycloak(config);
}
var kc = this;
kc.authenticated = false;
if (!options.url) {
var scripts = document.getElementsByTagName('script');
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].src.match(/.*keycloak\.js/)) {
options.url = scripts[i].src.substr(0, scripts[i].src.indexOf('/auth/js/keycloak.js'));
break;
var configPromise = createPromise();
configPromise.name = 'config';
if (!config) {
loadConfig('keycloak.json', configPromise);
} else if (typeof config === 'string') {
loadConfig(config, configPromise);
} else {
if (!config['url']) {
var scripts = document.getElementsByTagName('script');
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].src.match(/.*keycloak\.js/)) {
config.url = scripts[i].src.substr(0, scripts[i].src.indexOf('/js/keycloak.js'));
break;
}
}
}
}
if (!options.url) {
throw 'url missing';
}
if (!options.realm) {
throw 'realm missing';
}
if (!options.clientId) {
throw 'clientId missing';
}
kc.init = function (successCallback, errorCallback) {
if (window.oauth.callback) {
processCallback(successCallback, errorCallback);
} else if (options.token) {
kc.setToken(options.token, successCallback);
} else if (options.onload) {
switch (options.onload) {
case 'login-required' :
window.location = kc.createLoginUrl(true);
break;
case 'check-sso' :
window.location = kc.createLoginUrl(false);
break;
}
if (!config.realm) {
throw 'realm missing';
}
if (!config.clientId) {
throw 'clientId missing';
}
kc.authServerUrl = config.url;
kc.realm = config.realm;
kc.clientId = config.clientId;
configPromise.setSuccess();
}
kc.login = function () {
window.location.href = kc.createLoginUrl(true);
kc.init = function (init) {
var promise = createPromise();
var callback = parseCallback(window.location.href);
function processInit() {
if (callback) {
window.history.replaceState({}, null, location.protocol + '//' + location.host + location.pathname + (callback.fragment ? '#' + callback.fragment : ''));
processCallback(callback, promise);
return;
} else if (init) {
if (init.code || init.error) {
processCallback(init, promise);
return;
} else if (init.token || init.refreshToken) {
setToken(init.token, init.refreshToken);
} else if (init == 'login-required') {
kc.login();
return;
} else if (init == 'check-sso') {
window.location = kc.createLoginUrl() + '&prompt=none';
return;
}
}
promise.setSuccess(false);
}
configPromise.promise.success(processInit);
return promise.promise;
}
kc.logout = function () {
kc.setToken(undefined);
window.location.href = kc.createLogoutUrl();
kc.login = function (redirectUri) {
window.location.href = kc.createLoginUrl(redirectUri);
}
kc.createLoginUrl = function(redirectUri) {
var state = createUUID();
sessionStorage.oauthState = state;
var url = getRealmUrl()
+ '/tokens/login'
+ '?client_id=' + encodeURIComponent(kc.clientId)
+ '&redirect_uri=' + getEncodedRedirectUri(redirectUri)
+ '&state=' + encodeURIComponent(state)
+ '&response_type=code';
return url;
}
kc.logout = function(redirectUri) {
setToken(null, null);
window.location.href = kc.createLogoutUrl(redirectUri);
}
kc.clearToken = function() {
setToken(null, null);
}
kc.createLogoutUrl = function(redirectUri) {
var url = getRealmUrl()
+ '/tokens/logout'
+ '?redirect_uri=' + getEncodedRedirectUri(redirectUri);
return url;
}
kc.hasRealmRole = function (role) {
@ -60,122 +110,131 @@ var Keycloak = function (options) {
return access && access.roles.indexOf(role) >= 0 || false;
}
kc.hasResourceRole = function (role, resource) {
kc.hasResourceRole = function(role, resource) {
if (!kc.resourceAccess) {
return false;
}
var access = kc.resourceAccess[resource || options.clientId];
var access = kc.resourceAccess[resource || kc.clientId];
return access && access.roles.indexOf(role) >= 0 || false;
}
kc.loadUserProfile = function (success, error) {
var url = kc.getRealmUrl() + '/account';
kc.loadUserProfile = function() {
var url = getRealmUrl() + '/account';
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.setRequestHeader('Accept', 'application/json');
req.setRequestHeader('Authorization', 'bearer ' + kc.token);
var promise = createPromise();
req.onreadystatechange = function () {
if (req.readyState == 4) {
if (req.status == 200) {
kc.profile = JSON.parse(req.responseText);
success && success(kc.profile)
promise.setSuccess(kc.profile);
} else {
var response = { status: req.status, statusText: req.status };
if (req.responseText) {
response.data = JSON.parse(req.responseText);
}
error && error(response);
promise.setError();
}
}
}
req.send();
return promise.promise;
}
/**
* checks to make sure token is valid. If it is, it calls successCallback with no parameters.
* If it isn't valid, it tries to refresh the access token. On successful refresh, it calls successCallback.
*
* @param successCallback
* @param errorCallback
*/
kc.onValidAccessToken = function(successCallback, errorCallback) {
if (!kc.tokenParsed) {
console.log('no token');
errorCallback();
return;
kc.refreshAccessToken = function(minValidity) {
if (!kc.tokenParsed || !kc.refreshToken) {
throw 'Not authenticated';
}
var currTime = new Date().getTime() / 1000;
if (currTime > kc.tokenParsed['exp']) {
if (!kc.refreshToken) {
console.log('no refresh token');
errorCallback();
return;
var promise = createPromise();
if (minValidity) {
var expiresIn = kc.tokenParsed['exp'] - (new Date().getTime() / 1000);
if (expiresIn > minValidity) {
promise.setSuccess(false);
return promise.promise;
}
console.log('calling refresh');
var params = 'grant_type=refresh_token&' + 'refresh_token=' + kc.refreshToken;
var url = kc.getRealmUrl() + '/tokens/refresh';
var req = new XMLHttpRequest();
req.open('POST', url, true, options.clientId, options.clientSecret);
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
req.onreadystatechange = function () {
if (req.readyState == 4) {
if (req.status == 200) {
console.log('Refresh Success');
var tokenResponse = JSON.parse(req.responseText);
kc.refreshToken = tokenResponse['refresh_token'];
kc.setToken(tokenResponse['access_token'], successCallback);
} else {
console.log('error on refresh HTTP invoke: ' + req.status);
errorCallback && errorCallback({ authenticated: false, status: req.status, statusText: req.statusText });
}
}
};
req.send(params);
} else {
console.log('Token is still valid');
successCallback();
}
var params = 'grant_type=refresh_token&' + 'refresh_token=' + kc.refreshToken;
var url = getRealmUrl() + '/tokens/refresh';
var req = new XMLHttpRequest();
req.open('POST', url, true);
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
if (kc.clientId && kc.clientSecret) {
req.setRequestHeader('Authorization', 'Basic ' + btoa(kc.clientId + ':' + kc.clientSecret));
} else {
params += '&client_id=' + encodeURIComponent(kc.clientId);
}
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status == 200) {
var tokenResponse = JSON.parse(req.responseText);
setToken(tokenResponse['access_token'], tokenResponse['refresh_token']);
kc.onAuthRefreshSuccess && kc.onAuthRefreshSuccess();
promise.setSuccess(true);
} else {
kc.onAuthRefreshError && kc.onAuthRefreshError();
promise.setError();
}
}
};
req.send(params);
return promise.promise;
}
kc.getRealmUrl = function() {
return options.url + '/auth/rest/realms/' + encodeURIComponent(options.realm);
kc.processCallback = function(url) {
var callback = parseCallback(url);
if (callback) {
var promise = createPromise();
processCallback(callback, promise);
return promise;
}
}
function processCallback(successCallback, errorCallback) {
var code = window.oauth.code;
var error = window.oauth.error;
var prompt = window.oauth.prompt;
function getRealmUrl() {
return kc.authServerUrl + '/rest/realms/' + encodeURIComponent(kc.realm);
}
function processCallback(oauth, promise) {
var code = oauth.code;
var error = oauth.error;
var prompt = oauth.prompt;
if (code) {
var params = 'code=' + code;
var url = kc.getRealmUrl() + '/tokens/access/codes';
var url = getRealmUrl() + '/tokens/access/codes';
var req = new XMLHttpRequest();
req.open('POST', url, true);
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
if (options.clientId && options.clientSecret) {
req.setRequestHeader('Authorization', 'Basic ' + btoa(options.clientId + ':' + options.clientSecret));
if (kc.clientId && kc.clientSecret) {
req.setRequestHeader('Authorization', 'Basic ' + btoa(kc.clientId + ':' + kc.clientSecret));
} else {
params += '&client_id=' + encodeURIComponent(options.clientId);
params += '&client_id=' + encodeURIComponent(kc.clientId);
}
req.withCredentials = true;
req.onreadystatechange = function () {
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status == 200) {
var tokenResponse = JSON.parse(req.responseText);
kc.refreshToken = tokenResponse['refresh_token'];
kc.setToken(tokenResponse['access_token'], successCallback);
setToken(tokenResponse['access_token'], tokenResponse['refresh_token']);
kc.onAuthSuccess && kc.onAuthSuccess();
promise.setSuccess(true);
} else {
errorCallback && errorCallback({ authenticated: false, status: req.status, statusText: req.statusText });
kc.onAuthError && kc.onAuthError();
promise.setError();
}
}
};
@ -183,16 +242,38 @@ var Keycloak = function (options) {
req.send(params);
} else if (error) {
if (prompt != 'none') {
setTimeout(function() {
errorCallback && errorCallback({ authenticated: false, error: error })
}, 0);
kc.onAuthError && kc.onAuthError();
promise.setError();
}
}
}
kc.setToken = function(token, successCallback) {
function loadConfig(url, configPromise) {
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.setRequestHeader('Accept', 'application/json');
req.onreadystatechange = function () {
if (req.readyState == 4) {
if (req.status == 200) {
var config = JSON.parse(req.responseText);
kc.authServerUrl = config['auth-server-url'];
kc.realm = config['realm'];
kc.clientId = config['resource'];
configPromise.setSuccess();
} else {
configPromise.setError();
}
}
};
req.send();
}
function setToken(token, refreshToken) {
if (token) {
window.oauth.token = token;
kc.token = token;
kc.tokenParsed = JSON.parse(atob(token.split('.')[1]));
kc.authenticated = true;
@ -209,45 +290,32 @@ var Keycloak = function (options) {
kc.idToken[n] = kc.tokenParsed[n];
}
}
setTimeout(function() {
successCallback && successCallback({ authenticated: kc.authenticated, subject: kc.subject });
}, 0);
} else {
delete window.oauth.token;
delete kc.token;
delete kc.tokenParsed;
delete kc.subject;
delete kc.realmAccess;
delete kc.resourceAccess;
delete kc.idToken;
kc.authenticated = false;
}
if (refreshToken) {
kc.refreshToken = refreshToken;
kc.refreshTokenParsed = JSON.parse(atob(refreshToken.split('.')[1]));
} else {
delete kc.refreshToken;
delete kc.refreshTokenParsed;
}
}
kc.createLoginUrl = function(prompt) {
var state = createUUID();
sessionStorage.oauthState = state;
var url = kc.getRealmUrl()
+ '/tokens/login'
+ '?client_id=' + encodeURIComponent(options.clientId)
+ '&redirect_uri=' + getEncodedRedirectUri()
+ '&state=' + encodeURIComponent(state)
+ '&response_type=code';
if (prompt == false) {
url += '&prompt=none';
}
return url;
}
kc.createLogoutUrl = function() {
var url = kc.getRealmUrl()
+ '/tokens/logout'
+ '?redirect_uri=' + getEncodedRedirectUri();
return url;
}
function getEncodedRedirectUri() {
function getEncodedRedirectUri(redirectUri) {
var url;
if (options.redirectUri) {
url = options.redirectUri;
if (redirectUri) {
url = redirectUri;
} else if (kc.redirectUri) {
url = kc.redirectUri;
} else {
url = (location.protocol + '//' + location.hostname + (location.port && (':' + location.port)) + location.pathname);
if (location.hash) {
@ -269,7 +337,81 @@ var Keycloak = function (options) {
var uuid = s.join('');
return uuid;
}
function parseCallback(url) {
if (url.indexOf('?') != -1) {
var oauth = {};
var params = url.split('?')[1].split('&');
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
switch (decodeURIComponent(p[0])) {
case 'code':
oauth.code = p[1];
break;
case 'error':
oauth.error = p[1];
break;
case 'state':
oauth.state = decodeURIComponent(p[1]);
break;
case 'redirect_fragment':
oauth.fragment = decodeURIComponent(p[1]);
break;
case 'prompt':
oauth.prompt = p[1];
break;
}
}
if (oauth.state && oauth.state == sessionStorage.oauthState) {
delete sessionStorage.oauthState;
return oauth;
}
}
}
function createPromise() {
var p = {
setSuccess: function(result) {
p.success = true;
p.result = result;
if (p.successCallback) {
p.successCallback(result);
}
},
setError: function(result) {
p.error = true;
p.result = result;
if (p.errorCallback) {
p.errorCallback(result);
}
},
promise: {
success: function(callback) {
if (p.success) {
callback(p.result);
} else if (!p.error) {
p.successCallback = callback;
}
return p.promise;
},
error: function(callback) {
if (p.error) {
callback(p.result);
} else if (!p.success) {
p.errorCallback = callback;
}
return p.promise;
}
}
}
return p;
}
var idTokenProperties = [
"name",
"given_name",
@ -298,45 +440,4 @@ var Keycloak = function (options) {
"country",
"claims_locales"
]
}
window.oauth = (function () {
var oauth = {};
var params = window.location.search.substring(1).split('&');
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
switch (decodeURIComponent(p[0])) {
case 'code':
oauth.code = p[1];
break;
case 'error':
oauth.error = p[1];
break;
case 'state':
oauth.state = decodeURIComponent(p[1]);
break;
case 'redirect_fragment':
oauth.fragment = decodeURIComponent(p[1]);
break;
case 'prompt':
oauth.prompt = p[1];
break;
}
}
if (oauth.state && oauth.state == sessionStorage.oauthState) {
oauth.callback = true;
delete sessionStorage.oauthState;
} else {
oauth.callback = false;
}
if (oauth.callback) {
window.history.replaceState({}, null, location.protocol + '//' + location.host + location.pathname + (oauth.fragment ? '#' + oauth.fragment : ''));
} else if (oauth.fragment) {
window.history.replaceState({}, null, location.protocol + '//' + location.host + location.pathname + (oauth.fragment ? '#' + oauth.fragment : ''));
}
return oauth;
}());
}

View file

@ -1,24 +0,0 @@
<html>
<head>
<script src="http://192.168.0.16/js/keycloak.js"></script>
</head>
<body>
<button onclick="keycloak.login()">Login</button>
<script>
var keycloak = Keycloak({ realm: 'test', clientId: 'test', clientSecret: 'password' });
keycloak.init(function () {
console.debug('Token: ' + keycloak.tokenParsed);
console.debug('Realm access: ' + keycloak.realmAccess);
console.debug('Resource access: ' + keycloak.resourceAccess);
keycloak.loadUserProfile(function (profile) {
console.debug(profile);
}, function (error) {
console.debug(error);
})
});
</script>
</body>
</html>

View file

@ -37,8 +37,9 @@ public class KeycloakServerApplication extends KeycloakApplication {
try {
RealmManager manager = new RealmManager(session);
if (rep.getId() == null) {
throw new RuntimeException("Realm id not specified");
if (rep.getId() != null && manager.getRealm(rep.getId()) != null) {
log.info("Not importing realm " + rep.getRealm() + " realm already exists");
return;
}
if (manager.getRealmByName(rep.getRealm()) != null) {