reset password
Author Message
yurimuradyan
Posts: 42
Posted 22:09 Jun 01, 2009 |

I was wondering if any of you are having the same problem and know of a solution. When I edit a blog entry I use the saveBlogEntry to do this. Problem is, I also use the same method for creating a new entry. The requirement of part 1 of homework 7 asks us to limit Creating a new blogEntry to owner of the blog, but editing must be limited to the owner OR the Admin.

I am not sure how to separate the two (Add and Edit) when trying to secure the saveBlogEntry.

cysun
Posts: 2935
Posted 22:50 Jun 01, 2009 |

You don't have to distinguish Add and Edit blog entries. If it implicitly allows the Admin to create blog entries, that's OK.

yurimuradyan
Posts: 42
Posted 22:52 Jun 01, 2009 |
cysun wrote:

You don't have to distinguish Add and Edit blog entries. If it implicitly allows the Admin to create blog entries, that's OK.

Great, thank you!!

yurimuradyan
Posts: 42
Posted 00:19 Jun 02, 2009 |

Hi Dr. Sun,

Sorry, I missed this part of my question. I have a similar situation with saveComment, when I call it during creation and edit. This either means everyone can add/edit, or only user and admin can add/edit. In other words, I am not sure how to allow everyone who is ROLE_USER to add, but only author and admin to edit. Could you make a suggestion please, since I am not sure if this is should be treated the same way as blogEntry creation? Thanks in advance!!

cysun
Posts: 2935
Posted 10:08 Jun 02, 2009 |

I think you can check whether the Id field is null or not in saveComment() (or saveBlogEntry()) to determine if a comment (or a blog entry) is new. Try that and let me know if it works.

So basically you'll use RoleVoter to ensure that only ROLE_USER can call saveComment(), and then your own voter to check the edit case.

yurimuradyan
Posts: 42
Posted 11:55 Jun 02, 2009 |
cysun wrote:

I think you can check whether the Id field is null or not in saveComment() (or saveBlogEntry()) to determine if a comment (or a blog entry) is new. Try that and let me know if it works.

This works perfectly, thank You!!

So basically you'll use RoleVoter to ensure that only ROLE_USER can call saveComment(), and then your own voter to check the edit case.

This portion, however, I am not so sure about. I had an idea of creating 2 other methods, say saveCommenNew() and saveCommentEdit() and call them based on the comment.getId() (whether it is null or not). Then I can secure those methods instead of securing the saveComment() itself. Will this be ok, or is there a more ellegant way of handling this??

 

Last edited by yurimuradyan at 11:55 Jun 02, 2009.
cysun
Posts: 2935
Posted 12:16 Jun 02, 2009 |
yurimuradyan wrote:

This portion, however, I am not so sure about. I had an idea of creating 2 other methods, say saveCommenNew() and saveCommentEdit() and call them based on the comment.getId() (whether it is null or not). Then I can secure those methods instead of securing the saveComment() itself. Will this be ok, or is there a more ellegant way of handling this??

That's OK, and from a security perspective it's probably better because it distinguishes the "new" case and the "edit" case. From the application perspective I like having just saveComment() though, and it can be secured by something like the following in spring-security.xml:

    csns.model.blog.dao.CommentDao.saveComment=ROLE_USER,PERM_BLOG_COMMENT_WRITE

The roleVoter (referenced by methodAccessDecisionManager) will ensure that only ROLE_USER can call this method, and a custom voter, e.g. BlogCommentWriterVoter, needs to be created to handle the edit case.

yurimuradyan
Posts: 42
Posted 13:26 Jun 02, 2009 |
cysun wrote:
yurimuradyan wrote:

This portion, however, I am not so sure about. I had an idea of creating 2 other methods, say saveCommenNew() and saveCommentEdit() and call them based on the comment.getId() (whether it is null or not). Then I can secure those methods instead of securing the saveComment() itself. Will this be ok, or is there a more ellegant way of handling this??

That's OK, and from a security perspective it's probably better because it distinguishes the "new" case and the "edit" case. From the application perspective I like having just saveComment() though, and it can be secured by something like the following in spring-security.xml:

    csns.model.blog.dao.CommentDao.saveComment=ROLE_USER,PERM_BLOG_COMMENT_WRITE

The roleVoter (referenced by methodAccessDecisionManager) will ensure that only ROLE_USER can call this method, and a custom voter, e.g. BlogCommentWriterVoter, needs to be created to handle the edit case.

That sounds great, but how will I be able to distinguish (inside the BlogCommentWriteVoter) if it is an edit or a new entry? I guess that is the main issue I am having. I don't know how to distinguish the 2 inside the voter.

cysun
Posts: 2935
Posted 13:30 Jun 02, 2009 |
yurimuradyan wrote:
cysun wrote:
yurimuradyan wrote:

This portion, however, I am not so sure about. I had an idea of creating 2 other methods, say saveCommenNew() and saveCommentEdit() and call them based on the comment.getId() (whether it is null or not). Then I can secure those methods instead of securing the saveComment() itself. Will this be ok, or is there a more ellegant way of handling this??

That's OK, and from a security perspective it's probably better because it distinguishes the "new" case and the "edit" case. From the application perspective I like having just saveComment() though, and it can be secured by something like the following in spring-security.xml:

    csns.model.blog.dao.CommentDao.saveComment=ROLE_USER,PERM_BLOG_COMMENT_WRITE

The roleVoter (referenced by methodAccessDecisionManager) will ensure that only ROLE_USER can call this method, and a custom voter, e.g. BlogCommentWriterVoter, needs to be created to handle the edit case.

That sounds great, but how will I be able to distinguish (inside the BlogCommentWriteVoter) if it is an edit or a new entry? I guess that is the main issue I am having. I don't know how to distinguish the 2 inside the voter.

Using the id field of the entry. You said it worked. Smile

yurimuradyan
Posts: 42
Posted 13:32 Jun 02, 2009 |
cysun wrote:
yurimuradyan wrote:
cysun wrote:
yurimuradyan wrote:

This portion, however, I am not so sure about. I had an idea of creating 2 other methods, say saveCommenNew() and saveCommentEdit() and call them based on the comment.getId() (whether it is null or not). Then I can secure those methods instead of securing the saveComment() itself. Will this be ok, or is there a more ellegant way of handling this??

That's OK, and from a security perspective it's probably better because it distinguishes the "new" case and the "edit" case. From the application perspective I like having just saveComment() though, and it can be secured by something like the following in spring-security.xml:

    csns.model.blog.dao.CommentDao.saveComment=ROLE_USER,PERM_BLOG_COMMENT_WRITE

The roleVoter (referenced by methodAccessDecisionManager) will ensure that only ROLE_USER can call this method, and a custom voter, e.g. BlogCommentWriterVoter, needs to be created to handle the edit case.

That sounds great, but how will I be able to distinguish (inside the BlogCommentWriteVoter) if it is an edit or a new entry? I guess that is the main issue I am having. I don't know how to distinguish the 2 inside the voter.

Using the id field of the entry. You said it worked. Smile

Yeap, I am so sorry, it's been a very long day. Yes, it's working now. Thanks a lot Dr. Sun!!!

yurimuradyan
Posts: 42
Posted 13:42 Jun 02, 2009 |
yurimuradyan wrote:
cysun wrote:
yurimuradyan wrote:
cysun wrote:
yurimuradyan wrote:

This portion, however, I am not so sure about. I had an idea of creating 2 other methods, say saveCommenNew() and saveCommentEdit() and call them based on the comment.getId() (whether it is null or not). Then I can secure those methods instead of securing the saveComment() itself. Will this be ok, or is there a more ellegant way of handling this??

That's OK, and from a security perspective it's probably better because it distinguishes the "new" case and the "edit" case. From the application perspective I like having just saveComment() though, and it can be secured by something like the following in spring-security.xml:

    csns.model.blog.dao.CommentDao.saveComment=ROLE_USER,PERM_BLOG_COMMENT_WRITE

The roleVoter (referenced by methodAccessDecisionManager) will ensure that only ROLE_USER can call this method, and a custom voter, e.g. BlogCommentWriterVoter, needs to be created to handle the edit case.

That sounds great, but how will I be able to distinguish (inside the BlogCommentWriteVoter) if it is an edit or a new entry? I guess that is the main issue I am having. I don't know how to distinguish the 2 inside the voter.

Using the id field of the entry. You said it worked. Smile

Yeap, I am so sorry, it's been a very long day. Yes, it's working now. Thanks a lot Dr. Sun!!!

Jumped the gun, AGAIN. I tested it in saveComment(), and it works there. However, inside the voter it does not, because at this point the comment already has an assigned id, even if it is a brand new comment. Sorry for the confusion.

cysun
Posts: 2935
Posted 13:53 Jun 02, 2009 |
yurimuradyan wrote:
...

Jumped the gun, AGAIN. I tested it in saveComment(), and it works there. However, inside the voter it does not, because at this point the comment already has an assigned id, even if it is a brand new comment. Sorry for the confusion.

Are you sure about that? A new object should get an id after getHibernateTemplate().saveOrUpdate(obj), which happens inside saveComment(). Your voter, which should be an AccessDecisionVoter (e.g. inherits MethodAccessVoter), not an AfterInvocationProvider, should intercept saveComment() before it's called. In spring-security.xml, it should be wired to methodAccessDecisionManager, not afterInvocationManager.

And BTW, as indicated by their names, AccessDecisionVoter decides whether an access (including method invocation) should happen at all, while an AfterInvocationProvider checks the return value after a method is invoked.

yurimuradyan
Posts: 42
Posted 14:10 Jun 02, 2009 |
cysun wrote:
yurimuradyan wrote:
...

Jumped the gun, AGAIN. I tested it in saveComment(), and it works there. However, inside the voter it does not, because at this point the comment already has an assigned id, even if it is a brand new comment. Sorry for the confusion.

Are you sure about that? A new object should get an id after getHibernateTemplate().saveOrUpdate(obj), which happens inside saveComment(). Your voter, which should be an AccessDecisionVoter (e.g. inherits MethodAccessVoter), not an AfterInvocationProvider, should intercept saveComment() before it's called. In spring-security.xml, it should be wired to methodAccessDecisionManager, not afterInvocationManager.

And BTW, as indicated by their names, AccessDecisionVoter decides whether an access (including method invocation) should happen at all, while an AfterInvocationProvider checks the return value after a method is invoked.

I think that's what I have. Here are snippets of the code as I have it implemented, maybe this can help to clarify the situation:

BlogCommentWriteVoter

import org.aopalliance.intercept.MethodInvocation;

import csns.model.User;
import csns.model.blog.Comment;

public class BlogCommentWriteVoter extends MethodAccessVoter {

    public boolean isAccessAllowed( User user, MethodInvocation method )
    {
        Comment comment = (Comment) method.getArguments()[0];
        if (comment.getId()==null)
            return true;
        else
            return comment.getAuthor() == user;
    }

}


From spring-security.xml:

<bean id="methodAccessDecisionManager"
class="csns.spring.security.vote.UnanimousBased">
<property name="allowIfAllAbstainDecisions" value="false" />
<property name="decisionVoters">
<list>
.....
......
<ref local="blogCommentWriteVoter" />
</list>
</property>
</bean>

....
<bean id="blogCommentWriteVoter"
class="csns.spring.security.access.BlogCommentWriteVoter">
<property name="userDao" ref="userDao" />
<property name="processConfigAttribute" value="PERM_BLOG_COMMENT_WRITE" />
<property name="privilegedRoles" value="ROLE_ADMIN" />
</bean>

....
csns.model.blog.dao.BlogDao.saveComment=ROLE_USER,ROLE_ADMIN,PERM_BLOG_COMMENT_WRITE
cysun
Posts: 2935
Posted 14:44 Jun 02, 2009 |
yurimuradyan wrote:
I think that's what I have. Here are snippets of the code as I have it implemented, maybe this can help to clarify the situation:

....

The code looks fine syntactically. I don't know why your getId() didn't return null for new Comments - Hibernate needs that information to decide whether to generate an INSERT statement or an UPDATE statement. I also tried with existing CSNS code, and getId() does return null for new objects. If you can't figure out the problem, bring your laptop to my office hours tomorrow.

yurimuradyan
Posts: 42
Posted 14:46 Jun 02, 2009 |
cysun wrote:
yurimuradyan wrote:
I think that's what I have. Here are snippets of the code as I have it implemented, maybe this can help to clarify the situation:

....

The code looks fine syntactically. I don't know why your getId() didn't return null for new Comments - Hibernate needs that information to decide whether to generate an INSERT statement or an UPDATE statement. I also tried with existing CSNS code, and getId() does return null for new objects. If you can't figure out the problem, bring your laptop to my office hours tomorrow.

If I cannot figure out I will see you tomorrow during your office hours. Thanks again Dr. Sun!!

liangxu
Posts: 15
Posted 23:14 Jun 02, 2009 |

My paradox is with "edit blog entry" and "add comments".   A blog entry is saved after it is edited.

Also after a comment is added to a blog entry, this blog entry is saved too.  Both securities are binded

to method saveBlogentry, blog entry can be edited only by its author or admin, while comments can

be added by any roleuser.   Is there anyway to work out this paradox?  Or I have to use tag lib

in the JSP to hide the "edit blog entry" button?   Thanks.

cysun
Posts: 2935
Posted 16:38 Jun 03, 2009 |
liangxu wrote:

My paradox is with "edit blog entry" and "add comments".   A blog entry is saved after it is edited.

Also after a comment is added to a blog entry, this blog entry is saved too.  Both securities are binded

to method saveBlogentry, blog entry can be edited only by its author or admin, while comments can

be added by any roleuser.   Is there anyway to work out this paradox?  Or I have to use tag lib

in the JSP to hide the "edit blog entry" button?   Thanks.

This basically means that you can't simply secure blogEntryDao.saveBlogEntry() for all possible cases. The idealistic approach is to create different methods/services for different purposes and secure them separately. For example, use blogEntryDao.addComment() and blogEntryDao.createEntry() instead of just blogEntryDao.saveEntry(). The pragmatic approach is to do some security checks in controllers. Note that either way, you should hide the "edit" button when appropriate.

liangxu
Posts: 15
Posted 22:44 Jun 03, 2009 |

Hi Prof Sun,

Thanks for your suggestions.  But I have some doubts on your last comment, i.e.,

"Note that either way, you should hide the "edit" button when appropriate."


As for my understanding, if I use the first way secure blogEntryDao.saveBlogEntry(),
an unauthorized user will get a page like "access denied" after he clicks the
edit button and does some editting.  If the "edit" button is hidden here,
the system won't even get to the blogEntryDao.saveBlogEntry secure method level.
In this view, we shouldn't hide the "edit" button here.

Please correct me if I'am wrong.  Thanks.

cysun
Posts: 2935
Posted 23:57 Jun 03, 2009 |
liangxu wrote:

Hi Prof Sun,

Thanks for your suggestions.  But I have some doubts on your last comment, i.e.,

"Note that either way, you should hide the "edit" button when appropriate."


As for my understanding, if I use the first way secure blogEntryDao.saveBlogEntry(),
an unauthorized user will get a page like "access denied" after he clicks the
edit button and does some editting.  If the "edit" button is hidden here,
the system won't even get to the blogEntryDao.saveBlogEntry secure method level.
In this view, we shouldn't hide the "edit" button here.

Please correct me if I'am wrong.  Thanks.

I'm not sure if I understand what you mean by "In this view, we shouldn't hide the edit button". Note that the purpose of security is not to show an "access denied" page, but to prevent users from doing what they should not do.

Let's say that User A and User B both left some comments to a blog entry. After User A logs in, he (or she) should only see Edit buttons for his (or her) own comments. In other words, there should not be Edit buttons for User B's comments, and that's what I refer to as "hide the edit button when appropriate".

Note that hiding the edit button is a user interface design requirement. It is not really a security measure because it does not prevent a user to access the edit page directly by typing the right URL in the browser's address bar. This is the reason why we need to secure methods like saveComment().

abhishek_sharma
Posts: 79
Posted 09:39 Jun 04, 2009 |

Hi Prof

I am little confuse with ROLE, and want to know how we are distinguishing between an Admin from other USER/s in our database.

Because I am facing difficulty in order to provide the 'EditBlogEntry' and 'Edit' link for both blogentry and comment in jsp

<security:authorize ifAllGranted="ROLE_USER">
<a href="<c:url value='addComment.html?blogentryId=${blogentry.id}'/>">Add Comment</a>
<c:if test="${not empty results }">
|<a href="<c:url value='editBlogEntry.html?blogEntryId=${blogentry.id}'/>">Edit BlogEntry</a>
</c:if></security:authorize> 
<security:authorize ifAllGranted="ROLE_ADMIN">
<a href="<c:url value='addComment.html?blogentryId=${blogentry.id}'/>">Add Comment</a>
|<a href="<c:url value='editBlogEntry.html?blogEntryId=${blogentry.id}'/>">Edit BlogEntry</a>
</security:authorize>

This work fine until admin login to his/her own blog and/or comment. A that time Admin satisfies both the condition of being ROLE_USER and ROLE_ADMIN, and am getting all links twice (although both link works in similar way).

I tried with all Grants i.e., Any and Not but still unsucessfull. Please give any kind of suggesstion or hint

Thanks

cysun
Posts: 2935
Posted 11:48 Jun 04, 2009 |
abhishek_sharma wrote:

Hi Prof

I am little confuse with ROLE, and want to know how we are distinguishing between an Admin from other USER/s in our database.

Because I am facing difficulty in order to provide the 'EditBlogEntry' and 'Edit' link for both blogentry and comment in jsp

