Hoe niet-geverifieerde gebruikers te filteren en een login-formulier te tonen zonder de sessie te starten?

Mijn situatie is:

  1. I have a servlet which should not be accessible by unauthentified users. This servlet does some business logic and passes some intermediary data to a jsp secret.jsp via RequestDispatcher::forward(). (secret.jsp is just an example, there will be many servlets and/or jsps).

  2. There is also a login jsp login.jsp.

  3. In front of the servlet sits a filter which should redirect to login.jsp all the requests from unauthentified users. Basically doFilter() looks like:

    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse resp = (HttpServletResponse) response;
    
    if(-1 == req.getRequestURI().indexOf("login.jsp")) {//if page which is not whitelisted
        HttpSession session = req.getSession(false);
        if(null == session) {
            RequestDispatcher rd = req.getServletContext().getRequestDispatcher("/login.jsp");
            rd.forward(request, response);
        }
        else {
            //not whitelisted but already logged in...
            log("we are logged in");
        }
    }
    
    chain.doFilter(request, response);
    

De problemen zijn

  1. De forward in de servlet zorgt ervoor dat het filter 2 * 2 = 4 keer wordt geactiveerd (twee keer omdat het heen en weer gaat wanneer het verzoek binnenkomt en wanneer het antwoord wordt afgeleverd). Ik zou graag willen dat het slechts één keer wordt geactiveerd (wanneer het oorspronkelijke verzoek binnenkomt) - of op zijn minst slechts twee keer.

  2. De sessie is gestart. Ik wil niet dat de sessie wordt gestart totdat de gebruiker niet daadwerkelijk is geverifieerd (dus de JSESSIONID-cookie naar de client heeft gestuurd).

Wat is de meest elegante manier om deze problemen op te lossen?

Ik wil niet omleiden door de browser een Locatie header te sturen, maar in plaats daarvan intern.

Addendum

secret.jsp:

<%@page contentType="text/html" pageEncoding="UTF-8" import="java.util.*"%>
<%@taglib prefix="tags" uri="/WEB-INF/tlds/tag_library.tld" %>

    hello ${requestScope.msg} 

waarin de tag wordt gebruikt wrapper.tagf :

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@tag pageEncoding="UTF-8"%>
<%@attribute name="title" required="true" type="java.lang.String" %>
<%@attribute name="menu" type="java.util.HashMap" %>


    <head>
        <link rel="stylesheet" type="text/css" href="css/reset.css"/>
        <link rel="stylesheet/less" type="text/css" href="css/default.less"/>
        <script src="js/less-1.1.5.min.js" type="text/javascript"></script>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>${pageScope.title}</title>
    </head>
    <body>
        <div id="leftMenu">menu</div>
        <div id="body">
            
        </div>
    </body>
</html>
0

1 antwoord

De forward in de servlet zorgt ervoor dat het filter 2 * 2 = 4 keer wordt geactiveerd (twee keer omdat het heen en weer gaat wanneer het verzoek binnenkomt en wanneer het antwoord wordt afgeleverd). Ik zou graag willen dat het slechts één keer wordt geactiveerd (wanneer het initiële verzoek binnenkomt) - of op zijn minst slechts twee keer.

U bent vergeten terug te keren na het doorsturen, waardoor uw filter nog steeds de aanvraag/responsketen voortzette.

rd.forward(request, response);
return;

Het aanroepen van een willekeurige Java-methode beëindigt het abrupt lopende procesblok niet abrupt en springt eruit (verwacht van System # exit() of wanneer het een uitzondering genereert natuurlijk, maar dat is een verhaal uit elkaar) .


De sessie is gestart. Ik wil niet dat de sessie wordt gestart totdat de gebruiker niet daadwerkelijk is geverifieerd (dus de JSESSIONID-cookie naar de client heeft gestuurd).

Dit wordt elders veroorzaakt dan in het filter, hoogstwaarschijnlijk door uw JSP. Voeg het volgende toe aan uw JSP om de impliciete sessie-aanmaak door JSP expliciet uit te schakelen:

<%@page session="false" %>

Maak zo nodig een HttpSessionListener en plaats een onderbrekingspunt op de methode sessionCreated() om de echte oorzaak vast te stellen.

0
toegevoegd
Dat terzijde, heeft het antwoord geholpen bij het oplossen van het probleem? Laat het me alsjeblieft als het nog steeds niet het probleem oplost.
toegevoegd de auteur BalusC, de bron
@Flavius ​​Is er een specifieke reden waarom u geen sessie wilt? Het hebben van een doet geen (of heel, heel weinig) schade. Over het algemeen is het gemakkelijker om te controleren op de aanwezigheid van een bekend sessieattribuut in de sessie dan te proberen om helemaal geen sessie te vermijden. JSP's maken een sessie tenzij u ze expliciet configureert om niet te doen.
toegevoegd de auteur Dave Newton, de bron
Gedaan zoals voorgesteld, krijg ik na het openen van "TheServlet" nog steeds een JSESSIONID samen met het aanmeldingsformulier.
toegevoegd de auteur Flavius, de bron
waarom start de jsp de sessie zonder mijn toestemming? Ik wil dat zelf beheersen.
toegevoegd de auteur Flavius, de bron
Het hebben van een sessie zonder een geverifieerde gebruiker ziet er niet goed uit. Semantisch gesproken. Trouwens, dat is een sessie die voor niets is gestart, het vervuilt gewoon de server.
toegevoegd de auteur Flavius, de bron