2011-05-30 16 views
3

當我執行CalendarService.setOAuthCredentials(oauthParameters,new OAuthHmacSha1Signer());我得到一個OAuthException 401錯誤未知授權標頭。401錯誤未知授權檢索Google日曆

我正在使用GWT + GAE我不知道爲什麼我收到此錯誤,oauthParameters似乎沒問題。

  1. 我得到用戶登錄上 loginService.login
  2. 我檢查我是否有 認證已經在 oauthService.checkOauthTokenSecret
  3. 如果沒有,我會爲做一個重定向到谷歌 Aproval頁GCalendar 許可
  4. 我得到的查詢字符串由谷歌返回 和我得到Access 令牌和訪問令牌密鑰和 將其設置爲用戶耳鼻喉科稍後在oauthService.upgradeLogin上使用 。
  5. 並試圖獲取日曆 oauthService.getPublicCalendars。

我使用的是mvp4g框架MVP模式,對不起,如果有點混亂0 :-)

任何想法,爲什麼我收到401錯誤?我認爲這是一些關於我要去了&向下通過客戶端與服務器和外部的網頁...以及缺少的東西:-(但所有參數似乎正確fullfilled。

客戶端

public void onStart(){ 
    GWT.log("onStart"); 
    loginService.login(GWT.getHostPageBaseURL(), new AsyncCallback<LoginInfo>() { 
     @Override 
     public void onSuccess(LoginInfo result) { 
      Common.loginInfo = result; 
      if(Common.loginInfo.isLoggedIn()) { 
       oauthService.checkOauthTokenSecret(new AsyncCallback<String>() { 
        @Override 
        public void onSuccess(String result) { 
         if (result == null){ 
          eventBus.OauthLogin(); 
         }else{ 
          oauthService.upgradeLogin(Window.Location.getQueryString(),Common.loginInfo, new AsyncCallback<LoginInfo>() { 
           @Override 
           public void onSuccess(LoginInfo result) { 
            Common.loginInfo = result; 
            getCitas(); 
           } 
           @Override public void onFailure(Throwable caught) { 
            Common.handleError(caught);       
           } 
          }); 
         } 
        } 
        @Override public void onFailure(Throwable caught) { 
         Common.handleError(caught);       
        } 
       }); 
      }else{ 
       eventBus.LoadLogin(); 
      } 
     } 
     @Override public void onFailure(Throwable caught) { 
      Common.handleError(caught); 
     } 
    }); 
} 

服務器端

import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

import javax.servlet.ServletContext; 

import com.google.gdata.client.authn.oauth.GoogleOAuthHelper; 
import com.google.gdata.client.authn.oauth.GoogleOAuthParameters; 
import com.google.gdata.client.authn.oauth.OAuthException; 
import com.google.gdata.client.authn.oauth.OAuthHmacSha1Signer; 
import com.google.gdata.client.authn.oauth.OAuthParameters; 
import com.google.gdata.client.calendar.CalendarService; 
import com.google.gdata.data.calendar.CalendarEntry; 
import com.google.gdata.data.calendar.CalendarFeed; 
import com.google.gdata.util.ServiceException; 
import com.google.gwt.user.server.rpc.RemoteServiceServlet; 
import com.rdt.citas.client.OAuthoritzationService; 
import com.rdt.citas.client.shared.LoginInfo; 

public class OAuthoritzationServiceImpl extends RemoteServiceServlet 
implements OAuthoritzationService { 

/** 
* 
*/ 
private static final long serialVersionUID = 1L; 

private static final Logger log = Logger.getLogger(OAuthoritzationServiceImpl.class.getName()); 

private static String KEY_PARAM = "oauth_consumer_key"; 
private static String SECRET_PARAM = "oauth_consumer_secret"; 
private static String SCOPE_PARAM = "scope_calendars"; 
private static String CALLBACK_PARAM = "oauth_callback"; 


public String checkOauthTokenSecret(){ 

    ServletContext context = this.getServletContext(); 
    getOauthParams(context); 

    return (String) this.getThreadLocalRequest().getSession().getAttribute("oauthTokenSecret");; 
} 

public String getApprovalOAuthPageURL() throws IOException{ 

    ServletContext context = this.getServletContext(); 
    getOauthParams(context); 

    GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters(); 

    oauthParameters.setOAuthConsumerKey(getFromSession(KEY_PARAM)); 
    oauthParameters.setOAuthConsumerSecret(getFromSession(SECRET_PARAM)); 
    oauthParameters.setScope(getFromSession(SCOPE_PARAM)); 
    oauthParameters.setOAuthCallback(getFromSession(CALLBACK_PARAM)); 
    GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(new OAuthHmacSha1Signer()); 

    try {      
     oauthHelper.getUnauthorizedRequestToken(oauthParameters); 

     String approvalPageUrl = oauthHelper.createUserAuthorizationUrl(oauthParameters); 
     String oauthTokenSecret = oauthParameters.getOAuthTokenSecret(); 

     this.getThreadLocalRequest().getSession().setAttribute("oauthTokenSecret", oauthTokenSecret); 

     return approvalPageUrl; 

    } catch (OAuthException e) { 
     log.log(Level.WARNING,e.toString()); 
     return ""; 
    } finally{ 
    } 

} 

public LoginInfo upgradeLogin(String queryString, LoginInfo login){ 
    // receiving '?key1=value1&key2=value2 
    queryString = queryString.substring(1, queryString.length()); 
    String k = getFromSession(KEY_PARAM); 
    String s = getFromSession(SECRET_PARAM); 

    GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters(); 
    oauthParameters.setOAuthConsumerKey(k); 
    oauthParameters.setOAuthConsumerSecret(s); 

    String oauthTS = (String) this.getThreadLocalRequest().getSession().getAttribute("oauthTokenSecret");//oauthParameters.getOAuthTokenSecret(); 
    oauthParameters.setOAuthTokenSecret(oauthTS); 

    GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(new OAuthHmacSha1Signer()); 
    oauthHelper.getOAuthParametersFromCallback(queryString,oauthParameters); 

    login.setQueryStringTokens(queryString); 
    login.setAccessTokenSecret(oauthTS); 

    try { 
     String accesToken = oauthHelper.getAccessToken(oauthParameters); 
     login.setTokenSecret(accesToken); 
    } catch (OAuthException e) { 
     log.log(Level.WARNING,e.toString()); 
    } 
    return login; 
} 

public ArrayList<String> getPublicCalendars(String accessToken, String accessTokenSecret){ 
    ArrayList<String> result = new ArrayList<String>(); 
    CalendarFeed calendarResultFeed = null; 

    GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters(); 
    oauthParameters.setOAuthConsumerKey(getFromSession(KEY_PARAM)); 
    oauthParameters.setOAuthConsumerSecret(getFromSession(SECRET_PARAM)); 
    oauthParameters.setOAuthToken(accessToken); 
    oauthParameters.setOAuthTokenSecret(accessTokenSecret);    
    oauthParameters.setOAuthType(OAuthParameters.OAuthType.THREE_LEGGED_OAUTH); 
    oauthParameters.setScope(getFromSession(SCOPE_PARAM)); 

    CalendarService myService = new CalendarService("exampleCo-exampleApp-1");     

    try { 
     myService.setOAuthCredentials(oauthParameters, new OAuthHmacSha1Signer()); 
     URL calendarFeedUrl = new URL("https://www.google.com/calendar/feeds/default/owncalendars/full"); 
     calendarResultFeed = myService.getFeed(calendarFeedUrl, CalendarFeed.class); 
    } catch (OAuthException e) { 
     log.info("OAuthException"); 
     log.log(Level.WARNING,e.toString()); 
     e.printStackTrace(); 
    } catch (MalformedURLException e) { 
     log.info("MalformedURLException"); 
     log.log(Level.WARNING,e.toString()); 
     e.printStackTrace(); 
    } catch (IOException e) { 
     log.info("IOException"); 
     log.log(Level.WARNING,e.toString()); 
     e.printStackTrace(); 
    } catch (ServiceException e) { 
     log.info("ServiceException"); 
     log.log(Level.WARNING,e.toString()); 
     e.printStackTrace(); 
    } 

    if (calendarResultFeed != null && calendarResultFeed.getEntries() != null) { 
     for (int i = 0; i < calendarResultFeed.getEntries().size(); i++) { 
      CalendarEntry entry = calendarResultFeed.getEntries().get(i); 
      result.add(entry.getTitle().getPlainText());    
     } 
    } 
    return result; 
} 


private void getOauthParams(ServletContext context) { 
    this.getThreadLocalRequest().getSession() 
     .setAttribute(KEY_PARAM, context.getInitParameter(KEY_PARAM)); 
    this.getThreadLocalRequest().getSession() 
     .setAttribute(SECRET_PARAM, context.getInitParameter(SECRET_PARAM)); 
    this.getThreadLocalRequest().getSession() 
     .setAttribute(SCOPE_PARAM, context.getInitParameter(SCOPE_PARAM)); 
    this.getThreadLocalRequest().getSession() 
     .setAttribute(CALLBACK_PARAM, context.getInitParameter(CALLBACK_PARAM)); 
} 

private String getFromSession(String param){ 
    return (String) this.getThreadLocalRequest().getSession().getAttribute(param); 
} 

} 
+0

順便說一句,我不知道這是你的問題或沒有,但我從來沒有見過的範圍樣子,對於谷歌日曆。我一直認爲Google日曆OAuth範圍看起來像http://www.google.com/calendar/feeds/user%40domain/private/full請參閱Google文檔:http://code.google.com/apis/accounts/ docs/OAuth.html#prepScope – Owen 2011-07-07 16:25:17

回答

1

我最近一直在與OAuth的,裏面upgradeLogin(...)當你升級到一個訪問令牌,你不取相應的訪問令牌SECR等。

getAccessToken()請求之後的訪問令牌密鑰與請求之前的訪問令牌密鑰不同。您當前正在設置訪問令牌密碼(通過login.setAccessTokenSecret(oauthTS)),它是您正在使用的預先更新的訪問令牌密碼值。您需要將其設置爲更新請求後返回的訪問令牌祕密值:

String accesToken = oauthHelper.getAccessToken(oauthParameters); 
String accesTokenSecret = oauthParameters.getOAuthTokenSecret();     
login.setTokenSecret(accesToken); 
login.setAccessTokenSecret(accesTokenSecret); 

您也可能希望在一些地方保存此更新的令牌/隱匿對。這是訪問令牌密鑰將此值應該然後被內部getPublicCalendars在路上使用(...):

oauthParameters.setOAuthTokenSecret(accessTokenSecret); 

帖子中的更新訪問令牌/隱匿對長壽命,因此可以重新使用(無需再次更新),直到它被撤銷。

順便說一下,我發現oAuth Playground Tool用於診斷我的問題。

我希望這有助於

+0

是的,由於我在GWT,GAE甚至是java的經驗不足,我做了很多解決方法:PI解決了問題,現在我對OAuth的工作原理有了更好的理解。非常感謝! – rubdottocom 2011-11-22 08:35:27