JSF JSF Redirect zu Requested URL nach Login

Marc T.

Bekanntes Mitglied
Hallo Leute,

ich arbeite derzeit an einem kleinen Problem. Ich habe einen Login implementiert
mit Hilfe eines Loginfilters. Um das ganze zu testen habe ich natürlich auch eine
kleine private XHTML-Seite, die unter

Code:
private/text.xhtml

gespeichert ist.

Wenn jetzt ein User, der nicht eingeloggt ist, auf die test.xhtml zugreifen möchte,
wird er zur Login-Seite umgeleitet. Ich möchte nun aber die ursprünglich angeforderte
URL, also zur test.xhtml, speichern, damit ich den User nach erfolgreichem Login dahin
umleiten kann.

Hier mal mein Loginfilter, in dem ich versuche, die angeforderte URL als Session-Attribut
zu speichern:

Java:
@WebFilter("/private/*")
public class LoginFilter implements Filter {
	@Inject
	private NavigationService navigationService = null;
	
	@Override
	public void init(FilterConfig config) throws ServletException {}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse res = (HttpServletResponse)response;
		
		String from = req.getRequestURI();
		
		if(req.getQueryString() != null) {
			from += "?" + req.getQueryString();
		}
		
		User user = (User) req.getSession().getAttribute("user");
		
		if(user != null) {
			chain.doFilter(request, response);
		} else {
			req.getSession().setAttribute("from", from);
			
			res.sendRedirect(req.getContextPath() + navigationService.toLogin());
		}
	}
	
	@Override
	public void destroy() {}
}

Mein LoginService der aufgerufen wird, nachdem man auf den Login-Button geklickt
hat, sieht folgendermaßen aus:

Java:
@Named
@SessionScoped
public class LoginService implements Serializable {
	private String username = "";
	private String password = "";
	@Inject
	private NavigationService navigationService = null;
	@Inject
	private DAO dao = null;
	
	public void doLogin() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
		FacesContext context = FacesContext.getCurrentInstance();
		ExternalContext externalContext = context.getExternalContext();

		User user = null;
		boolean validated = false;
		String from = "";
		
		if(this.username != null && !this.username.trim().isEmpty()) {
			user = dao.findUserByUsername(this.username);
			
			if(this.password != null && !this.password.trim().isEmpty()) {
				validated = PasswordHasher.validatePassword(this.password, user.getPassword());
			}
		}
		
		if(externalContext.getRequestMap().containsKey("from")) {
			from = (String)externalContext.getRequestMap().get("from");
		} else {
			from = navigationService.externalContextRedirectToIndex();
		}
			
		if(user != null && validated) {
			externalContext.getSessionMap().put("user", user);
			externalContext.redirect(from);
		} else {
			context.addMessage(null, new FacesMessage("False username or password!"));
		}
	}
	
	public void doLogout() throws IOException {
		ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
		
		externalContext.invalidateSession();
		externalContext.redirect(externalContext.getRequestContextPath() + navigationService.toLogin());
	}
	
	// Getter and Setter

Nun ist es aber so, dass das ganze entweder nicht in der Session landet oder aber
sonst was passiert denn in der SessionMap befindet sich leider nie "from".

Könnte mir einer dabei helfen?

Ich möchte wie gesagt, dass der User nach erfolgreichem Login zur ursprünglich
angeforderten Seite umgeleitet wird.
 
SessionScoped

Ich denke aber das der nicht viel zur Sache tut, denn der sammelt nur Addressen:

Java:
@Named
@SessionScoped
public class NavigationService implements Serializable {
	
	public String toIndex() {
		return "/index.html";
	}
	
	public String redirectToIndex() {
		return "/index.html?faces-redirect=true";
	}

	public String externalContextToIndex() {
		return "/Web-Tschuwwa/index.html";
	}
	
	public String externalContextRedirectToIndex() {
		return "/Web-Tschuwwa/index.html?faces-redirect=true";
	}
	
	public String toLogin() {
		return "/login/login.html";
	}

	public String redirectToLogin() {
		return "/login/login.html?faces-redirect=true";
	}
	
	public String toRegister() {
		return "/login/register.html";
	}
	
	public String redirectToRegister() {
		return "/login/register.html?faces-redirect=true";
	}
}

Warum ich hier zwei verschiedene links verwende, also einmal mit Web-Tschuwwa und einmal
ohne? Web-Tschuwwa ist mein Projektname und ich habe festgestellt, dass wenn ich über
einen externalContext redirecte und dabei meinem Projektnamen nicht mit angebe, ich
zur index.html von meinem Glassfish Server redirected. Warum weiß ich nicht.
 
Zuletzt bearbeitet:
In dem Filter speicherst du das "from" in der Session und in dem LoginService versuchst es aus dem ExternalContext aus zu lesen. Vielleicht ist das das Problem. Versuche mal im Filter auch mit dem ExternalContext zu arbeiten.

EDIT: Außerdem ist es üblich, dass die Request-URL als GET-Parameter an die Login-URL übergeben wird
 
Zuletzt bearbeitet:
Schon probiert, funktioniert leider nicht, weil der ExternalContext im Filter immer null ist.

Aus dem LoginService hole ich mir aus dem ExternalContext ja die RequestMap, in die
ich ja hier:

Java:
req.getSession().setAttribute("from", from);

Das "from" hinzugefügt habe.
 
Oh ich danke dir!

Java:
if(externalContext.getSessionMap().containsKey("from")) {
	from = (String)externalContext.getSessionMap().get("from");
} else {
	from = navigationService.externalContextRedirectToIndex();
}

schon klappts!
 

Neue Themen


Zurück
Oben