Доступ к токенам пользователя Oauth, возвращаемым Keycloak

У меня есть Keycloak (автономный) v1.9.4. Окончательная настройка установки с использованием Wildfly 10 на экземпляре AWS, и я пытаюсь использовать keycloak (через страницу входа в keycloak) и Twitter4j для аутентификации пользователя с помощью Twitter, а затем, очевидно, мое приложение аутентифицируется и просматривается временная шкала пользователей и т. д.

Я настроил поставщика удостоверений (Twitter), область и свое клиентское приложение.

У меня также есть установка приложения Twitter на apps.twitter.com и ключи, помещенные в мой файл twitter4j.properties.

На данный момент я могу:

  1. Перейдите на веб-страницу JSF моего приложения и перенаправляйтесь на страницу входа /auth Keycloak.
  2. Нажмите на логотип Twitter и войдите в свою учетную запись Twitter (отдельная учетная запись от учетной записи, которой принадлежит приложение Twitter)
  3. Заполните информацию о пользователе, которую запрашивает Keycloak.
  4. После заполнения информации о пользователе Keycloak успешно направляет пользователя обратно в клиентское приложение (в данном случае на страницу JSF).

Проблема в том, что я не могу понять, как получить доступ к пользователям OAuth AccessToken и AccessTokenSecret для объединения с ConsumerKey и ConsumerKeySecret приложения Twitter.

Ниже приведены соответствующие фрагменты кода:

twitterLogin.xhtml

...
#{twitterBean.getUserInfo()}
...


TwitterBean.java

@Context
private final FacesContext facesContext = FacesContext.getCurrentInstance();
private final Twitter twitter = TwitterFactory.getSingleton();

public String getUserInfo() {

    if (facesContext != null) {
        HttpSession httpSession = (HttpSession) facesContext.getExternalContext().getSession(false);
        KeycloakSecurityContext keycloakContext = (RefreshableKeycloakSecurityContext) httpSession.getAttribute(KeycloakSecurityContext.class.getName());
        queryTwitter(keycloakContext.getTokenString(), keycloakContext.getIdTokenString());
    }
}

public void queryTwitter(String accessToken, String accessTokenSecret) {
    ConfigurationBuilder cb = new ConfigurationBuilder();
    cb.setDebugEnabled(true)
            .setOAuthConsumerKey("APPLICATIONS_CONSUMER_KEY")
            .setOAuthConsumerSecret("APPLICATIONS_CONSUMER_KEY_SECRET")
            .setOAuthAccessToken(accessToken)
            .setOAuthAccessTokenSecret(accessTokenSecret);
    TwitterFactory tf = new TwitterFactory(cb.build());
    twitter = tf.getInstance();
    user = twitter.verifyCredentials();
    ...
}

В зависимости от того, как мы размещаем различные токены (попробовав разные строки токенов в разных местах), мы получаем разные ошибки, возвращаемые Twitter при вызове verifyCredentials(), но все они по сути являются «недействительной аутентификацией».

Для нас очевидно, что методы .getTokenString() и .getIdTokenString() не являются правильными для использования, но мы не знаем, где Keycloak может предоставить токены oauth пользователя.

Мы безуспешно пытались посмотреть на FaceContext.getExternalContext().getRequest() и FacesContext.getExternalContext().getResponse().

Мой вопрос: когда Keycloak перенаправляет обратно в клиентское приложение (поставщик услуг) после того, как пользователь аутентифицируется в Twitter и регистрирует пользователя в Keycloak, где хранятся токены oauth, чтобы мы могли получить к ним доступ, а затем выполнить двойную аутентификацию (Application/ Аутентификация пользователя)?


person Brooks    schedule 16.05.2016    source источник


Ответы (1)


Надеюсь, этот фрагмент кода поможет кому-то...

@PostConstruct
public void init() {
    facesContext = FacesContext.getCurrentInstance();
}


public void login() {

    if (user == null) {

        if (facesContext != null) {
            HttpSession httpSession = (HttpSession) facesContext.getExternalContext().getSession(false);
            KeycloakSecurityContext keycloakContext = (RefreshableKeycloakSecurityContext) httpSession.getAttribute(KeycloakSecurityContext.class.getName());
            MyAccessToken accessToken = generateMyAccessToken(keycloakContext);

        }
    }
}

private MyAccessToken generateMyAccessToken(KeycloakSecurityContext keycloakContext) {
    AccessToken keycloakToken = keycloakContext.getToken();
    MyAccessToken token = new MyAccessToken();

    token.withEmail(keycloakToken.getEmail())
            .withExpiration(keycloakToken.getExpiration())
            .withUsername(keycloakToken.getPreferredUsername())
            .withOauthToken(getTwitterOAuthResponse(keycloakContext.getTokenString()))
            .withFirstName(keycloakToken.getGivenName())
            .withLastName(keycloakToken.getFamilyName());

    return token;
}

private OAuthTokenWrapper getTwitterOAuthResponse(final String tokenString) {
    ClientRequestFilter authFilter = new ClientRequestFilter() {
        @Override
        public void filter(ClientRequestContext requestContext) throws IOException {
            requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, "Bearer " + tokenString);
        }
    };

    Client client = ClientBuilder.newBuilder().register(authFilter).build();
    WebTarget target = client.target(getIdentityProviderTokenUrl());

    TwitterOAuthResponse resp = target.request().get().readEntity(TwitterOAuthResponse.class);
    return new OAuthTokenWrapper(resp.getToken(), resp.getTokenSecret());
}

private String getIdentityProviderTokenUrl() {
    return "https://login.example.com:8443/auth/realms/myapp/broker/twitter/token";

}

person Brooks    schedule 28.06.2016
comment
Привет, у тебя есть ссылка на репозиторий github? - person Karan; 23.05.2018