Results 1 to 8 of 8

Thread: Best way to approach following scenario

  1. #1
    Join Date
    Aug 2004
    Location
    New York, NY
    Posts
    46

    Default Best way to approach following scenario

    I am hoping this is common enough of a scenario that someone out there has tackled it already.

    I have Users and they have Roles. Each of these roles represents a URL to protect. So far, that's pretty simple with Acegi Security System for Spring. Just wire up a fitler assigning the roles to the url to protect.

    My biggest problem is the index page of this app. When a user first come in or their session is invalid, the page should show a login form.

    If the user is logged in, it should show links to the URLs they are allowed to go to using the auth tag provided by Acegi Security System for Spring.

    How can I achieve this without making the index page protected by some generic role? I ask this mostly because there's user administration in the app and someone could inadvertantly remove this generic role from a user, and that would be bad.

    I guess I could add the generic role dynamically when the UserDetails' getGrantedAuthorties() method is called, but that hard codes the generic role in. I'd like to externalize this as much as possible.

    Another solution I thought of was writing my own tags to check for authentication. But I had misunderstood the isAuthenticated() method on the Authencation object. I expected it to be set to true if the user was authenticated....but that's only if the url is protected.

    Along the lines of my own tag, is it enough that an Authentication object exists in the secure context to ensure that the user has at least been challenged by Acegi and successfully presented credentials? If so, I could just have my tags make a check for just an Authentication object, disregarding the isAuthenticated() method.

    Would that work? Any other ideas on how to tackle the problem?

    Thanks,
    Patrick

  2. #2
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    You can wire against your FilterSecurityInterceptor's AccessDecisionManager an additional AccessDecisionVoter called IsLoggedInVoter. The voter would simply return AccessDecisionVoter.ACCESS_GRANTED, as for the voter to have been called the FilterSecurityInterceptor (or more technically, AbstractSecurityInterceptor) will have already run it via the authentication process. You'd make it respond to a particular configuration attribute, such as MUST_BE_LOGGED_IN and you'd make that the only configuration attribute against your index page. Thus you are avoiding using a generic role.

    I am assuming your index page is a redirect to something like /secure/index.jsp, so your login page can be at /login.jsp or similar.

    Onto your taglib question, unless someone especially writes a false Authentication to the well-known container location or ContextHolder you can be safe in extracting it from the ContextHolder and assuming Acegi Security at some point validated it. The isAuthenticated() should be ignored. It will return true if it was definately validated during that web request, or false if not.

  3. #3
    Join Date
    Aug 2004
    Location
    New York, NY
    Posts
    46

    Default

    Thanks again Ben.

    My layout is something like this, except with Spring based MVC instead:


    /
    index.jsp
    login.jsp
    loginForm.jsp
    accessdenied.jsp


    The index.jsp page has a check for Authenticated (I wrote tags that check what you described...good assumption I made there). If false, it includes the loginForm.jsp and if true, it shows a menu based on role access. Then those links go into role protected areas of the site (such as /useradmin ) .

    If you try and access a role protected area, you are redirected to the login.jsp page and it includes the loginForm.jsp. I thought sharing it would be better than duplicating it.

    The only problem I have run into with this, and I will be checking out tomorrow is Sitemesh. All our pages are decorated with the same decorator and the decorator page uses my authentication checking tag to decided whether or not to show a logout link. Strang thing is, the tag doesn't work there. ContextHolder during the Sitemesh call to the tag doesn't have anything. It's like it's on another thread and since the acegi filter has already been applied in this chain (my fix from before) acegi never runs during that sitemesh request. It's all very strange. I'm going to confirm it's in another thread tomorrow and try and figure out how to get around that. This is with Jboss 3.2.5 with the Tomcat container. I will also be checking it with Weblogic 8.1 SP3. I let you know the results there.

    I know the tag works with the index.jsp page because it shows what I expect if you are or are not authenticated. It definitely has something to do with RequestDispatcher.forward() or RequestDispatcher.include().

    I also got to wondering about AccessDecisionVoter, but I don't understand where I would put the MUST_BE_LOGGED_IN in the config. What would that look like since the voter would also return ACCESS_GRANTED.

    Thanks again,
    Patrick

  4. #4
    Join Date
    Aug 2004
    Location
    New York, NY
    Posts
    46

    Default

    RE: AccessDecisionVoter

    I really shouldn't post after a long day at work. After coming back and exploring my config, I see exactly how all that will work. Pardon my lack of understanding...

    Thanks,
    Patrick

  5. #5
    Join Date
    Aug 2004
    Location
    New York, NY
    Posts
    46

    Default

    And I figured out the Sitemesh thing...ugh. Filter order is certainly important...I had Sitemesh before the Acegi filters and of couse that isn't going to work since Acegi cleans up after itself.

    Putting Sitemesh after Acegi cleared up my problems with my tags.

    Patrick

  6. #6
    Join Date
    Aug 2004
    Posts
    19

    Default

    I don't fully understand Ben's reply earlier. Could you please elaborate a bit. My situation is quite similar in that I have a number of pages where I don't care what the user's role is, as long as the user is logged in. I'd like to understand how to configure this situation without creating some generic role.

    Thanks,
    Will

  7. #7
    Join Date
    Aug 2004
    Posts
    19

    Default

    OK. So after puzzling through Ben's comment above, and working with some code, I did figure this out.

    Now for a similar but slightly different scenario. I'd like to protect all URLs in my webapp, except one or two. So one of my config attributes would be like

    /**/*=ROLE_USER

    But somehow I want to specify that /public.html (for example) doesn't require authentication. How would I do that?

    (By the way, protecting all my URLs works because I'm using CAS, and the logon page is on a remote server.)

    Will

  8. #8
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    You can specifiy particular URLs do not require a login by using the anonymous authentication support in Acegi Security. See the Contacts Sample Filter version for a full example. Basically you use AnonymousProcessingFilter and this populates a ROLE_ANONYMOUS, and then you define public.html=ROLE_ANONYMOUS in the FilterSecurityInterceptor.
    Ben Alex
    Project Founder, Spring UAA, Spring Roo and Spring Security

Similar Threads

  1. Replies: 1
    Last Post: Jun 24th, 2007, 10:58 AM
  2. Replies: 3
    Last Post: Oct 3rd, 2005, 01:58 PM
  3. Replies: 3
    Last Post: Jun 24th, 2005, 09:46 PM
  4. Replies: 1
    Last Post: Nov 30th, 2004, 04:42 PM
  5. Replies: 4
    Last Post: Nov 7th, 2004, 01:07 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •