Promoting OpenID out of the Sandbox
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.providers.openid;
|
||||
|
||||
import org.springframework.security.AuthenticationException;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates that OpenID authentication was cancelled
|
||||
*
|
||||
* @author Robin Bramley, Opsera Ltd
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationCancelledException extends AuthenticationException {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AuthenticationCancelledException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public AuthenticationCancelledException(String msg, Throwable t) {
|
||||
super(msg, t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.providers.openid;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.security.Authentication;
|
||||
import org.springframework.security.AuthenticationException;
|
||||
import org.springframework.security.AuthenticationServiceException;
|
||||
import org.springframework.security.BadCredentialsException;
|
||||
import org.springframework.security.providers.AuthenticationProvider;
|
||||
import org.springframework.security.providers.AuthoritiesPopulator;
|
||||
import org.springframework.security.userdetails.UserDetails;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* Finalises the OpenID authentication by obtaining local roles
|
||||
*
|
||||
* @author Robin Bramley, Opsera Ltd.
|
||||
*/
|
||||
public class OpenIDAuthenticationProvider implements AuthenticationProvider, InitializingBean {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AuthoritiesPopulator authoritiesPopulator;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(this.authoritiesPopulator, "The authoritiesPopulator must be set");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.security.providers.AuthenticationProvider#authenticate(org.springframework.security.Authentication)
|
||||
*/
|
||||
public Authentication authenticate(Authentication authentication)
|
||||
throws AuthenticationException {
|
||||
|
||||
if (!supports(authentication.getClass())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (authentication instanceof OpenIDAuthenticationToken) {
|
||||
OpenIDAuthenticationToken response = (OpenIDAuthenticationToken) authentication;
|
||||
OpenIDAuthenticationStatus status = response.getStatus();
|
||||
|
||||
// handle the various possibilites
|
||||
if (status == OpenIDAuthenticationStatus.SUCCESS) {
|
||||
//String message = "Log in succeeded: ";// + savedId;
|
||||
|
||||
/* TODO: allow for regex for mapping URL
|
||||
* e.g. http://mydomain.com/username
|
||||
* or http://{username}.mydomain.com
|
||||
*/
|
||||
|
||||
// Lookup user details
|
||||
UserDetails userDetails = this.authoritiesPopulator.getUserDetails(response.getIdentityUrl());
|
||||
|
||||
authentication = new OpenIDAuthenticationToken(userDetails.getAuthorities(), response.getStatus(),
|
||||
response.getIdentityUrl());
|
||||
|
||||
return authentication;
|
||||
} else if (status == OpenIDAuthenticationStatus.CANCELLED) {
|
||||
throw new AuthenticationCancelledException("Log in cancelled");
|
||||
} else if (status == OpenIDAuthenticationStatus.ERROR) {
|
||||
throw new AuthenticationServiceException("Error message from server: " + response.getMessage());
|
||||
} else if (status == OpenIDAuthenticationStatus.FAILURE) {
|
||||
throw new BadCredentialsException("Log in failed - identity could not be verified");
|
||||
} else if (status == OpenIDAuthenticationStatus.SETUP_NEEDED) {
|
||||
throw new AuthenticationServiceException(
|
||||
"The server responded setup was needed, which shouldn't happen");
|
||||
} else {
|
||||
throw new AuthenticationServiceException("Unrecognized return value " + status.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setAuthoritiesPopulator(AuthoritiesPopulator authoritiesPopulator) {
|
||||
this.authoritiesPopulator = authoritiesPopulator;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.security.providers.AuthenticationProvider#supports(java.lang.Class)
|
||||
*/
|
||||
public boolean supports(Class authentication) {
|
||||
return OpenIDAuthenticationToken.class.isAssignableFrom(authentication);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.providers.openid;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* Based on JanRain status codes
|
||||
*
|
||||
* @author JanRain Inc.
|
||||
* @author Robin Bramley, Opsera Ltd
|
||||
*/
|
||||
public class OpenIDAuthenticationStatus implements Serializable {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final long serialVersionUID = -998877665544332211L;
|
||||
private static int nextOrdinal = 0;
|
||||
|
||||
/** This code indicates a successful authentication request */
|
||||
public static final OpenIDAuthenticationStatus SUCCESS = new OpenIDAuthenticationStatus("success");
|
||||
|
||||
/** This code indicates a failed authentication request */
|
||||
public static final OpenIDAuthenticationStatus FAILURE = new OpenIDAuthenticationStatus("failure");
|
||||
|
||||
/** This code indicates the server reported an error */
|
||||
public static final OpenIDAuthenticationStatus ERROR = new OpenIDAuthenticationStatus("error");
|
||||
|
||||
/** This code indicates that the user needs to do additional work to prove their identity */
|
||||
public static final OpenIDAuthenticationStatus SETUP_NEEDED = new OpenIDAuthenticationStatus("setup needed");
|
||||
|
||||
/** This code indicates that the user cancelled their login request */
|
||||
public static final OpenIDAuthenticationStatus CANCELLED = new OpenIDAuthenticationStatus("cancelled");
|
||||
private static final OpenIDAuthenticationStatus[] PRIVATE_VALUES = {SUCCESS, FAILURE, ERROR, SETUP_NEEDED, CANCELLED};
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private String name;
|
||||
private final int ordinal = nextOrdinal++;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
private OpenIDAuthenticationStatus(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
private Object readResolve() throws ObjectStreamException {
|
||||
return PRIVATE_VALUES[ordinal];
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.providers.openid;
|
||||
|
||||
import org.springframework.security.GrantedAuthority;
|
||||
|
||||
import org.springframework.security.providers.AbstractAuthenticationToken;
|
||||
|
||||
|
||||
/**
|
||||
* OpenID Authentication Token
|
||||
*
|
||||
* @author Robin Bramley, Opsera Ltd
|
||||
*/
|
||||
public class OpenIDAuthenticationToken extends AbstractAuthenticationToken {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private OpenIDAuthenticationStatus status;
|
||||
private String identityUrl;
|
||||
private String message;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public OpenIDAuthenticationToken(OpenIDAuthenticationStatus status, String identityUrl, String message) {
|
||||
super(new GrantedAuthority[0]);
|
||||
this.status = status;
|
||||
this.identityUrl = identityUrl;
|
||||
this.message = message;
|
||||
setAuthenticated(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by the OpenIDAuthenticationProvider on successful authentication.
|
||||
* <b>Do not use directly</b>
|
||||
*
|
||||
* @param authorities
|
||||
* @param status
|
||||
* @param identityUrl
|
||||
*/
|
||||
public OpenIDAuthenticationToken(GrantedAuthority[] authorities, OpenIDAuthenticationStatus status,
|
||||
String identityUrl) {
|
||||
super(authorities);
|
||||
this.status = status;
|
||||
this.identityUrl = identityUrl;
|
||||
|
||||
setAuthenticated(true);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.security.Authentication#getCredentials()
|
||||
*/
|
||||
public Object getCredentials() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getIdentityUrl() {
|
||||
return identityUrl;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.security.Authentication#getPrincipal()
|
||||
*/
|
||||
public Object getPrincipal() {
|
||||
return identityUrl;
|
||||
}
|
||||
|
||||
public OpenIDAuthenticationStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<body>
|
||||
An authentication provider that can process <a href="http://openid.net">OpenID</a>
|
||||
Authentication Tokens as created by implementations of the OpenIDConsumer interface.
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,26 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.ui.openid;
|
||||
|
||||
/**
|
||||
* Constants required by OpenID classes
|
||||
*
|
||||
* @author Robin Bramley, Opsera Ltd
|
||||
*/
|
||||
public class OpenIDConstants {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
public static final String OPENID_SESSION_MAP_KEY = "openid.session";
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.ui.openid;
|
||||
|
||||
import org.springframework.security.providers.openid.OpenIDAuthenticationToken;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* An interface for OpenID library implementations
|
||||
*
|
||||
* @author Ray Krueger
|
||||
* @author Robin Bramley, Opsera Ltd
|
||||
*/
|
||||
public interface OpenIDConsumer {
|
||||
|
||||
public String beginConsumption(HttpServletRequest req, String identityUrl, String returnToUrl)
|
||||
throws OpenIDConsumerException;
|
||||
|
||||
public OpenIDAuthenticationToken endConsumption(HttpServletRequest req)
|
||||
throws OpenIDConsumerException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.ui.openid;
|
||||
|
||||
/**
|
||||
* Thrown by an OpenIDConsumer if it cannot process a request
|
||||
*
|
||||
* @author Robin Bramley, Opsera Ltd
|
||||
*/
|
||||
public class OpenIDConsumerException extends Exception {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public OpenIDConsumerException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public OpenIDConsumerException(String message, Throwable t) {
|
||||
super(message, t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.ui.openid;
|
||||
|
||||
import org.springframework.security.Authentication;
|
||||
import org.springframework.security.AuthenticationException;
|
||||
import org.springframework.security.AuthenticationServiceException;
|
||||
|
||||
import org.springframework.security.providers.openid.OpenIDAuthenticationToken;
|
||||
|
||||
import org.springframework.security.ui.AbstractProcessingFilter;
|
||||
import org.springframework.security.ui.webapp.AuthenticationProcessingFilter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Process the response from the OpenID server to the returnTo URL.
|
||||
*
|
||||
* @author Robin Bramley, Opsera Ltd
|
||||
* @version $Id$
|
||||
*/
|
||||
public class OpenIDResponseProcessingFilter extends AbstractProcessingFilter {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private OpenIDConsumer consumer;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.security.ui.AbstractProcessingFilter#attemptAuthentication(javax.servlet.http.HttpServletRequest)
|
||||
* @Override
|
||||
*/
|
||||
public Authentication attemptAuthentication(HttpServletRequest req)
|
||||
throws AuthenticationException {
|
||||
OpenIDAuthenticationToken token;
|
||||
|
||||
try {
|
||||
token = consumer.endConsumption(req);
|
||||
} catch (OpenIDConsumerException oice) {
|
||||
throw new AuthenticationServiceException("Consumer error", oice);
|
||||
}
|
||||
|
||||
// delegate to the auth provider
|
||||
Authentication authentication = this.getAuthenticationManager().authenticate(token);
|
||||
|
||||
if (authentication.isAuthenticated()) {
|
||||
req.getSession()
|
||||
.setAttribute(AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY, token.getIdentityUrl());
|
||||
}
|
||||
|
||||
return authentication;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.security.ui.AbstractProcessingFilter#getDefaultFilterProcessesUrl()
|
||||
* @Override
|
||||
*/
|
||||
public String getDefaultFilterProcessesUrl() {
|
||||
return "/j_spring_openid_security_check";
|
||||
}
|
||||
|
||||
// dependency injection
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @param consumer The OpenIDConsumer to set.
|
||||
*/
|
||||
public void setConsumer(OpenIDConsumer consumer) {
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.ui.openid;
|
||||
|
||||
import org.springframework.security.Authentication;
|
||||
import org.springframework.security.AuthenticationException;
|
||||
import org.springframework.security.AuthenticationServiceException;
|
||||
import org.springframework.security.context.SecurityContextHolder;
|
||||
import org.springframework.security.providers.openid.OpenIDAuthenticationToken;
|
||||
import org.springframework.security.ui.AbstractProcessingFilter;
|
||||
import org.springframework.security.ui.webapp.AuthenticationProcessingFilter;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @author $author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class OpenIdAuthenticationProcessingFilter extends AbstractProcessingFilter {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log log = LogFactory.getLog(OpenIdAuthenticationProcessingFilter.class);
|
||||
public static final String DEFAULT_CLAIMED_IDENTITY_FIELD = "j_username";
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private OpenIDConsumer consumer;
|
||||
private String claimedIdentityFieldName = DEFAULT_CLAIMED_IDENTITY_FIELD;
|
||||
private String errorPage = "index.jsp";
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public Authentication attemptAuthentication(HttpServletRequest req)
|
||||
throws AuthenticationException {
|
||||
OpenIDAuthenticationToken token;
|
||||
|
||||
String identity = req.getParameter("openid.identity");
|
||||
|
||||
if (!StringUtils.hasText(identity)) {
|
||||
throw new OpenIdAuthenticationRequiredException("External Authentication Required", obtainUsername(req));
|
||||
}
|
||||
|
||||
try {
|
||||
token = consumer.endConsumption(req);
|
||||
} catch (OpenIDConsumerException oice) {
|
||||
throw new AuthenticationServiceException("Consumer error", oice);
|
||||
}
|
||||
|
||||
// delegate to the auth provider
|
||||
Authentication authentication = this.getAuthenticationManager().authenticate(token);
|
||||
|
||||
if (authentication.isAuthenticated()) {
|
||||
req.getSession()
|
||||
.setAttribute(AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY, token.getIdentityUrl());
|
||||
}
|
||||
|
||||
return authentication;
|
||||
}
|
||||
|
||||
protected String determineFailureUrl(HttpServletRequest request, AuthenticationException failed) {
|
||||
if (failed instanceof OpenIdAuthenticationRequiredException) {
|
||||
OpenIdAuthenticationRequiredException openIdRequiredException = (OpenIdAuthenticationRequiredException) failed;
|
||||
String claimedIdentity = openIdRequiredException.getClaimedIdentity();
|
||||
|
||||
if (StringUtils.hasText(claimedIdentity)) {
|
||||
try {
|
||||
String returnToUrl = buildReturnToUrl(request);
|
||||
return consumer.beginConsumption(request, claimedIdentity, returnToUrl);
|
||||
} catch (OpenIDConsumerException e) {
|
||||
log.error("Unable to consume claimedIdentity [" + claimedIdentity + "]", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.determineFailureUrl(request, failed);
|
||||
}
|
||||
|
||||
protected String buildReturnToUrl(HttpServletRequest request) {
|
||||
return request.getRequestURL().toString();
|
||||
}
|
||||
|
||||
public String getClaimedIdentityFieldName() {
|
||||
return claimedIdentityFieldName;
|
||||
}
|
||||
|
||||
public OpenIDConsumer getConsumer() {
|
||||
return consumer;
|
||||
}
|
||||
|
||||
public String getDefaultFilterProcessesUrl() {
|
||||
return "/j_spring_openid_security_check";
|
||||
}
|
||||
|
||||
public String getErrorPage() {
|
||||
return errorPage;
|
||||
}
|
||||
|
||||
protected boolean isAuthenticated(HttpServletRequest request) {
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
||||
return (auth != null) && auth.isAuthenticated();
|
||||
}
|
||||
|
||||
/**
|
||||
* The OpenIdAuthenticationProcessingFilter will ignore the request coming in if this method returns false.
|
||||
* The default functionality checks if the request scheme starts with http. <br/
|
||||
* > This method should be overridden in subclasses that wish to consider a different strategy
|
||||
*
|
||||
* @param request HttpServletRequest we're processing
|
||||
* @return true if this request is determined to be an OpenID request.
|
||||
*/
|
||||
protected boolean isOpenIdRequest(HttpServletRequest request) {
|
||||
String username = obtainUsername(request);
|
||||
return (StringUtils.hasText(username)) && username.toLowerCase().startsWith("http");
|
||||
}
|
||||
|
||||
protected String obtainUsername(HttpServletRequest req) {
|
||||
return req.getParameter(claimedIdentityFieldName);
|
||||
}
|
||||
|
||||
protected void onUnsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException failed) throws IOException {
|
||||
if (failed instanceof OpenIdAuthenticationRequiredException) {
|
||||
OpenIdAuthenticationRequiredException openIdAuthenticationRequiredException = (OpenIdAuthenticationRequiredException) failed;
|
||||
request.setAttribute(OpenIdAuthenticationRequiredException.class.getName(),
|
||||
openIdAuthenticationRequiredException.getClaimedIdentity());
|
||||
}
|
||||
}
|
||||
|
||||
public void setClaimedIdentityFieldName(String claimedIdentityFieldName) {
|
||||
this.claimedIdentityFieldName = claimedIdentityFieldName;
|
||||
}
|
||||
|
||||
public void setConsumer(OpenIDConsumer consumer) {
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
public void setErrorPage(String errorPage) {
|
||||
this.errorPage = errorPage;
|
||||
}
|
||||
|
||||
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException failed) throws IOException {
|
||||
SecurityContextHolder.getContext().setAuthentication(null);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Updated SecurityContextHolder to contain null Authentication");
|
||||
}
|
||||
|
||||
String failureUrl = determineFailureUrl(request, failed);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Authentication request failed: " + failed.toString());
|
||||
}
|
||||
|
||||
try {
|
||||
request.getSession().setAttribute(SPRING_SECURITY_LAST_EXCEPTION_KEY, failed);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
super.getRememberMeServices().loginFail(request, response);
|
||||
|
||||
sendRedirect(request, response, failureUrl);
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.ui.openid;
|
||||
|
||||
import org.springframework.security.AuthenticationException;
|
||||
|
||||
/**
|
||||
* @author Ray Krueger
|
||||
*/
|
||||
public class OpenIdAuthenticationRequiredException extends AuthenticationException {
|
||||
|
||||
private final String claimedIdentity;
|
||||
|
||||
public OpenIdAuthenticationRequiredException(String msg, String claimedIdentity) {
|
||||
super(msg);
|
||||
this.claimedIdentity = claimedIdentity;
|
||||
}
|
||||
|
||||
public String getClaimedIdentity() {
|
||||
return claimedIdentity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.ui.openid.consumers;
|
||||
|
||||
import org.springframework.security.providers.openid.OpenIDAuthenticationStatus;
|
||||
import org.springframework.security.providers.openid.OpenIDAuthenticationToken;
|
||||
|
||||
import org.springframework.security.ui.openid.OpenIDConsumer;
|
||||
import org.springframework.security.ui.openid.OpenIDConsumerException;
|
||||
|
||||
import org.openid4java.association.AssociationException;
|
||||
|
||||
import org.openid4java.consumer.ConsumerException;
|
||||
import org.openid4java.consumer.ConsumerManager;
|
||||
import org.openid4java.consumer.VerificationResult;
|
||||
|
||||
import org.openid4java.discovery.DiscoveryException;
|
||||
import org.openid4java.discovery.DiscoveryInformation;
|
||||
import org.openid4java.discovery.Identifier;
|
||||
|
||||
import org.openid4java.message.AuthRequest;
|
||||
import org.openid4java.message.MessageException;
|
||||
import org.openid4java.message.ParameterList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @author Ray Krueger
|
||||
*/
|
||||
public class OpenId4JavaConsumer implements OpenIDConsumer {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final ConsumerManager consumerManager;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public OpenId4JavaConsumer(ConsumerManager consumerManager) {
|
||||
this.consumerManager = consumerManager;
|
||||
}
|
||||
|
||||
public OpenId4JavaConsumer() throws ConsumerException {
|
||||
this(new ConsumerManager());
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public String beginConsumption(HttpServletRequest req, String identityUrl, String returnToUrl)
|
||||
throws OpenIDConsumerException {
|
||||
List discoveries;
|
||||
|
||||
try {
|
||||
discoveries = consumerManager.discover(identityUrl);
|
||||
} catch (DiscoveryException e) {
|
||||
throw new OpenIDConsumerException("Error during discovery", e);
|
||||
}
|
||||
|
||||
DiscoveryInformation information = consumerManager.associate(discoveries);
|
||||
HttpSession session = req.getSession(true);
|
||||
session.setAttribute(DiscoveryInformation.class.getName(), information);
|
||||
|
||||
AuthRequest authReq;
|
||||
|
||||
try {
|
||||
authReq = consumerManager.authenticate(information, returnToUrl);
|
||||
} catch (MessageException e) {
|
||||
throw new OpenIDConsumerException("Error processing ConumerManager authentication", e);
|
||||
} catch (ConsumerException e) {
|
||||
throw new OpenIDConsumerException("Error processing ConumerManager authentication", e);
|
||||
}
|
||||
|
||||
return authReq.getDestinationUrl(true);
|
||||
}
|
||||
|
||||
public OpenIDAuthenticationToken endConsumption(HttpServletRequest request)
|
||||
throws OpenIDConsumerException {
|
||||
// extract the parameters from the authentication response
|
||||
// (which comes in as a HTTP request from the OpenID provider)
|
||||
ParameterList openidResp = new ParameterList(request.getParameterMap());
|
||||
|
||||
// retrieve the previously stored discovery information
|
||||
DiscoveryInformation discovered = (DiscoveryInformation) request.getSession()
|
||||
.getAttribute(DiscoveryInformation.class.getName());
|
||||
|
||||
// extract the receiving URL from the HTTP request
|
||||
StringBuffer receivingURL = request.getRequestURL();
|
||||
String queryString = request.getQueryString();
|
||||
|
||||
if ((queryString != null) && (queryString.length() > 0)) {
|
||||
receivingURL.append("?").append(request.getQueryString());
|
||||
}
|
||||
|
||||
// verify the response
|
||||
VerificationResult verification;
|
||||
|
||||
try {
|
||||
verification = consumerManager.verify(receivingURL.toString(), openidResp, discovered);
|
||||
} catch (MessageException e) {
|
||||
throw new OpenIDConsumerException("Error verifying openid response", e);
|
||||
} catch (DiscoveryException e) {
|
||||
throw new OpenIDConsumerException("Error verifying openid response", e);
|
||||
} catch (AssociationException e) {
|
||||
throw new OpenIDConsumerException("Error verifying openid response", e);
|
||||
}
|
||||
|
||||
// examine the verification result and extract the verified identifier
|
||||
Identifier verified = verification.getVerifiedId();
|
||||
|
||||
if (verified != null) {
|
||||
return new OpenIDAuthenticationToken(OpenIDAuthenticationStatus.SUCCESS, verified.getIdentifier(),
|
||||
"some message");
|
||||
} else {
|
||||
return new OpenIDAuthenticationToken(OpenIDAuthenticationStatus.FAILURE,
|
||||
discovered.getClaimedIdentifier().getIdentifier(),
|
||||
"Verification status message: [" + verification.getStatusMsg() + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Implementations of the OpenIDConsumer interface using 3rd party libraries.
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Authenticates standard web browser users via <a href="http://openid.net">OpenID</a>.
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user