7

我尝试使用带有 OpenID4Java 库的 Google Apps 开放 ID 登录。

我在消费者类中使用以下代码发现用户的服务:


        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.verifyconsumerManager.verifyNonce. 我不确定使用这种方法是否会产生安全问题。你知道我应该改变什么来让我的 open id 消费者与 Google Apps openid 一起工作吗?

4

1 回答 1

0

Google Apps 使用的发现过程与 OpenID4Java 基本版本所支持的发现过程略有不同。在http://code.google.com/p/step2/有一个附加库,您可能会觉得它很有用(在http://code.google.com/p/openid-filter/有一个更高级别的包装器。 )

我不知道有谁用修改后的 Step2 类完成了 Spring Security 集成,但修改代码以适当地设置 Step2 应该不会太难。它建立在 OpenID4Java 之上,编写依赖方的代码基本相同。

于 2011-12-09T18:42:09.400 回答