2016-05-16 74 views
1

我有一個Keycloak(standalone)v1.9.4.Final安裝設置使用AWS實例上的Wildfly 10,並試圖使用keycloak(通過keycloak的登錄頁面)和Twitter4j來驗證用戶身份Twitter,然後明顯讓我的應用程序進行身份驗證並查看用戶時間表等。訪問由Keycloak返回的用戶Oauth令牌

我配置了身份提供商(Twitter),領域和我的客戶端應用程序。

我還在apps.twitter.com上設置了Twitter應用程序設置,並將密鑰放入我的twitter4j.properties文件中。

到目前爲止,我能:

  1. 轉到我的應用程序的JSF網頁,並重定向到Keycloak的/ AUTH登錄頁面
  2. 點擊Twitter的標誌和我的Twitter帳戶(獨立賬戶的登錄該帳戶擁有Twitter應用程序)
  3. 完成Keycloak要求的用戶信息
  4. 完成用戶信息後,Keycloak成功地將用戶導回到客戶端應用程序(在本例中爲JSF頁面)。

問題是,我無法弄清楚如何訪問用戶OAuth AccessToken和AccessTokenSecret與Twitter應用程序的ConsumerKey和ConsumerKeySecret結合。

下面是代碼中的相關片段:

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

取決於我們如何安排的各種令牌(嘗試不同的令牌字符串在不同的地方),我們會在調用verifyCredentials()時返回不同的錯誤,但所有的錯誤基本上是「無效認證」。

對我們來說很明顯,.getTokenString()和.getIdTokenString()方法並不是正確的方法,但我們對Keycloak在哪裏提供用戶的oauth標記感到不知所措。我們嘗試着着眼於facesContext.getExternalContext()。getRequest()和facesContext.getExternalContext()。getResponse(),但沒有多少運氣。

我的問題是,當Keycloak重定向回客戶端應用程序(服務提供者)後,用戶使用Twitter進行身份驗證並在Keycloak中註冊用戶,oauth令牌的位置在哪裏,以便我們可以訪問它們,然後雙擊認證(應用程序/用戶認證)?

回答

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"; 

}