Created
December 17, 2015 12:10
-
-
Save schaloner/bade0da9033eb04f306f to your computer and use it in GitHub Desktop.
Auth0 Play Java callback - basic implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package be.objectify.example.controllers; | |
import java.util.Optional; | |
import java.util.concurrent.CompletableFuture; | |
import java.util.concurrent.CompletionStage; | |
import be.objectify.example.models.User; | |
import com.fasterxml.jackson.databind.node.ObjectNode; | |
import com.google.inject.Inject; | |
import play.cache.CacheApi; | |
import play.libs.F; | |
import play.libs.Json; | |
import play.libs.concurrent.HttpExecutionContext; | |
import play.libs.ws.WS; | |
import play.libs.ws.WSResponse; | |
import play.mvc.Controller; | |
import play.mvc.Http; | |
import play.mvc.Result; | |
public class AuthCallback extends Controller { | |
private static final String DOMAIN = "example.eu.auth0.com"; | |
private final HttpExecutionContext ec; | |
private final CacheApi cache; | |
@Inject | |
public AuthCallback(final HttpExecutionContext ec, | |
final CacheApi cache) { | |
this.ec = ec; | |
this.cache = cache; | |
} | |
public CompletionStage<Result> callback(final Optional<String> maybeCode, | |
final Optional<String> maybeState) { | |
return maybeCode.map(code -> getToken(code).thenComposeAsync(tuple -> getUser(tuple._2, | |
tuple), | |
ec.current()) | |
.thenApplyAsync(tuple2 -> { | |
cache.set(tuple2._2._1 + "profile", | |
tuple2._1); | |
session("idToken", | |
tuple2._2._1); | |
session("accessToken", | |
tuple2._2._2); | |
return redirect(routes.Application.dashboard()); | |
}, | |
ec.current()) | |
.exceptionally(t -> unauthorized(t.getMessage()))) | |
.orElseGet(() -> CompletableFuture.supplyAsync(() -> badRequest("No parameters supplied"), | |
ec.current())); | |
} | |
private CompletionStage<F.Tuple<String, String>> getToken(final String code) { | |
final ObjectNode root = Json.newObject(); | |
root.put("client_id", | |
"foo"); | |
root.put("client_secret", | |
"bar"); | |
root.put("redirect_uri", | |
"http://localhost:9001/callback"); | |
root.put("code", | |
code); | |
root.put("grant_type", | |
"authorization_code"); | |
return WS.url(String.format("https://%s/oauth/token", | |
DOMAIN)) | |
.setHeader(Http.HeaderNames.ACCEPT, | |
Http.MimeTypes.JSON) | |
.post(root) | |
.thenApplyAsync(WSResponse::asJson, | |
ec.current()) | |
.thenApplyAsync(json -> new F.Tuple<>(json.get("id_token").asText(), | |
json.get("access_token").asText()), | |
ec.current()) | |
.exceptionally(t -> { | |
throw new IllegalStateException("Tokens not sent"); | |
}); | |
} | |
private CompletionStage<F.Tuple<User, F.Tuple<String, String>>> getUser(final String accessToken, | |
final F.Tuple<String, String> tuple) { | |
return WS.url(String.format("https://%s/userinfo", | |
DOMAIN)) | |
.setQueryParameter("access_token", | |
accessToken) | |
.get() | |
.thenApplyAsync(WSResponse::asJson, | |
ec.current()) | |
.thenApplyAsync(json -> new F.Tuple<>(new User.Builder().givenName(json.get("name").asText()).build(), | |
tuple), | |
ec.current()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment