Redirect führt zu seltsamen CSS-Verhalten

DaBe1812

Bekanntes Mitglied
Hallo,

ich habe eine Primefaces Anwendung. In der Firma wird ein Autologin via ADFS angeboten, welcher auch von unserer Anwendung genutzt werden soll.
Dazu gibt es auf der normalen Login-Seite einen Button zum automatisch anmelden.
Hier mal die login.xhtml:
HTML:
<h:body>
    <f:event listener="#{sessionHandler.checkLoggedIn}" type="preRenderView" />
    <p:panel id="loginBasePnl" style="background: transparent;border: 0;">
        <p:growl id="msg" showDetail="true" life="3000" />
        <p:staticMessage severity="error" summary="WARTUNGSMODUS" detail="#{aduserHandler.sperrmeldungsText}" style="width: 100%"
            rendered="#{aduserHandler.sperrmeldung}" />
        <p:panel id="loginPnl" header="Login" style="width: 400px;" rendered="#{aduserHandler.autoLoginFade}">

            <h:form id="autoLoginForm">
                <p:commandButton id="autoLoginButton" action="adfs/adfsRequest.xhtml" value="Automatisch anmelden" update="loginBasePnl"
                    style="width: 100%;margin-bottom: 20px;" rendered="#{aduserHandler.ssoActive}" />
            </h:form>

            <h:form id="loginForm">
                <h:panelGrid id="loginPanel" columns="2">

                    <h:outputText value="Username" />
                    <p:inputText id="username" value="#{aduserHandler.benutzer}"></p:inputText>
                    <p:spacer></p:spacer>
                    <p:message for="username"></p:message>

                    <h:outputText value="Password" />
                    <p:password id="password" value="#{aduserHandler.passwort}" feedback="false"></p:password>
                    <p:spacer></p:spacer>
                    <p:message for="password"></p:message>

                    <h:outputText value="Domäne" />
                    <p:inputText id="domain" value="#{aduserHandler.userdomain}"></p:inputText>
                    <p:spacer></p:spacer>
                    <p:message for="domain"></p:message>

                    <p:spacer></p:spacer>
                    <p:commandButton id="loginButton" action="#{aduserHandler.login}" value="Login" update="loginBasePnl" ajax="true"
                        style="width: 100%;" />

                </h:panelGrid>
            </h:form>

        </p:panel>
        <p:blockUI block="loginPnl" trigger="loginForm:loginButton" style="float:right;">
            <p:graphicImage value="resources/images/loader.gif" />
        </p:blockUI>
    </p:panel>
</h:body>
Wenn man sich normal anmeldet ist alles hübsch, das BlockUI wird eingeblendet, während der Code sich die Benutzergruppen vom AD holt, alles schick.

Wenn man aber auf den Autologin Button klickt, verweist das auf eine leere Seite, welche lediglich eine URL aufbaut und damit ein Redirect ans ADFS macht.
Im Browser stellt sich das aber so dar, dass für eine knappe Sekunde die Login-Seite, aber komplett ohne CSS angezeigt wird.

Jetzt steh ich ein wenig doof da, weil ich nicht weiß, wie ich dieses Verhalten unterbinden soll. Meine Versuche bisher:
  • Redirect auf der nächsten Seite erhöht auf eine Sekunde, damit er die Seite wechselt und eben eine leere Seite an zeigt --> Nächste Seite wird nicht angezeigt, Redirect funktioniert allerdings.
  • Im loginPanel habe ich ein ein Rendered eingebaut, der boolean soll beim Aufruf einer Funktion geändert werden. Problem dabei, wenn ich die Aktion auf action lasse, dann wird der Boolean in der Oberfläche nicht geändert, wenn ich einen actionListener daraus mache, dann, dann wird der Boolean geändert und alle Elemente ausgeblendet, aber der Redirect funktioniert nicht mehr, wenn ic hbeides mache, dann habe ich wieder diese CSS-lose Hässlichkeit vor mir.
Und jetzt gehen mir die Ideen aus.
 

Robert Zenz

Top Contributor
Ich wuerde mal den Netzwerkverkehr im Browser dabei ansehen. Meine Vermutung ist dass ein neuladen der Login-Seite erfolgt, und von dort wird man dann weitergeleitet. Durch die Weiterleitung wird das nachladen von Resourcen (CSS) unterbrochen und damit hat man da nicht alles geladen. Aber das muesstest du im Browser nachvollziehen was da passiert.
 

DaBe1812

Bekanntes Mitglied
Moin,
sowas kann ich leider nur an der Arbeit checken, und gerade getan. Also erstmal die gute Nachricht:
@Robert Zenz du hast es genau vorher gesagt. Ein klick auf den Butten führt erstmal zum reload der eigenen Seite. Wenn ich actionListener verwende und er somit auf der Seite bleibt, wird direkt als nächstes das CSS geladen. Wenn ich action verwende und der redirect erfolgt, dann lädt er die Seite und statt des CSS lädt er die nächste Seite, die eine Weile braucht, weil sie eben arbeitet und in der Zeit wird meine Seite ohne CSS angezeigt.
Aber die Frage bleibt, wie verhindere ich das?
 

