diff --git a/docs/manual/src/docbook/samples.xml b/docs/manual/src/docbook/samples.xml
index 89f3907d40..1503de9bf1 100644
--- a/docs/manual/src/docbook/samples.xml
+++ b/docs/manual/src/docbook/samples.xml
@@ -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
authentication providers configured in this application.
+
+ OpenID Sample
+
+ The OpenID sample demonstrates how to use the namespace to configure OpenID and how to set up
+ attribute exchange
+ configurations for Google, Yahoo and MyOpenID identity providers (you can experiment with adding others
+ if you wish). It uses the JQuery-based openid-selector
+ 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.
+
+
+ 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 Welcome [your name]"
+ message. If you logout and log back in (with the same OpenID identity) then this should change to Welcome Back.
+ This is achieved by using a custom UserDetailsService 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.
+
+ CAS Sample The CAS sample requires that you run both a CAS server and CAS client. It isn't
diff --git a/samples/openid/src/main/java/org/springframework/security/samples/openid/CustomUserDetailsService.java b/samples/openid/src/main/java/org/springframework/security/samples/openid/CustomUserDetailsService.java
index cfa736673a..57dd73c633 100644
--- a/samples/openid/src/main/java/org/springframework/security/samples/openid/CustomUserDetailsService.java
+++ b/samples/openid/src/main/java/org/springframework/security/samples/openid/CustomUserDetailsService.java
@@ -69,6 +69,10 @@ public class CustomUserDetailsService implements UserDetailsService, Authenticat
firstName = attribute.getValues().get(0);
}
+ if (attribute.getName().equals("lastname")) {
+ lastName = attribute.getValues().get(0);
+ }
+
if (attribute.getName().equals("fullname")) {
fullName = attribute.getValues().get(0);
}
diff --git a/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml b/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml
index ff1b9ccbed..aa13cc6531 100644
--- a/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml
+++ b/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml
@@ -11,8 +11,11 @@
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
-
+
+
+
+
@@ -25,6 +28,10 @@
+
+
+
+
diff --git a/samples/openid/src/main/webapp/css/openid.css b/samples/openid/src/main/webapp/css/openid.css
new file mode 100644
index 0000000000..8929ff07ab
--- /dev/null
+++ b/samples/openid/src/main/webapp/css/openid.css
@@ -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;
+ }
\ No newline at end of file
diff --git a/samples/openid/src/main/webapp/images/aol.gif b/samples/openid/src/main/webapp/images/aol.gif
new file mode 100644
index 0000000000..decc4f1236
Binary files /dev/null and b/samples/openid/src/main/webapp/images/aol.gif differ
diff --git a/samples/openid/src/main/webapp/images/blogger.ico b/samples/openid/src/main/webapp/images/blogger.ico
new file mode 100644
index 0000000000..1b9730b01c
Binary files /dev/null and b/samples/openid/src/main/webapp/images/blogger.ico differ
diff --git a/samples/openid/src/main/webapp/images/claimid.ico b/samples/openid/src/main/webapp/images/claimid.ico
new file mode 100644
index 0000000000..2b80f49183
Binary files /dev/null and b/samples/openid/src/main/webapp/images/claimid.ico differ
diff --git a/samples/openid/src/main/webapp/images/facebook.gif b/samples/openid/src/main/webapp/images/facebook.gif
new file mode 100644
index 0000000000..b997b358f7
Binary files /dev/null and b/samples/openid/src/main/webapp/images/facebook.gif differ
diff --git a/samples/openid/src/main/webapp/images/flickr.ico b/samples/openid/src/main/webapp/images/flickr.ico
new file mode 100644
index 0000000000..11f6e07f68
Binary files /dev/null and b/samples/openid/src/main/webapp/images/flickr.ico differ
diff --git a/samples/openid/src/main/webapp/images/google.gif b/samples/openid/src/main/webapp/images/google.gif
new file mode 100644
index 0000000000..1b6cd07bd8
Binary files /dev/null and b/samples/openid/src/main/webapp/images/google.gif differ
diff --git a/samples/openid/src/main/webapp/images/livejournal.ico b/samples/openid/src/main/webapp/images/livejournal.ico
new file mode 100644
index 0000000000..f3d21ec5e8
Binary files /dev/null and b/samples/openid/src/main/webapp/images/livejournal.ico differ
diff --git a/samples/openid/src/main/webapp/images/myopenid.ico b/samples/openid/src/main/webapp/images/myopenid.ico
new file mode 100644
index 0000000000..ceb06e6a3f
Binary files /dev/null and b/samples/openid/src/main/webapp/images/myopenid.ico differ
diff --git a/samples/openid/src/main/webapp/images/openid-inputicon.gif b/samples/openid/src/main/webapp/images/openid-inputicon.gif
new file mode 100644
index 0000000000..cde836c893
Binary files /dev/null and b/samples/openid/src/main/webapp/images/openid-inputicon.gif differ
diff --git a/samples/openid/src/main/webapp/images/openid.gif b/samples/openid/src/main/webapp/images/openid.gif
new file mode 100644
index 0000000000..c718b0e6f3
Binary files /dev/null and b/samples/openid/src/main/webapp/images/openid.gif differ
diff --git a/samples/openid/src/main/webapp/images/technorati.ico b/samples/openid/src/main/webapp/images/technorati.ico
new file mode 100644
index 0000000000..fa1083c116
Binary files /dev/null and b/samples/openid/src/main/webapp/images/technorati.ico differ
diff --git a/samples/openid/src/main/webapp/images/verisign.gif b/samples/openid/src/main/webapp/images/verisign.gif
new file mode 100644
index 0000000000..faa6aaafbd
Binary files /dev/null and b/samples/openid/src/main/webapp/images/verisign.gif differ
diff --git a/samples/openid/src/main/webapp/images/verisign.ico b/samples/openid/src/main/webapp/images/verisign.ico
new file mode 100644
index 0000000000..3953af9319
Binary files /dev/null and b/samples/openid/src/main/webapp/images/verisign.ico differ
diff --git a/samples/openid/src/main/webapp/images/vidoop.ico b/samples/openid/src/main/webapp/images/vidoop.ico
new file mode 100644
index 0000000000..bbd9a0d50f
Binary files /dev/null and b/samples/openid/src/main/webapp/images/vidoop.ico differ
diff --git a/samples/openid/src/main/webapp/images/wordpress.ico b/samples/openid/src/main/webapp/images/wordpress.ico
new file mode 100644
index 0000000000..31b7d2c2b7
Binary files /dev/null and b/samples/openid/src/main/webapp/images/wordpress.ico differ
diff --git a/samples/openid/src/main/webapp/images/yahoo.gif b/samples/openid/src/main/webapp/images/yahoo.gif
new file mode 100644
index 0000000000..42adbfa57f
Binary files /dev/null and b/samples/openid/src/main/webapp/images/yahoo.gif differ
diff --git a/samples/openid/src/main/webapp/js/jquery-1.2.6.min.js b/samples/openid/src/main/webapp/js/jquery-1.2.6.min.js
new file mode 100644
index 0000000000..82b98e1d76
--- /dev/null
+++ b/samples/openid/src/main/webapp/js/jquery-1.2.6.min.js
@@ -0,0 +1,32 @@
+/*
+ * jQuery 1.2.6 - New Wave Javascript
+ *
+ * Copyright (c) 2008 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
+ * $Rev: 5685 $
+ */
+(function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else
+return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else
+return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else
+selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else
+this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else
+return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else
+jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else
+jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">"+tag+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"
+
+
- <%-- this form-login-page form is also used as the
- form-error-page to ask for a login again.
- --%>
-
-
- Your login attempt was not successful, try again.