2010-11-19 31 views
7

我嘗試使用Google Apps OpenID與OpenID4Java庫登錄。Spring Security 3.0 Google Apps使用OpenID4Java打開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。我不確定使用這種方法是否會造成安全問題。您知道我應該更改哪些內容以使我的開放標識消費者能夠使用Google Apps openid?

回答

0

Google Apps使用的發現過程與基礎版本的OpenID4Java支持的發現過程略有不同。有一個附加庫http://code.google.com/p/step2/,你可能會對抗有用的(和一個更高層次包裝在http://code.google.com/p/openid-filter/。)

我不知道任何人已經完成與修改的Step2類的Spring Security集成,但它不應該'要修改代碼來適當地設置Step2太難了。它基於OpenID4Java構建,編寫依賴方的代碼基本相同。