Stormpath не может получить объект учетной записи для входа в Google

Я полностью следовал руководству Google< /strong> к письмам и руководству Stormpath по интеграции с google тоже по буквам

Теперь пользователь может успешно войти в систему с помощью Google, но Stormpath выдает исключение в этой строке при попытке получить объект учетной записи Stormpath с использованием кода авторизации, полученного от Google;

ProviderAccountResult result = application.getAccount(request);

Вот фрагмент кода;

public static Account getAccount(String codeOrToken, AuthType authType){
    try{
        if(getDirectory() != null){
            ProviderAccountRequest request = null;
            switch(authType){
                case AUTH_CODE: 
                    request = Providers.GOOGLE.account().setCode(codeOrToken).build(); 
                    break;
                case ACCESS_TOKEN: 
                    request = Providers.GOOGLE.account().setAccessToken(codeOrToken).build(); 
                    break;
                default: 
                    break;
            }
            Application application = AuthUtil.getApplication();
            ProviderAccountResult result = application.getAccount(request);
            Account account = result.getAccount();
            account.getCustomData().put("isNew", result.isNewAccount());
            return account;
        }
    }catch(Exception ex){
        ex.printStackTrace();
    }
    return null;
}

А вот Exception StackTrace;

16:45:02,170 ERROR [stderr] (http-localhost-127.0.0.1-8080-5) com.stormpath.sdk.resource.ResourceException: HTTP 400, Stormpath 7200 (http://docs.stormpath.com/errors/7200): Stormpath was not able to complete the request to Google: this can be caused by either a bad Google directory configuration, or the provided account credentials are not valid. Google error message: 400 Bad Request
16:45:02,172 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.DefaultDataStore.execute(DefaultDataStore.java:492)

16:45:02,173 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.DefaultDataStore.access$000(DefaultDataStore.java:67)

16:45:02,174 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.DefaultDataStore$2.filter(DefaultDataStore.java:390)

16:45:02,175 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.DefaultFilterChain.filter(DefaultFilterChain.java:47)

16:45:02,176 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.ProviderAccountResultFilter.filter(ProviderAccountResultFilter.java:31)

16:45:02,177 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.DefaultFilterChain.filter(DefaultFilterChain.java:52)

16:45:02,178 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.api.ApiKeyQueryFilter.filter(ApiKeyQueryFilter.java:74)

16:45:02,180 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.DefaultFilterChain.filter(DefaultFilterChain.java:52)

16:45:02,181 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.cache.WriteCacheFilter.filter(WriteCacheFilter.java:80)

16:45:02,184 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.DefaultFilterChain.filter(DefaultFilterChain.java:52)

16:45:02,184 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.cache.ReadCacheFilter.filter(ReadCacheFilter.java:62)

16:45:02,185 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.DefaultFilterChain.filter(DefaultFilterChain.java:52)

16:45:02,186 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.api.DecryptApiKeySecretFilter.filter(DecryptApiKeySecretFilter.java:62)

16:45:02,187 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.DefaultFilterChain.filter(DefaultFilterChain.java:52)

16:45:02,188 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.EnlistmentFilter.filter(EnlistmentFilter.java:42)

16:45:02,189 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.DefaultFilterChain.filter(DefaultFilterChain.java:52)

16:45:02,189 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.DefaultDataStore.save(DefaultDataStore.java:411)

16:45:02,190 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.ds.DefaultDataStore.create(DefaultDataStore.java:322)

16:45:02,191 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.provider.ProviderAccountResolver.resolveProviderAccount(ProviderAccountResolver.java:46)

16:45:02,192 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at com.stormpath.sdk.impl.application.DefaultApplication.getAccount(DefaultApplication.java:325)

16:45:02,193 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at ng.ajo.socials.Google.getAccount(Google.java:79)

16:45:02,193 ERROR [stderr] (http-localhost-127.0.0.1-8080-5)   at ng.ajo.server.SocialsServlet.doPost(SocialsServlet.java:81)

//... The rest omitted for brevity

Подскажите пожалуйста, что я могу делать не так и как решить эту проблему?

ИЗМЕНИТЬ:

Если это поможет предоставить больше контекста, вот как я создаю свой каталог Google:

public class Google {

    public static Directory getDirectory(){
        try{
            Directory directory = DirectoryUtil.getGoogleDirectory();

            //if the google directory does not exist CREATE it
            if(directory == null){
                Client client = AuthUtil.getClient();
                directory = client.instantiate(Directory.class);
                directory.setName(dirName);
                directory.setDescription(dirDescription);

                CreateDirectoryRequest request = Directories.newCreateRequestFor(directory)
                            .forProvider(Providers.GOOGLE.builder()
                                    .setClientId(appID)
                                    .setClientSecret(appSecret)
                                    .setRedirectUri(redirectURI)
                                    .build()
                            ).build();

                Tenant tenant = client.getCurrentTenant();
                directory = tenant.createDirectory(request);
                Application application = AuthUtil.getApplication();
                application.addAccountStore(directory.getHref());
            }

            return directory;

        }catch(Exception ex){
            ex.printStackTrace();
        }
    }
}

И когда я вхожу в свою веб-консоль Stormpath, я вижу, что каталог был создан и действительно существует со всеми конфигурациями на месте... теперь все это должно работать , но это не... все еще приводит меня в замешательство!


person SourceVisor    schedule 04.12.2015    source источник


Ответы (1)


  1. Перейдите на страницу https://console.developers.google.com/apis/credentials.
  2. Убедитесь, что вы «Добавить учетные данные»
  3. Обратите внимание на «Идентификатор клиента» и «Секрет клиента».
  4. Добавьте несколько «авторизованных URI перенаправления», например http://localhost:8080/googleOauthCallback
  5. Войдите на странице https://api.stormpath.com.
  6. Добавьте каталог Google, указав правильные ID, Secret и Redirect URI
  7. Теперь давайте получим код Google простым способом (без создания веб-проекта). Откройте этот URL в своем браузере; при появлении запроса выберите учетную запись Gmail, которую хотите использовать.

    https://accounts.google.com/o/oauth2/auth?client_id=XXXXXXX
    &response_type=code
    &scope=openid%20email
    &redirect_uri=http://localhost:8080/googleOauthCallback
    

    Примечание. XXXXXXX необходимо заменить идентификатором клиента, полученным на шаге 3.

  8. Вы получите сообщение об ошибке cannot connect to server, но это нормально, так как мы не используем веб-приложение, через которое Google может нам перезвонить. Здесь важно указать URL. Просто скопируйте значение code. Это будет что-то вроде 4/tcHrwq4N1eah1rwotyCEaXq-yfxBOYrIAVe2_ouHTMQ

  9. Этот код получит учетную запись Google через Stormpath:

    Client client = Clients.builder().build();
    
    Application application = client.getResource(applicationHref, Application.class);
    
    ProviderAccountRequest request = Providers.GOOGLE.account()
            .setCode(code) //where code is the value we obtained in step 8
            .build();
    
    ProviderAccountResult result = application.getAccount(request);
    System.out.println("Account Email: " + result.getAccount().getEmail());
    ProviderData providerData = result.getAccount().getProviderData();
    System.out.println("Access Token: " + ((GoogleProviderData)providerData).getAccessToken());
    

Это все...

person mario    schedule 07.12.2015
comment
Привет @jstack, спасибо за ответ. В моем приложении я сделал все эти вещи... Я уже очень хорошо получил этот код авторизации... Все работает нормально до этой строки ProviderAccountResult result = application.get account(request);... Возможно, это как-то связано с тем, как я получаю свои Client или Application объект, я не знаю, и хотя кажется странным, что это может быть причиной, я все равно попытаюсь сделать это, как вы показали, и вернуться к тому, что происходит. Спасибо. - person SourceVisor; 08.12.2015
comment
Убедитесь, что: 1) приложение Stormpath имеет каталог Google в качестве хранилища учетных записей. 2) Вы передаете код (а не метод accessToken в методе code(String). 3) Если у вас более одного приложения Google, убедитесь, что каталог, который вы настраиваете в Stormpath, соответствует тому же приложению Google, в котором вы создаете код. за - person mario; 08.12.2015
comment
привет @jstack, я сделал все это, но безуспешно. На самом деле, если вы посмотрите на код, который я предоставил в вопросе, вы увидите, что я делаю именно то, что вы описали. Мой AuthUtil.getApplication(); делает именно это client.getResource(applicationHref, Application.class);. Когда я отлаживаю eclipse, я обнаруживаю, что (1.) application объект извлекается правильно (2.) у меня есть code из Google, который выглядит примерно так 4/sz8XzIk5lPbgaQB3hNVg2M6pH06BdLC0G2IPdETujWM (3.) request объект построен правильно (*) ПРОБЛЕМА application.getAccount(request) все еще выдает это исключение; - person SourceVisor; 11.12.2015
comment
Эй, @jsatck, только что произошло что-то странное. Я использовал code, полученный путем отправки запроса GET, как вы указали, я смог получить объект Account, никакого исключения... Странно, что я даже ничего не изменил в своей кодовой базе. Единственное, что я сделал, это просто отправил запрос на получение с моими параметрами в этом URL. Теперь мне интересно, есть ли разница между code, которые я получаю при входе в Google developers.google.com/identity/sign-in/web/server-side-flow и code, которые я получаю, отправляя запрос на получение на этот URL?... Почему это работает с Stormpath, а другой нет? - person SourceVisor; 11.12.2015
comment
Код, который вы получаете с developers.google.com/identity/sign -in/web/server-side-flow предназначен для связи между серверами, а не между пользователем и сервером. За кулисами Strormpath использует этот межсерверный механизм, но вы должны создать пользовательский код: developers.google.com/identity/protocols/OAuth2UserAgent - person mario; 11.12.2015
comment
Большой. Было бы здорово, если бы вы могли проголосовать за это решение, чтобы оно могло помочь другим разработчикам в будущем. Спасибо! - person mario; 11.12.2015
comment
и @jstack, если вы работаете в Stormpath, было бы неплохо, чтобы ваши люди четко добавили эту маленькую деталь в документацию Stormpath. - person SourceVisor; 11.12.2015
comment
я хотел бы использовать эту возможность, чтобы вы помогли мне с моим другим вопросом здесь... Socially-signed-in-user-from-servlet-request-using-stormpa" title="Есть ли способ получить социально зарегистрированного пользователя из запроса сервлета с помощью stormpa"> stackoverflow.com/questions/34228709/ - person SourceVisor; 11.12.2015