mihe7

Top Contributor
Dein Code ist für mich etwas verwirrend: Du gibst in Zeilen 10 und 11 mit action ein XHTML-Target an, gleichzeitig willst Du etwas auf der Seite aktualisieren. Das passt irgendwo nicht zusammen. Wenn da eine Methode stünde, die ggf. null bzw. das Target (i.d.R. inkl. ?faces-redirect=true) zurückgibt (bzw. programmatisch einen Redirect durchführt), wäre das was anderes. Was soll an der Stelle denn passieren?
 

DaBe1812

Bekanntes Mitglied
Moin, ja das passiert, wenn man schon einen Tag am probieren ist und den Code nicht mehr ganz zurück gerollt hat.
Was soll passieren:
Der User klickt auf den Knopf.
Die Seite adfs/adfsRequest.xhtml wird geladen:
HTML:
<!DOCTYPE html>
<html>
    <head>
        <title>ADFS</title>
        <meta http-equiv="refresh" content="0;url=#{adfshandler.url}" />
    </head>
    <body>
    </body>
</html>
Hier hatte ich erwartet, dass eine leer Seite im Zwischenschritt ist.
Die Funktion macht nichts anders, als eine URL zum ADFS zu generieren.
Dann guckt das ADFS, ob der Benutzer vorm Browser Dinge darf und redirected wieder zurück zu meiner Seite mit dem response.
Und dieser Zwischenschritt der soll im Endeffekt einfach nur "unsichtbar" sein und nicht eine Seite anzeigen, die an Webseiten aus den 90ern erinnert.
 

mihe7

Top Contributor
Ich verstehe nicht ganz, was die Seite für einen Zweck hat. Du kannst doch direkt auf die Seite gehen, die adfshandler.url liefert.
 

Robert Zenz

Top Contributor
Ein klick auf den Butten führt erstmal zum reload der eigenen Seite. Wenn ich actionListener verwende und er somit auf der Seite bleibt, wird direkt als nächstes das CSS geladen. Wenn ich action verwende und der redirect erfolgt, dann lädt er die Seite und statt des CSS lädt er die nächste Seite, die eine Weile braucht, weil sie eben arbeitet und in der Zeit wird meine Seite ohne CSS angezeigt.

Ich kenne mich damit leider nicht so aus, aber was du eben machen musst ist dieses Neuladen unterbinden. Ich koennte es dior nur fuer planes HTML sagen wie du das machen sollst, in dem Fall bin ich leider etwas Aussen vor.
 

mihe7

Top Contributor
@Robert Zenz, bei seinem Aufruf dürfte die login-Seite überhaupt nicht direkt neu geladen werden. Der commandButton führt einen POST-Request durch. Jetzt gibts AFAIK zwei wesentliche Szenarien: einen AJAX-Request gegen eine Methode, um Teile der gleichen Seite zu aktualisieren, oder den Aufruf einer anderen Seite. Dabei gibt es wiederum zwei Möglichkeiten: a) ein interner Forward (die URL bleibt dabei bestehen) oder b) ein POST/Redirect/GET-Zyklus, der Server leitet den Browser dann auf eine neue URL um.

Es gibt jedenfalls für mich keinen ersichtlichen Sinn, sowohl ein update (Aktualisierung von Teilen der Seite) und gleichzeitig in action eine andere View zu haben. Wenn man fallweise unterscheiden möchte, ob der Anwender auf eine andere Seite geleitet werden soll, kann man das in einer Methode machen (ExternalContext#redirect).

Noch was: gibt man in action nur "adfs/adfsRequest.xhtml" an, erfolgt normalerweise ein interner Forward. Will man einen Redirect, kann man "adfs/adfsRequest.xhtml?faces-redirect=true" schreiben.

Allerdings verstehe ich nach wie vor nicht, warum man erst auf diese Seite gelangen soll, um dort per Refresh auf eine andere Seite umgeleitet zu werden. Da lasse ich mich doch von der Login-Seite aus auf die richtige URL umleiten und fertig.
 

DaBe1812

Bekanntes Mitglied
Hi,
wir gehen erst diese Woche produktiv und sind aktuell im Piloten, aber da klappt schonmal alles.
Was ich gemacht habe ist jetzt wirklich ganz einfach direkt auf dem Butten das ADFS auf zu rufen und dieses verweist dann auf eine der Folgeseiten.
Hat direkt ohne neue Konfiguration im ADFS geklappt.

Danke für eure Hilfe
 

Ähnliche Java Themen

Neue Themen


Oben