rewrite and redirection problem

Splash Forums PrettyFaces Users rewrite and redirection problem

This topic contains 5 replies, has 2 voices, and was last updated by  Enygmatik 2 years, 11 months ago.

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #24819

    Enygmatik
    Participant

    Hello,

    Here is my issue :
    I use PostLoginEvent event to redirect user to the initial requested page after he successfully logged in.
    here my login method :

    public String login(){
    		if(password != null && mail != null){
    			credentials.setUsername(mail);
    			PasswordCredential pc = new PasswordCredential(PasswordCredential.md5AsHexString(password));
    			credentials.setCredential(pc);
    			identity.login();
    			if(identity.isLoggedIn()){
    				localeSelector.setLocale(new Locale(currentUserManager.getCurrentUser().getPreferences().getDefaultLanguage().getDisplayName()));
    				FacesContext fc = FacesContext.getCurrentInstance();
    				Map<String, Object> sessionMap = fc.getExternalContext().getSessionMap();
    				postLoginEvent.fire(new PostLoginEvent(fc, sessionMap));
    			}
    		}
    		return "";
    	}

    all is working fine, except for redirect with parameters
    here is what happens :
    – user calls random page : http://localhost:8080/wal/interactive/1 (rewrited url by pretty faces)
    – redirected to login page beacause he is not yet
    – login successful, redirection happening
    But when the redirection is made, the url is now http://localhost:8080/wal/interactive/1?id=1
    Redirection method add again the previous paramater because, I guess, it doesn’t recognize “/1” as the parameter.

    Any suggestions about how to fix this ?

    Thanks a lot,

    Enygmatik

    #24820

    So you are using Seam Security, correct?

    To be honest, I don’t think that PrettyFaces is the problem here. It looks like the URL is correctly rewritten (/wal/interactive/1). I’ve no idea where the additional query parameter comes from. I guess Seam Security is doing something weird here.

    #24821

    Oh sorry, PostLoginEvent isn’t from Seam Security, isn’t it?

    #24822

    Enygmatik
    Participant

    PostLoginEvent is from Seam faces.
    But seam security has a class with an observer on PostLoginEvent who redirect to the previous URL indeed.
    Here is the class :

    /*
     * JBoss, Home of Professional Open Source
     * Copyright 2011, Red Hat, Inc., and individual contributors
     * by the @authors tag. See the copyright.txt in the distribution for a
     * full listing of individual contributors.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     * http://www.apache.org/licenses/LICENSE-2.0
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    package org.jboss.seam.faces.security;
    
    import java.io.IOException;
    import java.util.Map;
    
    import javax.enterprise.event.Observes;
    import javax.faces.context.FacesContext;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.RequestDispatcher;
    
    import org.jboss.seam.faces.event.PostLoginEvent;
    import org.jboss.seam.faces.event.PreLoginEvent;
    
    /**
     * Listen for {@link PreLoginEvent} and {@link PostLoginEvent} events, storing the viewId requested pre login,
     * and re-instating the navigation post login.
     *
     * @author <a href="mailto:bleathem@gmail.com">Brian Leathem</a>
     */
    public class LoginListener {
    
        private static final String PRE_LOGIN_URL = LoginListener.class.getName() + "_PRE_LOGIN_URL";
    
        public void observePreLoginEvent(@Observes PreLoginEvent event) {
            if (event.getFacesContext().getExternalContext().getRequest() instanceof HttpServletRequest) {
                HttpServletRequest request = (HttpServletRequest) event.getFacesContext().getExternalContext().getRequest();
                StringBuffer sb = request.getRequestURL();
                // If the original url has been forwarded, use the original
                Object forwardedUrl = event.getFacesContext().getExternalContext().getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);
                if (forwardedUrl != null && forwardedUrl instanceof String) {
                    sb = new StringBuffer((String) forwardedUrl);
                }
                // build the querystring out of the request parameters, because Reqeust#getQueryString is often null
                Map<String, String> requestParameterMap = event.getFacesContext().getExternalContext().getRequestParameterMap();
                if (requestParameterMap != null) {
                    boolean first = true;
                    for (Map.Entry<String, String> entry : requestParameterMap.entrySet()) {
                        if (first) {
                            sb.append("?");
                            first = false;
                        } else {
                            sb.append("&");
                        }
                        sb.append(entry.getKey()).append("=").append(entry.getValue());
                    }
                }
                String requestedUrl = sb.toString();
                event.getSessionMap().put(PRE_LOGIN_URL, requestedUrl);
            }
        }
    
        public void observePostLoginEvent(@Observes PostLoginEvent event) {
            FacesContext context = event.getFacesContext();
            if (context.getExternalContext().getSessionMap().get(PRE_LOGIN_URL) != null) {
                String oldUrl = (String) context.getExternalContext().getSessionMap().get(PRE_LOGIN_URL);
                context.getExternalContext().getSessionMap().remove(PRE_LOGIN_URL);
                try {
                    event.getFacesContext().getExternalContext().redirect(oldUrl);
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
        }
    }
    

    I’m currently trying to figure out who is creating this wrong url, but I can’t figure it out.
    In the observer, the old URL is already malformed :
    String oldUrl = (String) context.getExternalContext().getSessionMap().get(PRE_LOGIN_URL);
    returns : wal/interactive/1?id=1

    • This reply was modified 2 years, 11 months ago by  Enygmatik.
    #24824

    For me it looks like LoginListener.observePreLoginEvent() takes the original URL (which is /wal/interactive/1 in your case) and then appends all query parameters to this base URL (see if (requestParameterMap != null) block).

    So for me it looks like Seam Security is messing things up here. There are some options for you in this case:

    1. Manually overwrite the URL in the session map with the correct one.
    2. Create your own LoginListener by extending the existing one and annotating it with @Spezializes. Then overwrite observePreLoginEvent and fix the code.
    3. Do the redirect yourself

    #24825

    Enygmatik
    Participant

    Yeah, i found it too. I decided to rewrite manually the URL. I think I’ll go your way and rewrite the LoginListener, it seems cleaner.
    Thanks a lot !

    Regards,

    Enygmatik

Viewing 6 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic.

Comments are closed.