Announcement Announcement Module
Collapse
No announcement yet.
page redirecting depending on Role Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • page redirecting depending on Role

    Hi, I want to show the user depending on his Role different pages. I saw different approaches to do this, but nothing really works for me. I guess I am doing something wrong.

    Ok my actual approach looks like this :

    In my Bean I am having this method to invoke /j_spring_security_check
    Code:
     public String login() throws IOException{
    	        FacesContext.getCurrentInstance().getExternalContext().dispatch("/j_spring_security_check");
    	        FacesContext.getCurrentInstance().responseComplete();
    	        return null;
    	 }

    applicationContext-security.xml :
    Code:
    <http entry-point-ref="loginUrlAuthenticationEntryPoint" auto-config='false'>
        <intercept-url pattern="/login.jsf" filters="none" />   
        <intercept-url pattern="/**" access="IS_AUTHENTICATED_REMEMBERED"/>
        <custom-filter position="FORM_LOGIN_FILTER" ref="customUsernamePasswordAuthenticationFilter"/>   
        <logout />
      </http>
    
     <beans:bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
     <beans:property name="loginFormUrl" value="/login.jsf"/>
    </beans:bean>
    
    <beans:bean id="customUsernamePasswordAuthenticationFilter" class="mywebapp.MyAuthenticationProcessingFilter" >
     <beans:property name="authenticationManager" ref="authenticationManager"/>
     <beans:property name="authenticationFailureHandler" ref="failureHandler"/>
     <beans:property name="authenticationSuccessHandler" ref="successHandler"/>
    </beans:bean>
    
    
    <beans:bean id="successHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
     <beans:property name="defaultTargetUrl" value="/success.jsf"/>
    </beans:bean>
    <beans:bean id="failureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
     <beans:property name="defaultFailureUrl" value="/login.jsf?login_error=true"/>
    </beans:bean>
    MyAuthenticationProcessingFilter.java :
    Code:
    public class MyAuthenticationProcessingFilter extends
    UsernamePasswordAuthenticationFilter{
    	
    	 @Override
    	 protected void successfulAuthentication(HttpServletRequest request,HttpServletResponse response, Authentication authResult)throws IOException, ServletException {
    	     super.successfulAuthentication(request, response, authResult);
    	     String role =  authResult.getAuthorities().toString();
    	    
    	     
    		
    		 if(role.contains("ROLE_ADMIN")){
    			 System.out.println("adminl");
    			
    			 // i want to redirect from here to admin.jsf
    			
    		 }
    		 else if(role.contains("ROLE_USER")) {
    			 System.out.println("user");
    			
    		 }
    		
    		  
    	 }
    	 
    	
    	
    }

    Is this way right to determine which user is logged in and redirecting to the required page ?

    Would be nice if someone can help me out of this hell
    Incidentally I'm using Spring 3.0.5

  • #2
    Im not sure, because Im not an expert, but I always use this:

    Code:
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    auth.getAuthorities(); // this gives back for example [ROLE_ANONYMOUS]
    when you work with this, you can obtain a lot of informations from it, just go through the methods it offers (getPrincipal(), getDetails(), isAuthenticated()), and its pretty easy to use! also you can use it everywhere, its really comfortable

    Beside of this, I solve it differently when I want to show different content regarding of the role the user has. I redirect them to the SAME jsp and use the sec:authorize tag, for example:

    Code:
    <sec:authorize ifAnyGranted="ROLE_USER,ROLE_ADMIN" ifNotGranted="ROLE_ANONYMOUS">
    
    this text can be seen by users and admins but not by anonymous users
    
            </sec:authorize>
    so you can give back one jsp, but split the content so that a user will see different things than an admin. I dont know if this is the recommended way to do it, but it works and its pretty simple :-) good luck!

    Comment


    • #3
      Awesome Information, thanks.

      I solved the Problem with redirection to the page according to the role this way :
      Code:
      @Override
      	    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException, ServletException {
      	        SavedRequestAwareAuthenticationSuccessHandler srh = new SavedRequestAwareAuthenticationSuccessHandler();
      	        this.setAuthenticationSuccessHandler(srh);
      	        	        
      	        srh.setRedirectStrategy(new RedirectStrategy() {	        	
      	            public void sendRedirect(HttpServletRequest httpServletRequest,
      	                    HttpServletResponse httpServletResponse, String s) throws IOException {
      	                    //do nothing, no redirect
      	            }
      	        });
      	        
      	        super.successfulAuthentication(request, response, authResult);
      
      
      	      ...  
      
      	        
      	        if(role.contains("ROLE_ADMIN")){
      	        	 response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + "/admin.jsf"));	        				 }
      			 else if(role.contains("ROLE_USER")) {
      				 response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + "/student.jsf"));
      			 }
      			 
      	        
      	        
      	    }
      No idea if this is the right way, but it seems to work.
      Last edited by toxor; May 11th, 2011, 04:39 PM.

      Comment


      • #4
        Im glad its working!

        EDIT: I wrote this, but now I think you maybe dont need it, because in the class you use you are obviously not using spring mvc (I think youcan not use it there - sorry, like I said, Im no expert :-)) therefor, its maybe not important to you what I wrote down here. But just in case you might need it, I wont remove it.

        Another question: you dont use Spring MVC, dont you? Because you asked how to redirect... with Spring MVC its really easy

        one example

        Code:
            @RequestMapping(value = {"/user/messages"})
            public ModelAndView welcome() {
                logger.info("welcome(..): mapping to messages.jsp for private user");
                Authentication auth = SecurityContextHolder.getContext().getAuthentication();
                // you can test now which user with which role is requesting the page
        
                Map myModel = new HashMap();
        
                // Parameters: (name of the jsp which shall be called, name of the model, map containing informations to be displayed on the jsp page)
                return new ModelAndView("user/messages", "model", myModel);
        
            }
        this method gets called when /user/messages is requested and it redirects to messages.jsp which is in the folder "user". the jsp gets the information which the model contains. so if you want to redirect to different pages, you could give back a different parameter for the jsp (for example "user/messagesForAdmins") or simply give back a different model, containing only admin-data or user-data
        there are various possibilities :-)
        Last edited by jeeper; May 11th, 2011, 05:02 PM.

        Comment


        • #5
          as far as i know, MVC means a special software-architecture (Model-View-Controler). I'm using that in my Application. But if you mean a special spring-framework i'm not using that. I'm very new to this spring-world, so sry if I don't know what you mean. But thanks anyway for your help and good Informations.

          Comment


          • #6
            Originally posted by toxor View Post
            Awesome Information, thanks.

            I solved the Problem with redirection to the page according to the role this way :
            Code:
            @Override
            	    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException, ServletException {
            	        SavedRequestAwareAuthenticationSuccessHandler srh = new SavedRequestAwareAuthenticationSuccessHandler();
            	        this.setAuthenticationSuccessHandler(srh);
            	        	        
            	        srh.setRedirectStrategy(new RedirectStrategy() {	        	
            	            public void sendRedirect(HttpServletRequest httpServletRequest,
            	                    HttpServletResponse httpServletResponse, String s) throws IOException {
            	                    //do nothing, no redirect
            	            }
            	        });
            	    }
            If you are going to set the RedirectStrategy on the AuthenticationSuccessHandler I would not do it in the successfulAuthentication method since the method is invoked for every request it handles. Placing it in the constructor or configuring this in Spring configuration is probably better since that is only done once. Another reason to move the code is that the code you have posted has a race condition where the RedirectStrategy might not be set correctly. This is due to the fact that multiple threads will be acting on this object at the same time.

            Additionally, rather than have the RedirectStrategy do nothing you could place the logic to redirect based upon the role in the RedirectStrategy. In short, if you are going to use a RedirectStrategy to do this I would create a custom RedirectStrategy implementation that redirects based upon the role and inject it into the Filter.

            Personally I prefer a strategy where the RedirectStrategy will always redirect to the same page and that page will use the role logic to forward to the proper page based upon the role. This decouples your logic from Spring Security. If you search the forums you should find a number of examples of this.

            Comment


            • #7
              now youve got the expert answer :-)

              just one more information to this (in case you might want to know it):
              as far as i know, MVC means a special software-architecture (Model-View-Controler). I'm using that in my Application. But if you mean a special spring-framework i'm not using that. I'm very new to this spring-world, so sry if I don't know what you mean. But thanks anyway for your help and good Informations.
              yes, it's a software pattern and it is a spring module too. when you are using the software pattern in your application, I advice you to use the spring module too. It has very nice features and its very easy to implement. You have Controllers, Models, Views (like normally) and a DispatcherServlet (Front-Controller-Pattern) which dispatches request to controllers. You have a xml-file for it where you do some configuration (for example, if you use annotations for your controllers and how to map to the jsps.) Then you can simply annotate you Controller with @Controllers. Its very simple to use and comfortable. you can configure the RequestMapping with Annotations and return a Map which contains the Model values or just a string, however you need it. its very customizable.

              Comment


              • #8
                thanks, I will give Spring MVC a try.

                Comment


                • #9
                  Originally posted by rwinch View Post
                  If you are going to set the RedirectStrategy on the AuthenticationSuccessHandler I would not do it in the successfulAuthentication method since the method is invoked for every request it handles. Placing it in the constructor or configuring this in Spring configuration is probably better since that is only done once.
                  Can you tell me how to configure this in Spring ?

                  Comment


                  • #10
                    You would set the authenticationSuccessHandler property on the UsernamePasswordAuthenticationFilter to a custom implementation of the RedirectStrategy that performs your logic (you should be able to figure this out from the bean configuration you have already posted). Alternatively, you could use the authentication-success-handler-ref attribute.

                    As I mentioned before, I the the best solution would be to add the logic to determine which page to display to the code that handles default-target-url. You could optionally set always-use-default-target to true if you wanted the user to always see the page after login. This decouples the logic from Spring Security.

                    Comment


                    • #11
                      Other option.

                      Role based login redirect.
                      Redireccion Basada en el Rol del usuario

                      http://oajamfibia.wordpress.com/2011...ct/#comment-12

                      Comment

                      Working...
                      X