diff --git a/samples/openid/openid.gradle b/samples/openid/openid.gradle index e22ef503f5..a8d5269831 100644 --- a/samples/openid/openid.gradle +++ b/samples/openid/openid.gradle @@ -4,10 +4,13 @@ apply plugin: 'war' apply plugin: 'jetty' dependencies { + compile project(':spring-security-core'), + project(':spring-security-openid') + providedCompile 'javax.servlet:servlet-api:2.5@jar' runtime project(':spring-security-web'), project(':spring-security-config'), - project(':spring-security-openid'), + project(':spring-security-taglibs'), 'log4j:log4j:1.2.15@jar' } \ No newline at end of file diff --git a/samples/openid/pom.xml b/samples/openid/pom.xml index 24d666fc70..b3b1b54a09 100644 --- a/samples/openid/pom.xml +++ b/samples/openid/pom.xml @@ -25,6 +25,11 @@ spring-security-web ${project.version} + + org.springframework.security + spring-security-taglibs + ${project.version} + org.springframework.security spring-security-openid diff --git a/samples/openid/src/main/java/org/springframework/security/samples/openid/CustomUserDetails.java b/samples/openid/src/main/java/org/springframework/security/samples/openid/CustomUserDetails.java new file mode 100644 index 0000000000..4175d2893d --- /dev/null +++ b/samples/openid/src/main/java/org/springframework/security/samples/openid/CustomUserDetails.java @@ -0,0 +1,47 @@ +package org.springframework.security.samples.openid; + +import java.util.Collection; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.User; + +/** + * Customized {@code UserDetails} implementation. + * + * @author Luke Taylor + * @since 3.1 + */ +public class CustomUserDetails extends User { + private String email; + private String name; + private boolean newUser; + + public CustomUserDetails(String username, Collection authorities) { + super(username, "unused", authorities); + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public boolean isNewUser() { + return newUser; + } + + public void setNewUser(boolean newUser) { + this.newUser = newUser; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} + 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 new file mode 100644 index 0000000000..cfa736673a --- /dev/null +++ b/samples/openid/src/main/java/org/springframework/security/samples/openid/CustomUserDetailsService.java @@ -0,0 +1,103 @@ +package org.springframework.security.samples.openid; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.openid.OpenIDAttribute; +import org.springframework.security.openid.OpenIDAuthenticationToken; + +/** + * Custom UserDetailsService which accepts any OpenID user, "registering" new users in a map so they can be welcomed + * back to the site on subsequent logins. + * + * @author Luke Taylor + * @since 3.1 + */ +public class CustomUserDetailsService implements UserDetailsService, AuthenticationUserDetailsService { + + private Map registeredUsers = new HashMap(); + + private static final List DEFAULT_AUTHORITIES = AuthorityUtils.createAuthorityList("ROLE_USER"); + + /** + * Implementation of {@code UserDetailsService}. We only need this to satisfy the {@code RememberMeServices} + * requirements. + */ + public UserDetails loadUserByUsername(String id) throws UsernameNotFoundException { + UserDetails user = registeredUsers.get(id); + + if (user == null) { + throw new UsernameNotFoundException(id); + } + + return user; + } + + /** + * Implementation of {@code AuthenticationUserDetailsService} which allows full access to the submitted + * {@code Authentication} object. Used by the OpenIDAuthenticationProvider. + */ + public UserDetails loadUserDetails(OpenIDAuthenticationToken token) { + String id = token.getIdentityUrl(); + + CustomUserDetails user = registeredUsers.get(id); + + if (user != null) { + return user; + } + + String email = null; + String firstName = null; + String lastName = null; + String fullName = null; + + List attributes = token.getAttributes(); + + for (OpenIDAttribute attribute : attributes) { + if (attribute.getName().equals("email")) { + email = attribute.getValues().get(0); + } + + if (attribute.getName().equals("firstname")) { + firstName = attribute.getValues().get(0); + } + + if (attribute.getName().equals("fullname")) { + fullName = attribute.getValues().get(0); + } + } + + if (fullName == null) { + StringBuilder fullNameBldr = new StringBuilder(); + + if (firstName != null) { + fullNameBldr.append(firstName); + } + + if (lastName != null) { + fullNameBldr.append(" ").append(lastName); + } + fullName = fullNameBldr.toString(); + } + + user = new CustomUserDetails(id, DEFAULT_AUTHORITIES); + user.setEmail(email); + user.setName(fullName); + + registeredUsers.put(id, user); + + user = new CustomUserDetails(id, DEFAULT_AUTHORITIES); + user.setEmail(email); + user.setName(fullName); + user.setNewUser(true); + + return user; + } +} diff --git a/samples/openid/src/main/java/zzz/Dummy.java b/samples/openid/src/main/java/zzz/Dummy.java deleted file mode 100644 index ca5d30edb5..0000000000 --- a/samples/openid/src/main/java/zzz/Dummy.java +++ /dev/null @@ -1,6 +0,0 @@ -package zzz; -/** - * @author Luke Taylor - */ -public class Dummy { -} 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 fbb072e491..7741b8358d 100644 --- a/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml +++ b/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml @@ -14,10 +14,13 @@ - + - - + + + + @@ -28,11 +31,13 @@ + + diff --git a/samples/openid/src/main/webapp/index.jsp b/samples/openid/src/main/webapp/index.jsp index c815d484a3..dcf993ff34 100644 --- a/samples/openid/src/main/webapp/index.jsp +++ b/samples/openid/src/main/webapp/index.jsp @@ -1,11 +1,26 @@ +<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt"%> +<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> + -

Home Page

-

Anyone can view this page.

-

Your principal object is....: <%= request.getUserPrincipal() %>

+

OpenID Sample Home Page

-

Secure page

-

Extremely secure page

+ +

+Welcome back, ! +

+ +

+As a first time user of this site, your OpenID identity has been registered +by the application and will be recognized if you return. +

+
+ +

Technical Information

+

+Your principal object is....: <%= request.getUserPrincipal() %> +

+

Logout - \ No newline at end of file + diff --git a/samples/openid/src/main/webapp/secure/extreme/index.jsp b/samples/openid/src/main/webapp/secure/extreme/index.jsp deleted file mode 100644 index c5ff40bfef..0000000000 --- a/samples/openid/src/main/webapp/secure/extreme/index.jsp +++ /dev/null @@ -1,9 +0,0 @@ - - -

VERY Secure Page

-This is a protected page. You can only see me if you are a supervisor. - -

Home -

Logout - - \ No newline at end of file diff --git a/samples/openid/src/main/webapp/secure/index.jsp b/samples/openid/src/main/webapp/secure/index.jsp deleted file mode 100644 index 97d9b216d4..0000000000 --- a/samples/openid/src/main/webapp/secure/index.jsp +++ /dev/null @@ -1,15 +0,0 @@ - - -

Secure Page

-This is a protected page. You can get to me if you've been remembered, -or if you've authenticated this session.

- -<%if (request.isUserInRole("ROLE_SUPERVISOR")) { %> - You are a supervisor! You can therefore see the extremely secure page.

-<% } %> - - -

Home -

Logout - - \ No newline at end of file diff --git a/samples/tutorial/src/main/webapp/secure/index.jsp b/samples/tutorial/src/main/webapp/secure/index.jsp index 95fca71f15..0b2baeddd5 100644 --- a/samples/tutorial/src/main/webapp/secure/index.jsp +++ b/samples/tutorial/src/main/webapp/secure/index.jsp @@ -30,7 +30,7 @@ or if you've authenticated this session. -

Home -

Logout +

Home

+

Logout

diff --git a/web/src/main/java/org/springframework/security/web/authentication/preauth/AbstractPreAuthenticatedProcessingFilter.java b/web/src/main/java/org/springframework/security/web/authentication/preauth/AbstractPreAuthenticatedProcessingFilter.java index 8ab40a2190..72de83f565 100755 --- a/web/src/main/java/org/springframework/security/web/authentication/preauth/AbstractPreAuthenticatedProcessingFilter.java +++ b/web/src/main/java/org/springframework/security/web/authentication/preauth/AbstractPreAuthenticatedProcessingFilter.java @@ -204,6 +204,13 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi this.authenticationManager = authenticationManager; } + /** + * If set to {@code true}, any {@code AuthenticationException} raised by the {@code AuthenticationManager} will be + * swallowed, and the request will be allowed to proceed, potentially using alternative authentication mechanisms. + * If {@code false} (the default), authentication failure will result in an immediate exception. + * + * @param shouldContinue set to {@code true} to allow the request to proceed after a failed authentication. + */ public void setContinueFilterChainOnUnsuccessfulAuthentication(boolean shouldContinue) { continueFilterChainOnUnsuccessfulAuthentication = shouldContinue; }