Spring Security 3.0 de Google Apps signo Identificación abierta en el uso de OpenID4Java
-
26-09-2019 - |
Pregunta
Me intenta iniciar sesión en el uso de Google Apps Identificación abierto con biblioteca OpenID4Java.
Descubre el servicio del usuario utilizando el código siguiente en la clase de los consumidores:
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, realm);
// check for OpenID Simple Registration request needed
if (attributesByProvider != null || defaultAttributes != null)
{
//I set the attributes needed for getting the email of the user
}
}
catch (Exception e)
{
throw new OpenIDConsumerException("Error processing ConumerManager authentication", e);
}
return authReq.getDestinationUrl(true);
A continuación me sale de los parámetros de la petición HTTP y en la propiedad openid.claimed_id recibo " http: // domain.com/openid?id= ...." y si lo intento de verificar la consumerManager.verify(receivingURL.toString(), openidResp, discovered);
respuesta se produce una excepción:. org.openid4java.discovery.yadis.YadisException: 0x706: GET failed on http://domain.com/openid?id=... : 404:Not Found
Para evitar la excepción traté de modificar la lista de parámetros cambiando el valor " http://domain.com/ ? id = openid .... "a" https: / /www.google.com/a/domain.com/openid?id= .... "
// extract the receiving URL from the HTTP request
StringBuffer receivingURL = request.getRequestURL();
String queryString = request.getQueryString();
// extract the parameters from the authentication response
// (which comes in as a HTTP request from the OpenID provider)
ParameterList openidResp = new ParameterList(request.getParameterMap());
Parameter endPoint = openidResp.getParameter("openid.op_endpoint");
if (endPoint != null && endPoint.getValue().startsWith("https://www.google.com/a/"))
{
Parameter parameter = openidResp.getParameter("openid.claimed_id");
if (parameter != null)
{
String value = "https://www.google.com/a/" + parameter.getValue().replaceAll("http://", "");
openidResp.set(new Parameter("openid.claimed_id", value));
queryString = queryString.replaceAll("openid.claimed_id=http%3A%2F%2F", "openid.claimed_id=https%3A%2F%2Fwww.google.com%2Fa%2F");
}
parameter = openidResp.getParameter("openid.identity");
if (parameter != null)
{
String value = "https://www.google.com/a/" + parameter.getValue().replaceAll("http://", "");
openidResp.set(new Parameter("openid.identity", value));
queryString = queryString.replaceAll("openid.claimed_id=http%3A%2F%2F", "openid.claimed_id=https%3A%2F%2Fwww.google.com%2Fa%2F");
}
}
if ((queryString != null) && (queryString.length() > 0))
{
receivingURL.append("?").append(queryString);
}
// retrieve the previously stored discovery information
DiscoveryInformation discovered = (DiscoveryInformation) request.getSession().getAttribute(DiscoveryInformation.class.getName());
// verify the response
VerificationResult verification;
Map userDetails = new HashMap();
try
{
verification = consumerManager.verify(receivingURL.toString(), openidResp, discovered);
// check for OpenID Simple Registration request needed
if (attributesByProvider != null || defaultAttributes != null)
{
//Here I get the value of requested attributes
}
}
catch (Exception e)
{
throw new OpenIDConsumerException("Error verifying openid response", e);
}
// examine the verification result and extract the verified identifier
Identifier verified = null;
if (verification != null)
{
verified = verification.getVerifiedId();
}
OpenIDAuthenticationToken returnToken;
List attributes = null;
if (verified != null)
returnToken = new OpenIDAuthenticationToken(OpenIDAuthenticationStatus.SUCCESS, verified.getIdentifier(), "some message", attributes);
else
{
Identifier id = discovered.getClaimedIdentifier();
return new OpenIDAuthenticationToken(OpenIDAuthenticationStatus.FAILURE, id == null ? "Unknown" : id.getIdentifier(), "Verification status message: [" + verification.getStatusMsg() + "]", attributes);
}
Ahora el consumerManager.verify
método es no tirar más excepción, pero su estado se cambia a fallado. En el registro de los siguientes errores aparecen
09:46:45,424 ERROR ConsumerManager,http-80-1:1759 - No service element found to match the ClaimedID / OP-endpoint in the assertion.
09:46:45,428 ERROR ConsumerManager,http-80-1:1183 - Discovered information verification failed.
vi en un foro de un problema similar, pero la solución era cambiar consumerManager.verify
a consumerManager.verifyNonce
. No estoy seguro de si se utiliza este método no va a crear un problema de seguridad. ¿Tiene alguna idea de lo que debería cambiar para que mi identificación abierta consumidor para el trabajo con Google Apps OpenID?
Solución
Google Apps utiliza un proceso de descubrimiento ligeramente diferente de lo que se admite en la versión de la base de OpenID4Java. Hay un complemento de la biblioteca en http://code.google.com/p/step2/ que es posible luchar útil (y un envoltorio de nivel superior en http://code.google.com / p / openid-filtro / .)
No estoy al tanto de cualquier persona que ha realizado la integración de Seguridad de primavera con las clases Step2 modificados, pero no debería ser demasiado difícil de modificar el código para configurar apropiadamente Paso 2. Está construida sobre OpenID4Java y el código para escribir una parte que confía es en su mayoría la misma.