Search code examples
javaplayframeworkplay-framework-2.7

Play Framework 2.7 Authorization Get User


I'm trying to add authorization to a Rest API I've built in Play 2.7. I found a good example for older play versions here but I do not have access to the Http Context so I cannot add the user as an arg.

Is there another way to do this in Play 2.7 without having access to the context?

public class Secured extends Security.Authenticator {

    @Override
    public String getUsername(Context ctx) {
        String[] authTokenHeaderValues = ctx.request().headers().get(SecurityController.AUTH_TOKEN_HEADER);
        if ((authTokenHeaderValues != null) && (authTokenHeaderValues.length == 1) && (authTokenHeaderValues[0] != null)) {
            User user = models.User.findByAuthToken(authTokenHeaderValues[0]);
            if (user != null) {
                ctx.args.put("user", user);
                return user.getEmailAddress();
            }
        }

        return null;
    }

    @Override
    public Result onUnauthorized(Context ctx) {
        return unauthorized();
    }
}

I'm wanting to have the ability to get the user from other controllers as they have done in the Todo Controller.

Edit: My question comes down to where do you store the authenticated User in Play 2.7, since Http.Context is deprecated?


Solution

  • You can use Action Composition

    https://www.playframework.com/documentation/2.7.x/JavaActionsComposition#Passing-objects-from-action-to-controller

    public class Attrs {
        public static final TypedKey<User> USER = TypedKey.<User>create("user");
    }
    
    public class PassArgAction extends play.mvc.Action.Simple {
        public CompletionStage<Result> call(Http.Request req) {
            return delegate.call(req.addAttr(Attrs.USER, User.findById(1234)));
        }
    }
    

    In controller:

    @With(PassArgAction.class)
    public static Result passArgIndex(Http.Request request) {
        User user = request.attrs().get(Attrs.USER);
        return ok(Json.toJson(user));
    }
    

    I will recommend you also to look at pac4j. It has a plugin for playframework:

    https://github.com/pac4j/play-pac4j

    https://github.com/pac4j/play-pac4j-java-demo