Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions examples/as7-eap-demo/server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
<artifactId>keycloak-social-twitter</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-social-facebook</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-sdk-html</artifactId>
Expand Down
34 changes: 34 additions & 0 deletions social/facebook/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>keycloak-social-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-alpha-1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>

<artifactId>keycloak-social-facebook</artifactId>
<name>Keycloak Social Facebook</name>
<description/>

<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-social-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package org.keycloak.social.facebook;

import java.net.URI;
import java.util.UUID;

import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;

import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.keycloak.social.AuthCallback;
import org.keycloak.social.AuthRequest;
import org.keycloak.social.AuthRequestBuilder;
import org.keycloak.social.SocialProvider;
import org.keycloak.social.SocialProviderConfig;
import org.keycloak.social.SocialProviderException;
import org.keycloak.social.SocialUser;

/**
* Social provider for Facebook
*
* @author <a href="mailto:[email protected]">Marek Posolda</a>
*/
public class FacebookProvider implements SocialProvider {

private static final String AUTHENTICATION_ENDPOINT_URL = "https://graph.facebook.com/oauth/authorize";

private static final String ACCESS_TOKEN_ENDPOINT_URL = "https://graph.facebook.com/oauth/access_token";

private static final String PROFILE_ENDPOINT_URL = "https://graph.facebook.com/me";

private static final String DEFAULT_RESPONSE_TYPE = "code";

private static final String DEFAULT_SCOPE = "email";

@Override
public String getId() {
return "facebook";
}

@Override
public AuthRequest getAuthUrl(SocialProviderConfig config) throws SocialProviderException {
String state = UUID.randomUUID().toString();

AuthRequestBuilder b = AuthRequestBuilder.create(state, AUTHENTICATION_ENDPOINT_URL).setQueryParam("client_id", config.getKey())
.setQueryParam("response_type", DEFAULT_RESPONSE_TYPE).setQueryParam("scope", DEFAULT_SCOPE)
.setQueryParam("redirect_uri", config.getCallbackUrl()).setQueryParam("state", state);

b.setAttribute("state", state);

return b.build();
}

@Override
public String getRequestIdParamName() {
return "state";
}

@Override
public String getName() {
return "Facebook";
}

@Override
public SocialUser processCallback(SocialProviderConfig config, AuthCallback callback) throws SocialProviderException {
String code = callback.getQueryParam(DEFAULT_RESPONSE_TYPE);

try {
if (!callback.getQueryParam("state").equals(callback.getAttribute("state"))) {
throw new SocialProviderException("Invalid state");
}

ResteasyClient client = new ResteasyClientBuilder()
.hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY).build();

String accessToken = loadAccessToken(code, config, client);

FacebookUser facebookUser = loadUser(accessToken, client);

SocialUser socialUser = new SocialUser(facebookUser.getId());
socialUser.setEmail(facebookUser.getEmail());
socialUser.setLastName(facebookUser.getLastName());
socialUser.setFirstName(facebookUser.getFirstName());

return socialUser;
} catch (SocialProviderException spe) {
throw spe;
} catch (Exception e) {
throw new SocialProviderException(e);
}
}

protected String loadAccessToken(String code, SocialProviderConfig config, ResteasyClient client) throws SocialProviderException {
Form form = new Form();
form.param("grant_type", "authorization_code")
.param("code", code)
.param("client_id", config.getKey())
.param("client_secret", config.getSecret())
.param("redirect_uri", config.getCallbackUrl());

Response response = client.target(ACCESS_TOKEN_ENDPOINT_URL).request().post(Entity.form(form));

if (response.getStatus() != 200) {
String errorTokenResponse = response.readEntity(String.class);
throw new SocialProviderException("Access token request to Facebook failed. Status: " + response.getStatus() + ", response: " + errorTokenResponse);
}

String accessTokenResponse = response.readEntity(String.class);
return parseParameter(accessTokenResponse, "access_token");
}

protected FacebookUser loadUser(String accessToken, ResteasyClient client) throws SocialProviderException {
URI userDetailsUri = UriBuilder.fromUri(PROFILE_ENDPOINT_URL)
.queryParam("access_token", accessToken)
.queryParam("fields", "id,name,username,first_name,last_name,email")
.build();

Response response = client.target(userDetailsUri).request()
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON)
.get();
if (response.getStatus() != 200) {
String errorTokenResponse = response.readEntity(String.class);
throw new SocialProviderException("Request to Facebook for obtaining user failed. Status: " + response.getStatus() + ", response: " + errorTokenResponse);
}

return response.readEntity(FacebookUser.class);
}

// Parses value of given parameter from input string like "my_param=abcd&another_param=xyz"
private String parseParameter(String input, String paramName) {
int start = input.indexOf(paramName + "=");
if (start != -1) {
input = input.substring(start + paramName.length() + 1);
int end = input.indexOf("&");
return end==-1 ? input : input.substring(0, end);
} else {
throw new IllegalArgumentException("Parameter " + paramName + " not available in response " + input);
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.keycloak.social.facebook;

import org.codehaus.jackson.annotate.JsonProperty;

/**
* Wrap info about user from Facebook
*
* @author <a href="mailto:[email protected]">Marek Posolda</a>
*/
public class FacebookUser {

@JsonProperty("id")
private String id;

@JsonProperty("first_name")
private String firstName;

@JsonProperty("last_name")
private String lastName;

@JsonProperty("username")
private String username;

@JsonProperty("name")
private String name;

@JsonProperty("email")
private String email;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.keycloak.social.facebook.FacebookProvider
1 change: 1 addition & 0 deletions social/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<module>core</module>
<module>google</module>
<module>twitter</module>
<module>facebook</module>
</modules>

</project>