Search code examples
playframeworkdeadboltdeadbolt-2

Play java project with Deadbolt, having private Assets


I've been looking around to try and find an example of how to configure a folder of assets, have it being accessed through the @routes.Assets notation but only returning the asset if a user is authenticated.

I've got deadbolt configured and working perfectly using google accounts, the application is working as well, but unfortunately when I use the browser and write down the direct URL for the Javascript assets that are used for the application part, it allows me to download them without problems.

So, overall question is: Is there a way to configure an Assets folder that can only be accessed if the User is authenticated?

Thanks so much

Edit1 : the way I'm doing it now is I created a Controller called PrivateAssets , with a method called "at" that takes in a String path and String file arguments. That method is annotated with @SubjectPresent and in there I go and get the file and return it.


Solution

  • How I went about it was :

    Create an PrivateAssets that extends AssetsBuilderlike so :

    public class PrivateAssets extends AssetsBuilder {
    
        private final static Logger logger = LoggerFactory.getLogger(PrivateAssets.class);
    
        private static User getLocalUser(final Http.Session session) {
            final AuthUser currentAuthUser = PlayAuthenticate.getUser(session);
            final User localUser = User.findByAuthUserIdentity(currentAuthUser);
            return localUser;
        }
    
        private static Http.Session session() { return Http.Context.current().session(); }
    
        private static Http.Request request() { return Http.Context.current().request(); }
    
        private static Http.Response response() { return Http.Context.current().response();}
    
        @SubjectPresent
        public static Result at(String path , String file) {
            logger.debug(getLocalUser(session()).email + " -> secure asset call : " + path + " | " + file);
            return Results.ok(Play.application().getFile(path + File.separator + file), true);
        }
    }
    

    I also modified my Routes file in this way :

    GET         /assets/*file                                controllers.Assets.at(path="/public/public", file)
    GET         /secure/assets/*file                         controllers.PrivateAssets.at(path="/public/private", file)
    

    My public folder now has 2 other folders inside :

    - public
    - private
    

    Inside public I have all the asset structure that any person can have access to.

    Inside private I have all the asset structure that only authenticated used have access to.

    To get any of the private assets I do something like this :

    <script src="@routes.PrivateAssets.at("private.min.js")"></script>
    

    There were other options, as modifying the build.sbt file as described in the 2.3 migration guide to add another asset folder, in order to have two distinct folder for each type of asset. This gave me more problems than anything else, specially while testing.

    Hope this helps anyone else that need this sort of thing.