Spring Security 3.0 Службы Google для входа в систему с помощью OpenID4Java
Я пытаюсь войти с помощью открытого идентификатора Служб Google с помощью библиотеки OpenID4Java.
Я обнаружил службу пользователя, используя следующий код в классе потребителей:
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);
Затем я получаю параметры из запроса http и в свойстве openid.claimed_id я получаю " http://domain.com/openid?id=....", и если я пытаюсь проверить ответ consumerManager.verify(receivingURL.toString(), openidResp, discovered);
исключение выдается: org.openid4java.discovery.yadis.YadisException: 0x706: GET failed on http://domain.com/openid?id=... : 404:Not Found
,
Чтобы избежать исключения, я попытался изменить список параметров, изменив значение " http://domain.com/openid?id=...." на " 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);
}
Теперь метод consumerManager.verify
больше не генерирует исключение, но его статус меняется на сбойный. В журнале появляются следующие ошибки
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.
Я видел на форуме похожую проблему, но решение было изменить consumerManager.verify
в consumerManager.verifyNonce
, Я не уверен, что использование этого метода не создаст проблему безопасности. Есть ли у вас какие-либо идеи о том, что мне следует изменить, чтобы мой потребитель с открытым идентификатором работал с Google Apps openid?
1 ответ
Службы Google используют несколько иной процесс обнаружения, чем тот, который поддерживается в базовой версии OpenID4Java. На http://code.google.com/p/step2/ есть дополнительная библиотека, с которой вы можете бороться (и обертка более высокого уровня на http://code.google.com/p/openid-filter/.)
Я не знаю никого, кто занимался интеграцией Spring Security с измененными классами Step2, но не должно быть слишком сложно изменить код для соответствующей настройки Step2. Он построен на OpenID4Java, и код для написания проверяющей стороны в основном такой же.