Use xml / javaconfig folders for samples
Fixes gh-3752
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.samples.config;
|
||||
|
||||
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
|
||||
|
||||
/**
|
||||
* No customizations of {@link AbstractSecurityWebApplicationInitializer} are necessary.
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class MessageSecurityWebApplicationInitializer extends
|
||||
AbstractSecurityWebApplicationInitializer {
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.samples.config;
|
||||
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.samples.security.CustomUserDetailsService;
|
||||
|
||||
@EnableWebSecurity
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
// @formatter:off
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.authorizeRequests()
|
||||
.antMatchers("/resources/**").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.openidLogin()
|
||||
.loginPage("/login")
|
||||
.permitAll()
|
||||
.authenticationUserDetailsService(new CustomUserDetailsService())
|
||||
.attributeExchange("https://www.google.com/.*")
|
||||
.attribute("email")
|
||||
.type("http://axschema.org/contact/email")
|
||||
.required(true)
|
||||
.and()
|
||||
.attribute("firstname")
|
||||
.type("http://axschema.org/namePerson/first")
|
||||
.required(true)
|
||||
.and()
|
||||
.attribute("lastname")
|
||||
.type("http://axschema.org/namePerson/last")
|
||||
.required(true)
|
||||
.and()
|
||||
.and()
|
||||
.attributeExchange(".*yahoo.com.*")
|
||||
.attribute("email")
|
||||
.type("http://axschema.org/contact/email")
|
||||
.required(true)
|
||||
.and()
|
||||
.attribute("fullname")
|
||||
.type("http://axschema.org/namePerson")
|
||||
.required(true)
|
||||
.and()
|
||||
.and()
|
||||
.attributeExchange(".*myopenid.com.*")
|
||||
.attribute("email")
|
||||
.type("http://schema.openid.net/contact/email")
|
||||
.required(true)
|
||||
.and()
|
||||
.attribute("fullname")
|
||||
.type("http://schema.openid.net/namePerson")
|
||||
.required(true);
|
||||
}
|
||||
// @formatter:on
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.samples.mvc;
|
||||
|
||||
import org.springframework.security.openid.OpenIDAuthenticationToken;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/user/")
|
||||
public class UserController {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
public String show(Model model, OpenIDAuthenticationToken authentication) {
|
||||
model.addAttribute("authentication", authentication);
|
||||
return "user/show";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.samples.security;
|
||||
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.openid.OpenIDAuthenticationToken;
|
||||
|
||||
public class CustomUserDetailsService implements
|
||||
AuthenticationUserDetailsService<OpenIDAuthenticationToken> {
|
||||
public UserDetails loadUserDetails(OpenIDAuthenticationToken token)
|
||||
throws UsernameNotFoundException {
|
||||
return new User(token.getName(), "",
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||
}
|
||||
}
|
||||
12
samples/javaconfig/openid/src/main/resources/logback.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
@@ -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;
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 237 B |
|
After Width: | Height: | Size: 740 B |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
32
samples/javaconfig/openid/src/main/resources/resources/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;
|
||||
}
|
||||
@@ -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: 'https://me.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: 'resources/img/',
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
42
samples/javaconfig/openid/src/main/resources/users.ldif
Normal file
@@ -0,0 +1,42 @@
|
||||
dn: ou=groups,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: groups
|
||||
|
||||
dn: ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: people
|
||||
|
||||
dn: uid=admin,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: Rod Johnson
|
||||
sn: Johnson
|
||||
uid: admin
|
||||
userPassword: password
|
||||
|
||||
dn: uid=user,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: Dianne Emu
|
||||
sn: Emu
|
||||
uid: user
|
||||
userPassword: password
|
||||
|
||||
dn: cn=user,ou=groups,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: user
|
||||
member: uid=admin,ou=people,dc=springframework,dc=org
|
||||
member: uid=user,ou=people,dc=springframework,dc=org
|
||||
|
||||
dn: cn=admin,ou=groups,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: admin
|
||||
member: uid=admin,ou=people,dc=springframework,dc=org
|
||||
@@ -0,0 +1,46 @@
|
||||
<html xmlns:th="http://www.thymeleaf.org" xmlns:tiles="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title tiles:fragment="title">Messages : Login</title>
|
||||
<!-- /Simple OpenID Selector -->
|
||||
<link rel="stylesheet" th:href="@{/resources/css/openid.css}" />
|
||||
</head>
|
||||
<body>
|
||||
<div tiles:fragment="content">
|
||||
<form name="f" th:action="@{/login/openid}" method="post" id="openid_form">
|
||||
<input type="hidden" name="action" value="verify" />
|
||||
<fieldset>
|
||||
<legend>Sign-in or Create New Account</legend>
|
||||
<div th:if="${param.error}" class="alert alert-error">
|
||||
Invalid username and password.
|
||||
</div>
|
||||
<div th:if="${param.logout}" class="alert alert-success">
|
||||
You have been logged out.
|
||||
</div>
|
||||
<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 identity.
|
||||
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>
|
||||
|
||||
<script type="text/javascript" th:src="@{/resources/js/jquery-1.2.6.min.js}"><!-- --></script>
|
||||
<script type="text/javascript" th:src="@{/resources/js/openid-jquery.js}"><!-- --></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
openid.init('openid_identifier');
|
||||
// openid.setDemoMode(true); Stops form submission for client javascript-only test purposes
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,34 @@
|
||||
<html xmlns:th="http://www.thymeleaf.org" xmlns:tiles="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title tiles:fragment="title">Messages : Login</title>
|
||||
<!-- /Simple OpenID Selector -->
|
||||
<link rel="stylesheet" th:href="@{/resources/css/openid.css}" />
|
||||
</head>
|
||||
<body>
|
||||
<div tiles:fragment="content">
|
||||
<h1>User Attributes</h1>
|
||||
<table class="table table-border">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Attribute Name</th>
|
||||
<th>Attribute Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>ID</td>
|
||||
<td th:text="${authentication.identityUrl}">https://example.com/user/id</td>
|
||||
</tr>
|
||||
<tr th:each="attribute : ${authentication.attributes}">
|
||||
<td th:text="${attribute.name}">Attribute Name</td>
|
||||
<td>
|
||||
<dl th:each="value : ${attribute.values}">
|
||||
<dd th:text="${value}">Attribute Value</dd>
|
||||
</dl>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,42 @@
|
||||
<jsp:root
|
||||
xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:form="http://www.springframework.org/tags/form"
|
||||
xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
|
||||
version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html"/>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>User</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>User Attributes</h1>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Attribute Name</th>
|
||||
<th>Attribute Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>ID</td>
|
||||
<td><c:out value="${authentication.identityUrl}"/></td>
|
||||
</tr>
|
||||
<c:forEach items="${authentication.attributes}" var="attribute">
|
||||
<tr>
|
||||
<td><c:out value="${attribute.name}"/></td>
|
||||
<td>
|
||||
<dl>
|
||||
<c:forEach items="${attribute.values}" var="value">
|
||||
<dd><c:out value="${value}"/></dd>
|
||||
</c:forEach>
|
||||
</dl>
|
||||
</td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
||||
@@ -0,0 +1,2 @@
|
||||
Manifest-Version: 1.0
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.samples.config;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.web.FilterChainProxy;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class SecurityConfigTests {
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = "org.springframework.security.samples.config")
|
||||
public static class Config {
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private FilterChainProxy springSecurityFilterChain;
|
||||
|
||||
@Test
|
||||
public void securityConfigurationLoads() {
|
||||
}
|
||||
}
|
||||