<security:authorize ifAllGranted="ROLE_USER">
<a href="<c:url value='addComment.html?blogentryId=${blogentry.id}'/>">Add Comment</a>
<c:if test="${not empty results }">
|<a href="<c:url value='editBlogEntry.html?blogEntryId=${blogentry.id}'/>">Edit BlogEntry</a>
</c:if></security:authorize> 
<security:authorize ifAllGranted="ROLE_ADMIN">
<a href="<c:url value='addComment.html?blogentryId=${blogentry.id}'/>">Add Comment</a>
|<a href="<c:url value='editBlogEntry.html?blogEntryId=${blogentry.id}'/>">Edit BlogEntry</a>
</security:authorize>

This work fine until admin login to his/her own blog and/or comment. A that time Admin satisfies both the condition of being ROLE_USER and ROLE_ADMIN, and am getting all links twice (although both link works in similar way).

I tried with all Grants i.e., Any and Not but still unsucessfull. Please give any kind of suggesstion or hint

Thanks

You code logic is kind of messy. It should be something like:

  if USER_ROLE, show Add link

  if isAuthor or isAdmin, show Edit link

You can use <security:authorize> to check for the USER_ROLE, and use <c:if> to check for isAuthor or isAdmin.

liangxu
Posts: 15
Posted 14:15 Jun 04, 2009 |
I'm not sure if I understand what you mean by "In this view, we shouldn't hide the edit button". Note that the purpose of security is not to show an "access denied" page, but to prevent users from doing what they should not do.

Let's say that User A and User B both left some comments to a blog entry. After User A logs in, he (or she) should only see Edit buttons for his (or her) own comments. In other words, there should not be Edit buttons for User B's comments, and that's what I refer to as "hide the edit button when appropriate".

Note that hiding the edit button is a user interface design requirement. It is not really a security measure because it does not prevent a user to access the edit page directly by typing the right URL in the browser's address bar. This is the reason why we need to secure methods like saveComment().

I think somehow I understood it now.  I didn't consider the scenario that some people may copy URL directly to

get the access. Surprised  So it means by using security tag lib  <authorize> and <authentication> in the JSP, we just

appropriately hide the unauthorized access link from people, it does not really secure the info until we apply the

methods, objects or URL secure or some other  securities in the code.  Is it right?   Thanks.

cysun
Posts: 2935
Posted 14:19 Jun 04, 2009 |
liangxu wrote:

I think somehow I understood it now.  I didn't consider the scenario that some people may copy URL directly to get the access. Surprised  So it means by using security tag lib  <authorize> and <authentication> in the JSP, we just appropriately hide the unauthorized access link from people, it does not really secure the info until we apply the methods, objects or URL secure or some other  securities in the code.  Is it right?   Thanks.

That's exactly right.

meera halani
Posts: 39
Posted 16:22 Jun 04, 2009 |

Hello Dr.Sun, I have provded security but is it ok if it allows admin to create new blog entry using URL. I mean if admin directly writes url for creating new blogentry then the new blog entry is created. Is this ok?

 

Last edited by meera halani at 16:31 Jun 04, 2009.
cysun
Posts: 2935
Posted 17:07 Jun 04, 2009 |
meera halani wrote:

Hello Dr.Sun, I have provded security but is it ok if it allows admin to create new blog entry using URL. I mean if admin directly writes url for creating new blogentry then the new blog entry is created. Is this ok?

It's not ideal but it's OK for the homework.

meera halani
Posts: 39
Posted 17:27 Jun 04, 2009 |

Thank you.

kjadhav
Posts: 12
Posted 19:01 Jun 05, 2009 |

I am still facing the same problem. My Spring-security.xml has

 

    <bean id="blogEntryWriteVoter"
        class="csns.spring.security.access.BlogEntryWriteVoter">
        <property name="userDao" ref="userDao" />
        <property name="processConfigAttribute" value="PERM_BLOGENTRY_WRITE" />
    </bean>
   
    <bean id="blogCommentWriteVoter"
        class="csns.spring.security.access.BlogCommentWriteVoter">
        <property name="userDao" ref="userDao" />
        <property name="processConfigAttribute" value="PERM_BLOGCOMMENT_WRITE" />
    </bean>

 

Added below in methodAccessDecisionManager

                <ref local="blogCommentWriteVoter" />
                <ref local="blogEntryWriteVoter" />

 

And below code in methodInvocationInterceptor

                csns.model.blog.dao.BlogCommentDao.saveComment=ROLE_USER,PERM_BLOGCOMMENT_WRITE

 

Added below code in BlogCommentWriteVoter

        Comment comment = (Comment) method.getArguments()[0];
        if (comment.getId()==null)
            return true;
        else
            return comment.getAuthor() == user;

Problem is that any user is able to edit comment of other users. Does anyone know where may be the problem or has anyone faced similar problem.