【问题标题】:Google consent screen not shown as expectedGoogle 同意屏幕未按预期显示
【发布时间】:2013-12-25 16:15:00
【问题描述】:

我在 cloud.google.com 上注册了一个网络应用程序。 “OAuth 2.0 客户端 ID”如下所示:

我正在使用 grails 和 grails oauth 插件。在 Config.groovy 我添加了以下 sn-p:

google {
    api = GoogleApi
    key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com'
    secret = 'yyyyyyyyyyyyyyyyyyyyyyyy'

    scope = 'https://www.googleapis.com/auth/userinfo.profile'

    callback = "http://localhost:8080/grailsOauthPluginDemo/oauth/google/callback"
    successUri = "http://localhost:8080/grailsOauthPluginDemo/oauthCallBack/google"
    failureUri = "http://localhost:8080/grailsOauthPluginDemo/oauthCallBack/failure"
}

并将以下内容放入 index.gsp

<oauth:connect provider="google">Google</oauth:connect><br/>

我使用我的个人 Google 帐户登录。我正在使用https://github.com/manishkbharti/grailsOauthPluginDemo,当单击 Google 链接时,我会进入如下所示的同意页面:

我希望得到一个类似于以下内容的页面,其中包含我的应用程序名称。我知道我必须添加一张图片,但应该会弹出应用程序名称。

