SEC-1431: Added openid-selector to openid sample, plus AX configuration for myopenid.com.
@ -99,6 +99,26 @@ Success! Your web filters appear to be properly configured!
|
|||||||
the same application context file. This means there are actually two identical
|
the same application context file. This means there are actually two identical
|
||||||
authentication providers configured in this application. </para>
|
authentication providers configured in this application. </para>
|
||||||
</section>
|
</section>
|
||||||
|
<section xml:id="openid-sample">
|
||||||
|
<title>OpenID Sample</title>
|
||||||
|
<para>
|
||||||
|
The OpenID sample demonstrates how to use the namespace to configure OpenID and how to set up
|
||||||
|
<link xlink:href="http://openid.net/specs/openid-attribute-exchange-1_0.html">attribute exchange</link>
|
||||||
|
configurations for Google, Yahoo and MyOpenID identity providers (you can experiment with adding others
|
||||||
|
if you wish). It uses the JQuery-based <link xlink:href="http://code.google.com/p/openid-selector/">openid-selector</link>
|
||||||
|
project to provide a user-friendly login page which allows the user to easily select a provider, rather than
|
||||||
|
typing in the full OpenID identifier.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The application differs from normal authentication scenarios in that it allows any user to access the site (provided
|
||||||
|
their OpenID authentication is successful). The first time you login, you will get a <quote>Welcome [your name]"</quote>
|
||||||
|
message. If you logout and log back in (with the same OpenID identity) then this should change to <quote>Welcome Back</quote>.
|
||||||
|
This is achieved by using a custom <interfacename>UserDetailsService</interfacename> which assigns a standard role
|
||||||
|
to any user and stores the identities internally in a map. Obviously a real application would use a database instead.
|
||||||
|
Have a look at the source form more information. This class also takes into account the fact that different attributes may be returned
|
||||||
|
from different providers and builds the name with which it addresses the user accordingly.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
<section xml:id="cas-sample">
|
<section xml:id="cas-sample">
|
||||||
<title>CAS Sample</title>
|
<title>CAS Sample</title>
|
||||||
<para> The CAS sample requires that you run both a CAS server and CAS client. It isn't
|
<para> The CAS sample requires that you run both a CAS server and CAS client. It isn't
|
||||||
|
@ -69,6 +69,10 @@ public class CustomUserDetailsService implements UserDetailsService, Authenticat
|
|||||||
firstName = attribute.getValues().get(0);
|
firstName = attribute.getValues().get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (attribute.getName().equals("lastname")) {
|
||||||
|
lastName = attribute.getValues().get(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (attribute.getName().equals("fullname")) {
|
if (attribute.getName().equals("fullname")) {
|
||||||
fullName = attribute.getValues().get(0);
|
fullName = attribute.getValues().get(0);
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,11 @@
|
|||||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
|
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
|
||||||
|
|
||||||
<http>
|
<http>
|
||||||
<intercept-url pattern="/**" access="ROLE_USER"/>
|
|
||||||
<intercept-url pattern="/openidlogin.jsp*" filters="none"/>
|
<intercept-url pattern="/openidlogin.jsp*" filters="none"/>
|
||||||
|
<intercept-url pattern="/images/*" filters="none"/>
|
||||||
|
<intercept-url pattern="/css/*" filters="none"/>
|
||||||
|
<intercept-url pattern="/js/*" filters="none"/>
|
||||||
|
<intercept-url pattern="/**" access="ROLE_USER"/>
|
||||||
<logout/>
|
<logout/>
|
||||||
<openid-login login-page="/openidlogin.jsp" user-service-ref="registeringUserService"
|
<openid-login login-page="/openidlogin.jsp" user-service-ref="registeringUserService"
|
||||||
authentication-failure-url="/openidlogin.jsp?login_error=true">
|
authentication-failure-url="/openidlogin.jsp?login_error=true">
|
||||||
@ -25,6 +28,10 @@
|
|||||||
<openid-attribute name="email" type="http://axschema.org/contact/email" required="true"/>
|
<openid-attribute name="email" type="http://axschema.org/contact/email" required="true"/>
|
||||||
<openid-attribute name="fullname" type="http://axschema.org/namePerson" required="true" />
|
<openid-attribute name="fullname" type="http://axschema.org/namePerson" required="true" />
|
||||||
</attribute-exchange>
|
</attribute-exchange>
|
||||||
|
<attribute-exchange identifier-match=".*myopenid.com.*">
|
||||||
|
<openid-attribute name="email" type="http://schema.openid.net/contact/email" required="true"/>
|
||||||
|
<openid-attribute name="fullname" type="http://schema.openid.net/namePerson" required="true" />
|
||||||
|
</attribute-exchange>
|
||||||
</openid-login>
|
</openid-login>
|
||||||
<remember-me token-repository-ref="tokenRepo"/>
|
<remember-me token-repository-ref="tokenRepo"/>
|
||||||
</http>
|
</http>
|
||||||
|
45
samples/openid/src/main/webapp/css/openid.css
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#openid_form {
|
||||||
|
width: 580px;
|
||||||
|
}
|
||||||
|
#openid_form legend {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
#openid_choice {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#openid_input_area {
|
||||||
|
clear: both;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
#openid_btns, #openid_btns br {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
#openid_highlight {
|
||||||
|
padding: 3px;
|
||||||
|
background-color: #FFFCC9;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.openid_large_btn {
|
||||||
|
width: 100px;
|
||||||
|
height: 60px;
|
||||||
|
border: 1px solid #DDD;
|
||||||
|
margin: 3px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.openid_small_btn {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border: 1px solid #DDD;
|
||||||
|
margin: 3px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
a.openid_large_btn:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
a.openid_large_btn:focus
|
||||||
|
{
|
||||||
|
-moz-outline-style: none;
|
||||||
|
}
|
||||||
|
.openid_selected {
|
||||||
|
border: 4px solid #DDD;
|
||||||
|
}
|
BIN
samples/openid/src/main/webapp/images/aol.gif
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
samples/openid/src/main/webapp/images/blogger.ico
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
samples/openid/src/main/webapp/images/claimid.ico
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
samples/openid/src/main/webapp/images/facebook.gif
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
samples/openid/src/main/webapp/images/flickr.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
samples/openid/src/main/webapp/images/google.gif
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
samples/openid/src/main/webapp/images/livejournal.ico
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
samples/openid/src/main/webapp/images/myopenid.ico
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
samples/openid/src/main/webapp/images/openid-inputicon.gif
Normal file
After Width: | Height: | Size: 237 B |
BIN
samples/openid/src/main/webapp/images/openid.gif
Normal file
After Width: | Height: | Size: 740 B |
BIN
samples/openid/src/main/webapp/images/technorati.ico
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
samples/openid/src/main/webapp/images/verisign.gif
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
samples/openid/src/main/webapp/images/verisign.ico
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
samples/openid/src/main/webapp/images/vidoop.ico
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
samples/openid/src/main/webapp/images/wordpress.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
samples/openid/src/main/webapp/images/yahoo.gif
Normal file
After Width: | Height: | Size: 1.6 KiB |
32
samples/openid/src/main/webapp/js/jquery-1.2.6.min.js
vendored
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
/**
|
||||||
|
* jQuery.query - Query String Modification and Creation for jQuery
|
||||||
|
* Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com)
|
||||||
|
* Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).
|
||||||
|
* Date: 2009/02/08
|
||||||
|
*
|
||||||
|
* @author Blair Mitchelmore
|
||||||
|
* @version 2.1.3
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
new function(settings) {
|
||||||
|
// Various Settings
|
||||||
|
var $separator = settings.separator || '&';
|
||||||
|
var $spaces = settings.spaces === false ? false : true;
|
||||||
|
var $suffix = settings.suffix === false ? '' : '[]';
|
||||||
|
var $prefix = settings.prefix === false ? false : true;
|
||||||
|
var $hash = $prefix ? settings.hash === true ? "#" : "?" : "";
|
||||||
|
var $numbers = settings.numbers === false ? false : true;
|
||||||
|
|
||||||
|
jQuery.query = new function() {
|
||||||
|
var is = function(o, t) {
|
||||||
|
return o != undefined && o !== null && (!!t ? o.constructor == t : true);
|
||||||
|
};
|
||||||
|
var parse = function(path) {
|
||||||
|
var m, rx = /\[([^[]*)\]/g, match = /^(\S+?)(\[\S*\])?$/.exec(path), base = match[1], tokens = [];
|
||||||
|
while (m = rx.exec(match[2])) tokens.push(m[1]);
|
||||||
|
return [base, tokens];
|
||||||
|
};
|
||||||
|
var set = function(target, tokens, value) {
|
||||||
|
var o, token = tokens.shift();
|
||||||
|
if (typeof target != 'object') target = null;
|
||||||
|
if (token === "") {
|
||||||
|
if (!target) target = [];
|
||||||
|
if (is(target, Array)) {
|
||||||
|
target.push(tokens.length == 0 ? value : set(null, tokens.slice(0), value));
|
||||||
|
} else if (is(target, Object)) {
|
||||||
|
var i = 0;
|
||||||
|
while (target[i++] != null);
|
||||||
|
target[--i] = tokens.length == 0 ? value : set(target[i], tokens.slice(0), value);
|
||||||
|
} else {
|
||||||
|
target = [];
|
||||||
|
target.push(tokens.length == 0 ? value : set(null, tokens.slice(0), value));
|
||||||
|
}
|
||||||
|
} else if (token && token.match(/^\s*[0-9]+\s*$/)) {
|
||||||
|
var index = parseInt(token, 10);
|
||||||
|
if (!target) target = [];
|
||||||
|
target[index] = tokens.length == 0 ? value : set(target[index], tokens.slice(0), value);
|
||||||
|
} else if (token) {
|
||||||
|
var index = token.replace(/^\s*|\s*$/g, "");
|
||||||
|
if (!target) target = {};
|
||||||
|
if (is(target, Array)) {
|
||||||
|
var temp = {};
|
||||||
|
for (var i = 0; i < target.length; ++i) {
|
||||||
|
temp[i] = target[i];
|
||||||
|
}
|
||||||
|
target = temp;
|
||||||
|
}
|
||||||
|
target[index] = tokens.length == 0 ? value : set(target[index], tokens.slice(0), value);
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
};
|
||||||
|
|
||||||
|
var queryObject = function(a) {
|
||||||
|
var self = this;
|
||||||
|
self.keys = {};
|
||||||
|
|
||||||
|
if (a.queryObject) {
|
||||||
|
jQuery.each(a.get(), function(key, val) {
|
||||||
|
self.SET(key, val);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
jQuery.each(arguments, function() {
|
||||||
|
var q = "" + this;
|
||||||
|
q = decodeURIComponent(q);
|
||||||
|
q = q.replace(/^[?#]/,''); // remove any leading ? || #
|
||||||
|
q = q.replace(/[;&]$/,''); // remove any trailing & || ;
|
||||||
|
if ($spaces) q = q.replace(/[+]/g,' '); // replace +'s with spaces
|
||||||
|
|
||||||
|
jQuery.each(q.split(/[&;]/), function(){
|
||||||
|
var key = this.split('=')[0];
|
||||||
|
var val = this.split('=')[1];
|
||||||
|
|
||||||
|
if (!key) return;
|
||||||
|
|
||||||
|
if ($numbers) {
|
||||||
|
if (/^[+-]?[0-9]+\.[0-9]*$/.test(val)) // simple float regex
|
||||||
|
val = parseFloat(val);
|
||||||
|
else if (/^[+-]?[0-9]+$/.test(val)) // simple int regex
|
||||||
|
val = parseInt(val, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
val = (!val && val !== 0) ? true : val;
|
||||||
|
|
||||||
|
if (val !== false && val !== true && typeof val != 'number')
|
||||||
|
val = val;
|
||||||
|
|
||||||
|
self.SET(key, val);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
};
|
||||||
|
|
||||||
|
queryObject.prototype = {
|
||||||
|
queryObject: true,
|
||||||
|
has: function(key, type) {
|
||||||
|
var value = this.get(key);
|
||||||
|
return is(value, type);
|
||||||
|
},
|
||||||
|
GET: function(key) {
|
||||||
|
if (!is(key)) return this.keys;
|
||||||
|
var parsed = parse(key), base = parsed[0], tokens = parsed[1];
|
||||||
|
var target = this.keys[base];
|
||||||
|
while (target != null && tokens.length != 0) {
|
||||||
|
target = target[tokens.shift()];
|
||||||
|
}
|
||||||
|
return typeof target == 'number' ? target : target || "";
|
||||||
|
},
|
||||||
|
get: function(key) {
|
||||||
|
var target = this.GET(key);
|
||||||
|
if (is(target, Object))
|
||||||
|
return jQuery.extend(true, {}, target);
|
||||||
|
else if (is(target, Array))
|
||||||
|
return target.slice(0);
|
||||||
|
return target;
|
||||||
|
},
|
||||||
|
SET: function(key, val) {
|
||||||
|
var value = !is(val) ? null : val;
|
||||||
|
var parsed = parse(key), base = parsed[0], tokens = parsed[1];
|
||||||
|
var target = this.keys[base];
|
||||||
|
this.keys[base] = set(target, tokens.slice(0), value);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
set: function(key, val) {
|
||||||
|
return this.copy().SET(key, val);
|
||||||
|
},
|
||||||
|
REMOVE: function(key) {
|
||||||
|
return this.SET(key, null).COMPACT();
|
||||||
|
},
|
||||||
|
remove: function(key) {
|
||||||
|
return this.copy().REMOVE(key);
|
||||||
|
},
|
||||||
|
EMPTY: function() {
|
||||||
|
var self = this;
|
||||||
|
jQuery.each(self.keys, function(key, value) {
|
||||||
|
delete self.keys[key];
|
||||||
|
});
|
||||||
|
return self;
|
||||||
|
},
|
||||||
|
load: function(url) {
|
||||||
|
var hash = url.replace(/^.*?[#](.+?)(?:\?.+)?$/, "$1");
|
||||||
|
var search = url.replace(/^.*?[?](.+?)(?:#.+)?$/, "$1");
|
||||||
|
return new queryObject(url.length == search.length ? '' : search, url.length == hash.length ? '' : hash);
|
||||||
|
},
|
||||||
|
empty: function() {
|
||||||
|
return this.copy().EMPTY();
|
||||||
|
},
|
||||||
|
copy: function() {
|
||||||
|
return new queryObject(this);
|
||||||
|
},
|
||||||
|
COMPACT: function() {
|
||||||
|
function build(orig) {
|
||||||
|
var obj = typeof orig == "object" ? is(orig, Array) ? [] : {} : orig;
|
||||||
|
if (typeof orig == 'object') {
|
||||||
|
function add(o, key, value) {
|
||||||
|
if (is(o, Array))
|
||||||
|
o.push(value);
|
||||||
|
else
|
||||||
|
o[key] = value;
|
||||||
|
}
|
||||||
|
jQuery.each(orig, function(key, value) {
|
||||||
|
if (!is(value)) return true;
|
||||||
|
add(obj, key, build(value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
this.keys = build(this.keys);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
compact: function() {
|
||||||
|
return this.copy().COMPACT();
|
||||||
|
},
|
||||||
|
toString: function() {
|
||||||
|
var i = 0, queryString = [], chunks = [], self = this;
|
||||||
|
var addFields = function(arr, key, value) {
|
||||||
|
if (!is(value) || value === false) return;
|
||||||
|
var o = [encodeURIComponent(key)];
|
||||||
|
if (value !== true) {
|
||||||
|
o.push("=");
|
||||||
|
o.push(encodeURIComponent(value));
|
||||||
|
}
|
||||||
|
arr.push(o.join(""));
|
||||||
|
};
|
||||||
|
var build = function(obj, base) {
|
||||||
|
var newKey = function(key) {
|
||||||
|
return !base || base == "" ? [key].join("") : [base, "[", key, "]"].join("");
|
||||||
|
};
|
||||||
|
jQuery.each(obj, function(key, value) {
|
||||||
|
if (typeof value == 'object')
|
||||||
|
build(value, newKey(key));
|
||||||
|
else
|
||||||
|
addFields(chunks, newKey(key), value);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
build(this.keys);
|
||||||
|
|
||||||
|
if (chunks.length > 0) queryString.push($hash);
|
||||||
|
queryString.push(chunks.join($separator));
|
||||||
|
|
||||||
|
return queryString.join("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return new queryObject(location.search, location.hash);
|
||||||
|
};
|
||||||
|
}(jQuery.query || {}); // Pass in jQuery.query as settings object
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
Defines the base of where the OpenID Provider redirects its response to.
|
||||||
|
*/
|
||||||
|
var server_root = "http://openid-selector.googlecode.com/svn/trunk/"
|
||||||
|
|
||||||
|
/*
|
||||||
|
On the server-side you'd accept an OpenID URL and perform discovery
|
||||||
|
on it to find out the actual OpenID endpoint to send the authentication
|
||||||
|
request to. On the client side it isn't possible to lookup the endpoint
|
||||||
|
from the target server due to XSS restrictions. The endpoint for each
|
||||||
|
provider is therefore cached in this static file. If an endpoint isn't
|
||||||
|
specified for a provider then authentication on the client side cannot
|
||||||
|
proceed.
|
||||||
|
*/
|
||||||
|
var providers_endpoint = {
|
||||||
|
google: 'https://www.google.com/accounts/o8/ud',
|
||||||
|
yahoo: 'https://open.login.yahooapis.com/openid/op/auth',
|
||||||
|
aol: 'https://api.screenname.aol.com/auth/openidServer',
|
||||||
|
verisign: 'http://pip.verisignlabs.com/server'
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
var claimedID;
|
||||||
|
var providerID;
|
||||||
|
var openIDPopup;
|
||||||
|
|
||||||
|
function OpenID_iframe_then_popup_handler(provider, claimed) {
|
||||||
|
providerID = provider;
|
||||||
|
claimedID = claimed;
|
||||||
|
var immediateiframe = document.getElementById("openid_immediate_iframe");
|
||||||
|
|
||||||
|
var iframeurl = getBaseOpenIDProviderURL(providerID, claimedID, true);
|
||||||
|
|
||||||
|
immediateiframe.innerHTML = "<iframe frameborder='1' src='" + iframeurl + "'></iframe>";
|
||||||
|
}
|
||||||
|
|
||||||
|
function processOpenIDImmediateResponse(responseURL) {
|
||||||
|
var immediateiframe = document.getElementById("openid_immediate_iframe");
|
||||||
|
immediateiframe.innerHTML = responseURL;
|
||||||
|
|
||||||
|
var failure = new RegExp("openid.mode=setup_needed");
|
||||||
|
if(failure.test(responseURL)) {
|
||||||
|
var popupurl = getBaseOpenIDProviderURL(providerID, claimedID, false);
|
||||||
|
openIDPopup = window.open(popupurl, "OpenIDPopup");
|
||||||
|
} else {
|
||||||
|
alert("Success without popup!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function processOpenIDSetupResponse(responseURL) {
|
||||||
|
openIDPopup.close();
|
||||||
|
|
||||||
|
var results = "";
|
||||||
|
var responseQuery = $.query.load(responseURL);
|
||||||
|
$.each(responseQuery.get(), function(key, value) {
|
||||||
|
results += "<br/>" + key + "=" + value;
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("openid_status").innerHTML = "<br/>Result of authentication is: " + results;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBaseOpenIDProviderURL(provider, claimed, immediate) {
|
||||||
|
var providerEndpoint = providers_endpoint[provider];
|
||||||
|
var providerURL = providerEndpoint; //From previous discovery
|
||||||
|
providerURL += "?";
|
||||||
|
providerURL += "openid.ns=" + encodeURIComponent("http://specs.openid.net/auth/2.0");
|
||||||
|
if(providers[provider].label) {
|
||||||
|
providerURL += "&openid.claimed_id=" + encodeURIComponent(claimed);
|
||||||
|
providerURL += "&openid.identity=" + encodeURIComponent(claimed);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
providerURL += "&openid.claimed_id=" + encodeURIComponent("http://specs.openid.net/auth/2.0/identifier_select");
|
||||||
|
providerURL += "&openid.identity=" + encodeURIComponent("http://specs.openid.net/auth/2.0/identifier_select");
|
||||||
|
}
|
||||||
|
if(immediate) {
|
||||||
|
providerURL += "&openid.return_to=" + encodeURIComponent(server_root + "openid-client/checkid_immediate_response.html");
|
||||||
|
providerURL += "&openid.realm=" + encodeURIComponent(server_root + "openid-client/checkid_immediate_response.html");
|
||||||
|
providerURL += "&openid.mode=checkid_immediate";
|
||||||
|
} else {
|
||||||
|
providerURL += "&openid.return_to=" + encodeURIComponent(server_root + "openid-client/checkid_setup_response.html");
|
||||||
|
providerURL += "&openid.realm=" + encodeURIComponent(server_root + "openid-client/checkid_setup_response.html");
|
||||||
|
providerURL += "&openid.mode=checkid_setup";
|
||||||
|
}
|
||||||
|
return providerURL;
|
||||||
|
}
|
240
samples/openid/src/main/webapp/js/openid-jquery.js
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
/*
|
||||||
|
Simple OpenID Plugin
|
||||||
|
http://code.google.com/p/openid-selector/
|
||||||
|
|
||||||
|
This code is licenced under the New BSD License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var providers_large = {
|
||||||
|
google: {
|
||||||
|
name: 'Google',
|
||||||
|
url: 'https://www.google.com/accounts/o8/id'
|
||||||
|
},
|
||||||
|
yahoo: {
|
||||||
|
name: 'Yahoo',
|
||||||
|
url: 'http://yahoo.com/'
|
||||||
|
},
|
||||||
|
aol: {
|
||||||
|
name: 'AOL',
|
||||||
|
label: 'Enter your AOL screenname.',
|
||||||
|
url: 'http://openid.aol.com/{username}'
|
||||||
|
},
|
||||||
|
verisign: {
|
||||||
|
name: 'Verisign',
|
||||||
|
label: 'Your Verisign username',
|
||||||
|
url: 'http://{username}.pip.verisignlabs.com/'
|
||||||
|
},
|
||||||
|
openid: {
|
||||||
|
name: 'OpenID',
|
||||||
|
label: 'Enter your OpenID.',
|
||||||
|
url: null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var providers_small = {
|
||||||
|
myopenid: {
|
||||||
|
name: 'MyOpenID',
|
||||||
|
label: 'Enter your MyOpenID username.',
|
||||||
|
url: 'http://{username}.myopenid.com/'
|
||||||
|
},
|
||||||
|
livejournal: {
|
||||||
|
name: 'LiveJournal',
|
||||||
|
label: 'Enter your Livejournal username.',
|
||||||
|
url: 'http://{username}.livejournal.com/'
|
||||||
|
},
|
||||||
|
flickr: {
|
||||||
|
name: 'Flickr',
|
||||||
|
label: 'Enter your Flickr username.',
|
||||||
|
url: 'http://flickr.com/{username}/'
|
||||||
|
},
|
||||||
|
technorati: {
|
||||||
|
name: 'Technorati',
|
||||||
|
label: 'Enter your Technorati username.',
|
||||||
|
url: 'http://technorati.com/people/technorati/{username}/'
|
||||||
|
},
|
||||||
|
wordpress: {
|
||||||
|
name: 'Wordpress',
|
||||||
|
label: 'Enter your Wordpress.com username.',
|
||||||
|
url: 'http://{username}.wordpress.com/'
|
||||||
|
},
|
||||||
|
blogger: {
|
||||||
|
name: 'Blogger',
|
||||||
|
label: 'Your Blogger account',
|
||||||
|
url: 'http://{username}.blogspot.com/'
|
||||||
|
},
|
||||||
|
vidoop: {
|
||||||
|
name: 'Vidoop',
|
||||||
|
label: 'Your Vidoop username',
|
||||||
|
url: 'http://{username}.myvidoop.com/'
|
||||||
|
},
|
||||||
|
claimid: {
|
||||||
|
name: 'ClaimID',
|
||||||
|
label: 'Your ClaimID username',
|
||||||
|
url: 'http://claimid.com/{username}'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var providers = $.extend({}, providers_large, providers_small);
|
||||||
|
|
||||||
|
var openid = {
|
||||||
|
|
||||||
|
demo: false,
|
||||||
|
ajaxHandler: null,
|
||||||
|
cookie_expires: 6*30, // 6 months.
|
||||||
|
cookie_name: 'openid_provider',
|
||||||
|
cookie_path: '/',
|
||||||
|
|
||||||
|
img_path: 'images/',
|
||||||
|
|
||||||
|
input_id: null,
|
||||||
|
provider_url: null,
|
||||||
|
provider_id: null,
|
||||||
|
|
||||||
|
init: function(input_id) {
|
||||||
|
|
||||||
|
var openid_btns = $('#openid_btns');
|
||||||
|
|
||||||
|
this.input_id = input_id;
|
||||||
|
|
||||||
|
$('#openid_choice').show();
|
||||||
|
$('#openid_input_area').empty();
|
||||||
|
|
||||||
|
// add box for each provider
|
||||||
|
for (id in providers_large) {
|
||||||
|
|
||||||
|
openid_btns.append(this.getBoxHTML(providers_large[id], 'large', '.gif'));
|
||||||
|
}
|
||||||
|
if (providers_small) {
|
||||||
|
openid_btns.append('<br/>');
|
||||||
|
|
||||||
|
for (id in providers_small) {
|
||||||
|
|
||||||
|
openid_btns.append(this.getBoxHTML(providers_small[id], 'small', '.ico'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#openid_form').submit(this.submit);
|
||||||
|
|
||||||
|
var box_id = this.readCookie();
|
||||||
|
if (box_id) {
|
||||||
|
this.signin(box_id, true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getBoxHTML: function(provider, box_size, image_ext) {
|
||||||
|
|
||||||
|
var box_id = provider["name"].toLowerCase();
|
||||||
|
return '<a title="'+provider["name"]+'" href="javascript: openid.signin(\''+ box_id +'\');"' +
|
||||||
|
' style="background: #FFF url(' + this.img_path + box_id + image_ext+') no-repeat center center" ' +
|
||||||
|
'class="' + box_id + ' openid_' + box_size + '_btn"></a>';
|
||||||
|
|
||||||
|
},
|
||||||
|
/* Provider image click */
|
||||||
|
signin: function(box_id, onload) {
|
||||||
|
|
||||||
|
var provider = providers[box_id];
|
||||||
|
if (! provider) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.highlight(box_id);
|
||||||
|
this.setCookie(box_id);
|
||||||
|
|
||||||
|
this.provider_id = box_id;
|
||||||
|
this.provider_url = provider['url'];
|
||||||
|
|
||||||
|
// prompt user for input?
|
||||||
|
if (provider['label']) {
|
||||||
|
this.useInputBox(provider);
|
||||||
|
} else {
|
||||||
|
$('#openid_input_area').empty();
|
||||||
|
if (! onload) {
|
||||||
|
$('#openid_form').submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* Sign-in button click */
|
||||||
|
submit: function() {
|
||||||
|
|
||||||
|
var url = openid.provider_url;
|
||||||
|
if (url) {
|
||||||
|
url = url.replace('{username}', $('#openid_username').val());
|
||||||
|
openid.setOpenIdUrl(url);
|
||||||
|
}
|
||||||
|
if(openid.ajaxHandler) {
|
||||||
|
openid.ajaxHandler(openid.provider_id, document.getElementById(openid.input_id).value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(openid.demo) {
|
||||||
|
alert("In client demo mode. Normally would have submitted OpenID:\r\n" + document.getElementById(openid.input_id).value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
setOpenIdUrl: function (url) {
|
||||||
|
|
||||||
|
var hidden = document.getElementById(this.input_id);
|
||||||
|
if (hidden != null) {
|
||||||
|
hidden.value = url;
|
||||||
|
} else {
|
||||||
|
$('#openid_form').append('<input type="hidden" id="' + this.input_id + '" name="' + this.input_id + '" value="'+url+'"/>');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
highlight: function (box_id) {
|
||||||
|
|
||||||
|
// remove previous highlight.
|
||||||
|
var highlight = $('#openid_highlight');
|
||||||
|
if (highlight) {
|
||||||
|
highlight.replaceWith($('#openid_highlight a')[0]);
|
||||||
|
}
|
||||||
|
// add new highlight.
|
||||||
|
$('.'+box_id).wrap('<div id="openid_highlight"></div>');
|
||||||
|
},
|
||||||
|
setCookie: function (value) {
|
||||||
|
|
||||||
|
var date = new Date();
|
||||||
|
date.setTime(date.getTime()+(this.cookie_expires*24*60*60*1000));
|
||||||
|
var expires = "; expires="+date.toGMTString();
|
||||||
|
|
||||||
|
document.cookie = this.cookie_name+"="+value+expires+"; path=" + this.cookie_path;
|
||||||
|
},
|
||||||
|
readCookie: function () {
|
||||||
|
var nameEQ = this.cookie_name + "=";
|
||||||
|
var ca = document.cookie.split(';');
|
||||||
|
for(var i=0;i < ca.length;i++) {
|
||||||
|
var c = ca[i];
|
||||||
|
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||||
|
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
useInputBox: function (provider) {
|
||||||
|
|
||||||
|
var input_area = $('#openid_input_area');
|
||||||
|
|
||||||
|
var html = '';
|
||||||
|
var id = 'openid_username';
|
||||||
|
var value = '';
|
||||||
|
var label = provider['label'];
|
||||||
|
var style = '';
|
||||||
|
|
||||||
|
if (label) {
|
||||||
|
html = '<p>' + label + '</p>';
|
||||||
|
}
|
||||||
|
if (provider['name'] == 'OpenID') {
|
||||||
|
id = this.input_id;
|
||||||
|
value = 'http://';
|
||||||
|
style = 'background:#FFF url('+this.img_path+'openid-inputicon.gif) no-repeat scroll 0 50%; padding-left:18px;';
|
||||||
|
}
|
||||||
|
html += '<input id="'+id+'" type="text" style="'+style+'" name="'+id+'" value="'+value+'" />' +
|
||||||
|
'<input id="openid_submit" type="submit" value="Sign-In"/>';
|
||||||
|
|
||||||
|
input_area.empty();
|
||||||
|
input_area.append(html);
|
||||||
|
|
||||||
|
$('#'+id).focus();
|
||||||
|
},
|
||||||
|
setDemoMode: function (demoMode) {
|
||||||
|
this.demo = demoMode;
|
||||||
|
},
|
||||||
|
setAjaxHandler: function (ajaxFunction) {
|
||||||
|
this.ajaxHandler = ajaxFunction;
|
||||||
|
}
|
||||||
|
};
|
@ -1,33 +1,64 @@
|
|||||||
<%@ taglib prefix='c' uri='http://java.sun.com/jstl/core_rt' %>
|
<%@ taglib prefix='c' uri='http://java.sun.com/jstl/core_rt' %>
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>OpenID Login</title>
|
||||||
|
|
||||||
<html>
|
<!-- Simple OpenID Selector -->
|
||||||
<head>
|
<link rel="stylesheet" href="<c:url value='/css/openid.css'/>" />
|
||||||
<title>Open ID Login</title>
|
<script type="text/javascript" src="<c:url value='/js/jquery-1.2.6.min.js'/>"></script>
|
||||||
</head>
|
<script type="text/javascript" src="<c:url value='/js/openid-jquery.js'/>"></script>
|
||||||
|
|
||||||
<body onload="document.f.j_username.focus();">
|
<script type="text/javascript">
|
||||||
<h3>Please Enter Your OpenID Identity</h3>
|
$(document).ready(function() {
|
||||||
|
openid.init('openid_identifier');
|
||||||
|
// openid.setDemoMode(true); Stops form submission for client javascript-only test purposes
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<!-- /Simple OpenID Selector -->
|
||||||
|
|
||||||
<%-- this form-login-page form is also used as the
|
<style type="text/css">
|
||||||
form-error-page to ask for a login again.
|
/* Basic page formatting. */
|
||||||
--%>
|
body {
|
||||||
<c:if test="${not empty param.login_error}">
|
font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
<font color="red">
|
}
|
||||||
Your login attempt was not successful, try again.<br/><br/>
|
</style>
|
||||||
Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}"/>.
|
</head>
|
||||||
</font>
|
|
||||||
</c:if>
|
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
<form name="f" action="<c:url value='j_spring_openid_security_check'/>" method="POST">
|
<c:if test="${not empty param.login_error}">
|
||||||
<table>
|
<font color="red">
|
||||||
<tr><td>OpenID Identity:</td><td><input type='text' name='openid_identifier' value='<c:if test="${not empty param.login_error}"><c:out value="${SPRING_SECURITY_LAST_USERNAME}"/></c:if>'/></td></tr>
|
Your login attempt was not successful, try again.<br/><br/>
|
||||||
<tr><td><input type="checkbox" name="_spring_security_remember_me"></td><td>Remember me on this computer.</td></tr>
|
Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}"/>.
|
||||||
<tr><td colspan='2'><input name="submit" type="submit"></td></tr>
|
</font>
|
||||||
<tr><td colspan='2'><input name="reset" type="reset"></td></tr>
|
</c:if>
|
||||||
</table>
|
|
||||||
|
|
||||||
</form>
|
<!-- Simple OpenID Selector -->
|
||||||
|
<form action="<c:url value='j_spring_openid_security_check'/>" method="post" id="openid_form">
|
||||||
|
<input type="hidden" name="action" value="verify" />
|
||||||
|
|
||||||
</body>
|
<fieldset>
|
||||||
|
<legend>Sign-in or Create New Account</legend>
|
||||||
|
|
||||||
|
<div id="openid_choice">
|
||||||
|
<p>Please click your account provider:</p>
|
||||||
|
<div id="openid_btns"></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="openid_input_area">
|
||||||
|
<input id="openid_identifier" name="openid_identifier" type="text" value="http://" />
|
||||||
|
<input id="openid_submit" type="submit" value="Sign-In"/>
|
||||||
|
</div>
|
||||||
|
<noscript>
|
||||||
|
<p>OpenID is a service that allows you to log-on to many different websites using a single indentity.
|
||||||
|
Find out <a href="http://openid.net/what/">more about OpenID</a> and <a href="http://openid.net/get/">how to get an OpenID enabled account</a>.</p>
|
||||||
|
</noscript>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
<!-- /Simple OpenID Selector -->
|
||||||
|
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|