401错误未知授权检索Google日历

时间:2011-05-30 11:23:16

标签: java google-app-engine gwt oauth google-api

当我执行CalendarService.setOAuthCredentials(oauthParameters,new OAuthHmacSha1Signer());我收到OAuthException 401错误未知授权标题。

我正在使用GWT + GAE我不知道为什么我收到这个错误,oauthParameters似乎没问题。

  1. 我让用户登录 loginService.login
  2. 我检查一下 身份验证已经开启 oauthService.checkOauthTokenSecret
  3. 如果没有,我会重定向到Google GCalendar的Aproval页面 许可
  4. 我得到了查询字符串 由Google返回,我获得了Access 令牌和访问令牌秘密和 将其设置为用户实体以供日后使用 在oauthService.upgradeLogin上使用。
  5. 试图让日历开启 oauthService.getPublicCalendars。
  6. 我正在使用mvp4g框架的MVP模式,对不起如果有点混乱0: - )

    知道为什么我收到401错误?我认为是我正在上升的事情。通过客户端,服务器和外部页面......以及缺少的东西:-(但所有参数似乎都已正确填满。

    客户端

    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);
    }
    
    }
    

1 个答案:

答案 0 :(得分:1)

我最近一直在与oAuth合作。在升级到访问令牌时,在 upgradeLogin(...)内部,您无法获取相应的访问令牌密钥。

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对诊断我的问题非常有用。

我希望这有帮助,