【问题讨论】:

    标签: grails oauth screen google-oauth confirmation


    【解决方案1】:

    我相信 grailsOauthPluginDemo 正在使用Google's OAuth1.0a API,它目前对同意页面使用不同的模板。

    希望有帮助!

    【讨论】:

    • 感谢您的回复。但是,查看 BuildConfig.groovy 会给出 compile ":oauth:2.1.0" 所以不,这似乎不是问题。还是我理解错了?
    • 你能捕获 OAuth http 请求吗?查看路径(.../auth/oauth1? vs .../auth/oauth2?)将有助于确认 grailsOauthPluginDemo 正在触发 Google OAuth1 请求。
    • 我正在使用这个插件,grails.org/plugin/oauth 这可能基于 Oauth1。你说得对。应该使用grails.org/plugins/tag/oauth2 谢谢米格尔!
    • 没有spring security的oath 2.0有链接吗?
    【解决方案2】:

    感谢@svaret 试用该应用程序。

    我已经更新了application,现在它使用oauth2 代替Google authentication

    试一试。


    解决方案:-

    在 src/java 中创建一个文件,例如 Google2Api.java 并粘贴以下代码(Ref# https://gist.github.com/yincrash/2465453)

    package yourPackate;
    
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import org.scribe.exceptions.OAuthException;
    import org.scribe.extractors.AccessTokenExtractor;
    import org.scribe.model.OAuthConfig;
    import org.scribe.model.OAuthConstants;
    import org.scribe.model.OAuthRequest;
    import org.scribe.model.Response;
    import org.scribe.model.Token;
    import org.scribe.model.Verb;
    import org.scribe.model.Verifier;
    import org.scribe.oauth.OAuth20ServiceImpl;
    import org.scribe.oauth.OAuthService;
    import org.scribe.utils.OAuthEncoder;
    import org.scribe.utils.Preconditions;
    
    /**
     * Google OAuth2.0 
     * Released under the same license as scribe (MIT License)
     * @author yincrash
     * 
     */
    public class Google2Api extends DefaultApi20 {
    
    private static final String AUTHORIZE_URL = "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=%s&redirect_uri=%s";
    private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s";
    
    @Override
    public String getAccessTokenEndpoint() {
        return "https://accounts.google.com/o/oauth2/token";
    }
    
    @Override
    public AccessTokenExtractor getAccessTokenExtractor() {
        return new AccessTokenExtractor() {
    
            @Override
            public Token extract(String response) {
                Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string");
    
                Matcher matcher = Pattern.compile("\"access_token\" : \"([^&\"]+)\"").matcher(response);
                if (matcher.find())
                {
                  String token = OAuthEncoder.decode(matcher.group(1));
                  return new Token(token, "", response);
                } 
                else
                {
                  throw new OAuthException("Response body is incorrect. Can't extract a token from this: '" + response + "'", null);
                }
            }
        };
    }
    
    @Override
    public String getAuthorizationUrl(OAuthConfig config) {
        // Append scope if present
        if (config.hasScope()) {
            return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(),
                    OAuthEncoder.encode(config.getCallback()),
                    OAuthEncoder.encode(config.getScope()));
        } else {
            return String.format(AUTHORIZE_URL, config.getApiKey(),
                    OAuthEncoder.encode(config.getCallback()));
        }
    }
    
    @Override
    public Verb getAccessTokenVerb() {
        return Verb.POST;
    }
    
    @Override
    public OAuthService createService(OAuthConfig config) {
        return new GoogleOAuth2Service(this, config);
    }
    
    private class GoogleOAuth2Service extends OAuth20ServiceImpl {
    
        private static final String GRANT_TYPE_AUTHORIZATION_CODE = "authorization_code";
        private static final String GRANT_TYPE = "grant_type";
        private DefaultApi20 api;
        private OAuthConfig config;
    
        public GoogleOAuth2Service(DefaultApi20 api, OAuthConfig config) {
            super(api, config);
            this.api = api;
            this.config = config;
        }
    
        @Override
        public Token getAccessToken(Token requestToken, Verifier verifier) {
            OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint());
            switch (api.getAccessTokenVerb()) {
            case POST:
                request.addBodyParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
                request.addBodyParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
                request.addBodyParameter(OAuthConstants.CODE, verifier.getValue());
                request.addBodyParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
                request.addBodyParameter(GRANT_TYPE, GRANT_TYPE_AUTHORIZATION_CODE);
                break;
            case GET:
            default:
                request.addQuerystringParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
                request.addQuerystringParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
                request.addQuerystringParameter(OAuthConstants.CODE, verifier.getValue());
                request.addQuerystringParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
                if(config.hasScope()) request.addQuerystringParameter(OAuthConstants.SCOPE, config.getScope());
            }
            Response response = request.send();
            return api.getAccessTokenExtractor().extract(response.getBody());
        }
    }
    
    }
    

    并在Config.groovy 中更新google provider

    ....
    google {
        api = yourPackate.Google2Api
        ...
    }
    ....
    

    注意:- 包名不能与 scribe api 相同,即org.scribe.builder.api。使一些东西不同的包名称。我正在使用org.scribe.api

    【讨论】:

      【解决方案3】:

      https://github.com/manishkbharti/grailsOauthPluginDemo 已经更新了 google 使用 Oauth2 的方式。如果您不能使用此 Demo 中的 Oauth2,您可以查看 grails 插件:Google for Spring Security OAuth 插件 (https://github.com/donbeave/grails-spring-security-oauth-google)。在他们的源代码中,他们尝试实现Oauth2 from DefaultApi20 class

      我不知道为什么,但我只能在处理后获得授权码,所以我需要做一个额外的步骤来将此代码转换为访问令牌,这里是详细代码:

      def oauth2callback = { def code = params.code

          HttpTransport transport = new NetHttpTransport();
          JacksonFactory jsonFactory = new JacksonFactory();
          String CLIENT_ID = "....";
          String CLIENT_SECRET = "....";
          String REDIRECT_URI = ".....";
      
          GoogleTokenResponse response =
              new GoogleAuthorizationCodeTokenRequest(transport, jsonFactory, CLIENT_ID, CLIENT_SECRET, code, REDIRECT_URI).execute();
      
          GoogleCredential credential = new GoogleCredential.Builder().setClientSecrets(CLIENT_ID, CLIENT_SECRET)
                  .setJsonFactory(jsonFactory).setTransport(transport).build()
                  .setAccessToken(response.getAccessToken()).setRefreshToken(response.getRefreshToken());
      
          SpreadsheetService service = new SpreadsheetService("MySpreadsheetIntegration-v1");
          service.setOAuth2Credentials(credential);
          // Define the URL to request.  This should never change.
          URL SPREADSHEET_FEED_URL = new URL(
                  "https://spreadsheets.google.com/feeds/spreadsheets/private/full");
      
          // Make a request to the API and get all spreadsheets.
          SpreadsheetFeed feed = service.getFeed(SPREADSHEET_FEED_URL, SpreadsheetFeed.class);
          List<SpreadsheetEntry> spreadsheets = feed.getEntries();
      
          spreadsheets.each {
              println it.getTitle().getPlainText()
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2020-05-02
        • 1970-01-01
        • 2018-03-01
        • 2019-03-02
        • 2021-08-25
        • 2019-11-06
        • 1970-01-01
        • 1970-01-01
        • 2016-03-03
        相关资源
        最近更新 更多