Updated to social
This commit is contained in:
parent
ae045d4822
commit
75dd88cf5d
9 changed files with 59 additions and 34 deletions
|
@ -31,30 +31,26 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jboss.spec.javax.ejb</groupId>
|
<groupId>org.jboss.spec.javax.ejb</groupId>
|
||||||
<artifactId>jboss-ejb-api_3.2_spec</artifactId>
|
<artifactId>jboss-ejb-api_3.2_spec</artifactId>
|
||||||
<scope>provided</scope>
|
|
||||||
<version>1.0.0.Alpha2</version>
|
<version>1.0.0.Alpha2</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.api-client</groupId>
|
<groupId>com.google.api-client</groupId>
|
||||||
<artifactId>google-api-client</artifactId>
|
<artifactId>google-api-client</artifactId>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.http-client</groupId>
|
<groupId>com.google.http-client</groupId>
|
||||||
<artifactId>google-http-client-jackson</artifactId>
|
<artifactId>google-http-client-jackson</artifactId>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.apis</groupId>
|
<groupId>com.google.apis</groupId>
|
||||||
<artifactId>google-api-services-oauth2</artifactId>
|
<artifactId>google-api-services-oauth2</artifactId>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.twitter4j</groupId>
|
<groupId>org.twitter4j</groupId>
|
||||||
<artifactId>twitter4j-core</artifactId>
|
<artifactId>twitter4j-core</artifactId>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ public interface IdentityProvider {
|
||||||
String getId();
|
String getId();
|
||||||
|
|
||||||
@XmlTransient
|
@XmlTransient
|
||||||
URI getAuthUrl(IdentityProviderCallback callback);
|
URI getAuthUrl(IdentityProviderCallback callback) throws IdentityProviderException;
|
||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
|
@ -45,6 +45,6 @@ public interface IdentityProvider {
|
||||||
boolean isCallbackHandler(IdentityProviderCallback callback);
|
boolean isCallbackHandler(IdentityProviderCallback callback);
|
||||||
|
|
||||||
@XmlTransient
|
@XmlTransient
|
||||||
User processCallback(IdentityProviderCallback callback);
|
User processCallback(IdentityProviderCallback callback) throws IdentityProviderException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package org.keycloak.social;
|
||||||
|
|
||||||
|
public class IdentityProviderErrors {
|
||||||
|
public static final String INVALID_PROVIDER = "invalid_provider";
|
||||||
|
public static final String PROVIDER_ERROR = "provider_error";
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package org.keycloak.social;
|
||||||
|
|
||||||
|
public class IdentityProviderException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public IdentityProviderException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -24,9 +24,9 @@ package org.keycloak.social.google;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.jboss.resteasy.logging.Logger;
|
|
||||||
import org.keycloak.social.IdentityProvider;
|
import org.keycloak.social.IdentityProvider;
|
||||||
import org.keycloak.social.IdentityProviderCallback;
|
import org.keycloak.social.IdentityProviderCallback;
|
||||||
|
import org.keycloak.social.IdentityProviderException;
|
||||||
import org.picketlink.idm.model.SimpleUser;
|
import org.picketlink.idm.model.SimpleUser;
|
||||||
import org.picketlink.idm.model.User;
|
import org.picketlink.idm.model.User;
|
||||||
|
|
||||||
|
@ -46,8 +46,6 @@ public class GoogleProvider implements IdentityProvider {
|
||||||
|
|
||||||
private static final JacksonFactory JSON_FACTORY = new JacksonFactory();
|
private static final JacksonFactory JSON_FACTORY = new JacksonFactory();
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(GoogleProvider.class);
|
|
||||||
|
|
||||||
private static final NetHttpTransport TRANSPORT = new NetHttpTransport();
|
private static final NetHttpTransport TRANSPORT = new NetHttpTransport();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -81,7 +79,7 @@ public class GoogleProvider implements IdentityProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User processCallback(IdentityProviderCallback callback) {
|
public User processCallback(IdentityProviderCallback callback) throws IdentityProviderException {
|
||||||
String code = callback.getQueryParam("code");
|
String code = callback.getQueryParam("code");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -109,8 +107,7 @@ public class GoogleProvider implements IdentityProvider {
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to process callback", e);
|
throw new IdentityProviderException(e);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package org.keycloak.social.resources;
|
||||||
|
|
||||||
|
import javax.ws.rs.ApplicationPath;
|
||||||
|
import javax.ws.rs.core.Application;
|
||||||
|
|
||||||
|
@ApplicationPath("social/api")
|
||||||
|
public class SocialApplication extends Application {
|
||||||
|
|
||||||
|
}
|
|
@ -41,8 +41,11 @@ import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.logging.Logger;
|
||||||
import org.keycloak.social.IdentityProvider;
|
import org.keycloak.social.IdentityProvider;
|
||||||
import org.keycloak.social.IdentityProviderCallback;
|
import org.keycloak.social.IdentityProviderCallback;
|
||||||
|
import org.keycloak.social.IdentityProviderErrors;
|
||||||
|
import org.keycloak.social.IdentityProviderException;
|
||||||
import org.keycloak.social.IdentityProviderState;
|
import org.keycloak.social.IdentityProviderState;
|
||||||
import org.keycloak.social.util.UriBuilder;
|
import org.keycloak.social.util.UriBuilder;
|
||||||
import org.picketlink.idm.model.Attribute;
|
import org.picketlink.idm.model.Attribute;
|
||||||
|
@ -51,9 +54,11 @@ import org.picketlink.idm.model.User;
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
@Path("social")
|
@Path("")
|
||||||
public class SocialResource {
|
public class SocialResource {
|
||||||
|
|
||||||
|
private static final Logger log = Logger.getLogger(SocialResource.class);
|
||||||
|
|
||||||
// TODO This is just temporary - need to either save state variables somewhere they can be flushed after a timeout, or
|
// TODO This is just temporary - need to either save state variables somewhere they can be flushed after a timeout, or
|
||||||
// alternatively they could be saved in http session, but that is probably not a good idea
|
// alternatively they could be saved in http session, but that is probably not a good idea
|
||||||
private static final Map<String, IdentityProviderState> states = new HashMap<String, IdentityProviderState>();
|
private static final Map<String, IdentityProviderState> states = new HashMap<String, IdentityProviderState>();
|
||||||
|
@ -89,9 +94,12 @@ public class SocialResource {
|
||||||
callback.setProviderState(getProviderState(provider));
|
callback.setProviderState(getProviderState(provider));
|
||||||
|
|
||||||
if (provider.isCallbackHandler(callback)) {
|
if (provider.isCallbackHandler(callback)) {
|
||||||
User user = provider.processCallback(callback);
|
User user = null;
|
||||||
if (user == null) {
|
try {
|
||||||
break;
|
user = provider.processCallback(callback);
|
||||||
|
} catch (IdentityProviderException e) {
|
||||||
|
log.warn("Failed to process callback", e);
|
||||||
|
redirectToLogin(application, IdentityProviderErrors.PROVIDER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
String providerUsername = user.getLoginName();
|
String providerUsername = user.getLoginName();
|
||||||
|
@ -135,6 +143,7 @@ public class SocialResource {
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("providers")
|
@Path("providers")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public List<IdentityProvider> getProviders() {
|
public List<IdentityProvider> getProviders() {
|
||||||
List<IdentityProvider> providers = new LinkedList<IdentityProvider>();
|
List<IdentityProvider> providers = new LinkedList<IdentityProvider>();
|
||||||
Iterator<IdentityProvider> itr = ServiceRegistry.lookupProviders(IdentityProvider.class);
|
Iterator<IdentityProvider> itr = ServiceRegistry.lookupProviders(IdentityProvider.class);
|
||||||
|
@ -170,13 +179,12 @@ public class SocialResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response redirectToLogin(String application, String error) {
|
private Response redirectToLogin(String application, String error) {
|
||||||
URI uri = new UriBuilder(headers, uriInfo, "login?application=" + application + "&error=login_failed").build();
|
URI uri = new UriBuilder(headers, uriInfo, "sdk/api/" + application + "/login").setQueryParam("error", error).build();
|
||||||
return Response.seeOther(uri).build();
|
return Response.seeOther(uri).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{application}/auth/{provider}")
|
@Path("{application}/auth/{provider}")
|
||||||
@Produces(MediaType.TEXT_HTML)
|
|
||||||
public Response redirectToProviderAuth(@PathParam("application") String application,
|
public Response redirectToProviderAuth(@PathParam("application") String application,
|
||||||
@PathParam("provider") String providerId) {
|
@PathParam("provider") String providerId) {
|
||||||
Iterator<IdentityProvider> itr = ServiceRegistry.lookupProviders(IdentityProvider.class);
|
Iterator<IdentityProvider> itr = ServiceRegistry.lookupProviders(IdentityProvider.class);
|
||||||
|
@ -186,7 +194,8 @@ public class SocialResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (provider == null) {
|
if (provider == null) {
|
||||||
return redirectToLogin(application, "invalid_provider");
|
log.warn("Failed to redirect to provider auth: " + providerId + " not found");
|
||||||
|
return redirectToLogin(application, IdentityProviderErrors.INVALID_PROVIDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentityProviderCallback callback = new IdentityProviderCallback();
|
IdentityProviderCallback callback = new IdentityProviderCallback();
|
||||||
|
@ -195,12 +204,13 @@ public class SocialResource {
|
||||||
callback.setUriInfo(uriInfo);
|
callback.setUriInfo(uriInfo);
|
||||||
callback.setProviderKey(null); // TODO Get provider key
|
callback.setProviderKey(null); // TODO Get provider key
|
||||||
callback.setProviderSecret(null); // TODO Get provider secret
|
callback.setProviderSecret(null); // TODO Get provider secret
|
||||||
|
callback.setProviderState(getProviderState(provider));
|
||||||
|
|
||||||
URI authUrl = provider.getAuthUrl(callback);
|
try {
|
||||||
if (authUrl != null) {
|
return Response.seeOther(provider.getAuthUrl(callback)).build();
|
||||||
return Response.seeOther(authUrl).build();
|
} catch (Throwable t) {
|
||||||
} else {
|
log.warn("Failed to redirect to provider auth", t);
|
||||||
return redirectToLogin(application, "invalid_provider");
|
return redirectToLogin(application, IdentityProviderErrors.PROVIDER_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,9 @@ package org.keycloak.social.twitter;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import org.jboss.resteasy.logging.Logger;
|
|
||||||
import org.keycloak.social.IdentityProvider;
|
import org.keycloak.social.IdentityProvider;
|
||||||
import org.keycloak.social.IdentityProviderCallback;
|
import org.keycloak.social.IdentityProviderCallback;
|
||||||
|
import org.keycloak.social.IdentityProviderException;
|
||||||
import org.picketlink.idm.model.SimpleUser;
|
import org.picketlink.idm.model.SimpleUser;
|
||||||
import org.picketlink.idm.model.User;
|
import org.picketlink.idm.model.User;
|
||||||
|
|
||||||
|
@ -38,15 +38,13 @@ import twitter4j.auth.RequestToken;
|
||||||
*/
|
*/
|
||||||
public class TwitterProvider implements IdentityProvider {
|
public class TwitterProvider implements IdentityProvider {
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(TwitterProvider.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "twitter";
|
return "twitter";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URI getAuthUrl(IdentityProviderCallback callback) {
|
public URI getAuthUrl(IdentityProviderCallback callback) throws IdentityProviderException {
|
||||||
try {
|
try {
|
||||||
Twitter twitter = new TwitterFactory().getInstance();
|
Twitter twitter = new TwitterFactory().getInstance();
|
||||||
twitter.setOAuthConsumer(callback.getProviderKey(), callback.getProviderSecret());
|
twitter.setOAuthConsumer(callback.getProviderKey(), callback.getProviderSecret());
|
||||||
|
@ -55,8 +53,7 @@ public class TwitterProvider implements IdentityProvider {
|
||||||
callback.putState(requestToken.getToken(), requestToken);
|
callback.putState(requestToken.getToken(), requestToken);
|
||||||
return callback.createUri(requestToken.getAuthenticationURL()).build();
|
return callback.createUri(requestToken.getAuthenticationURL()).build();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to retrieve login url", e);
|
throw new IdentityProviderException(e);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +68,7 @@ public class TwitterProvider implements IdentityProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User processCallback(IdentityProviderCallback callback) {
|
public User processCallback(IdentityProviderCallback callback) throws IdentityProviderException {
|
||||||
try {
|
try {
|
||||||
Twitter twitter = new TwitterFactory().getInstance();
|
Twitter twitter = new TwitterFactory().getInstance();
|
||||||
twitter.setOAuthConsumer(callback.getProviderKey(), callback.getProviderSecret());
|
twitter.setOAuthConsumer(callback.getProviderKey(), callback.getProviderSecret());
|
||||||
|
@ -86,8 +83,7 @@ public class TwitterProvider implements IdentityProvider {
|
||||||
user.setFirstName(twitterUser.getName());
|
user.setFirstName(twitterUser.getName());
|
||||||
return user;
|
return user;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to process callback", e);
|
throw new IdentityProviderException(e);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue