0
votes

I am trying to make a online photo library where user upload image from their mobile devices like Android to the server and can access it. Current I am using Grails with Spring Security Plugin Core and I saved all the uploaded image in a folder in /web-app/uploaded-image. The upload part is currently working and I am able to upload image from my device to the server uploaded-image folder. However, one question I have is that currently I am using these line in my Config.groovy to do the access control part

grails.plugins.springsecurity.interceptUrlMap = [
/uploaded_image/**':['IS_AUTHENTICATED_REMEMBERED']
]

I planned on having the controller associate the image's path to a DomainClass called image which will be associate with each user's DomainClass. My question is that how do I make it so that user that is not the owner of the image would not have permission to view the image? I tried search google for answer and did not find many useful answer. Thank you for your time.

2
I'm not sure if this is the best way to solved the problem, but I ended up using the Requestmap way to do the access control and then add a new Requestmap which only allow the user who upload it to access it every time a new file is uploaded. It seems like the cache had to be flush out every time someone upload a image so I am not sure if this would be a good solution and it look like it kinda do what I want for now. - user1004215

2 Answers

1
votes

First, uploading images into the exploded WAR path is a bad idea. What happens when you have to deploy an update? Best to store your images completely outside the WAR structure.

Secondly, I've handled this several different ways.

  • Stream the image back via a Grails Controller. That way you can have direct access to the image request and deal with any kind of security you want, including checking roles, etc.

Very simple version that doesn't take into account caching, response headers, etc:

def avatarFilePath = new File(userInstance.avatarURL)
response.setContentType("application/png")
response.setContentLength(avatarFilePath.size().toInteger())
OutputStream out = response.getOutputStream();
out.write(avatarFilePath.bytes);
out.close();
  • Store the image in some content repository (AmazonS3 perhaps) and then either control the permissions through the providers API or have your own controller manage the security then redirect appropriately through the provider.

  • Use Apache in front of your Tomcat/Container and have Apache handle all the nitty gritty details of streaming the image back. I'm not sure how to handle the security in this case, however.

0
votes

You can use following logic to make sure that user that is not the owner of the image would not have permission to view the image

class ImageController {


  def springSecurityService

  def showImage() {
  Image image=Image.get(parmas.long("id")

 // this is the user  who is trying to access image from ui
    User user = User.get(image.userId) 

 //this is the logged-in user       
  User logged = User.get(springSecurityService.principal.id)
   if (user.id != logged.id) {
  {
      redirect(action: "accessDenied", controller='access' id: params.long("id"))        
    //re-direct accessDenied page

 }else{
 //show image  
  }
  }

  Class AccessController{
 def accessDenied= {

    render(view: "accessDenied")

}
}