2014-03-13 12 views
5

Ich benutze Feder Sicherheit v3.1.4. Was ich erreichen möchte ist, dass ein Administrator in der Lage ist, einen normalen Benutzer auszuloggen (seine Sitzung ungültig zu machen). Ein Benutzer kann sich nur einmal zu einem bestimmten Zeitpunkt anmelden, aber wenn er es vergisst, sich abzumelden, kann er sich nicht einloggen, wenn er versucht, sich von einem anderen Ort aus einzuloggen Der Administrator und der Administrator werden alle zuvor eingeloggten Sitzungen für ungültig erklären (hoffentlich gibt es nur einen).Wie programmiere ich einen Benutzer programmgesteuert mit Feder Sicherheit

in meiner web.xml habe ich folgendes definiert.

<listener> 
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> 
</listener> 

in meinem Frühling Sicherheit xml habe ich die folgenden definiert.

<session-management invalid-session-url="/home"> 
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" session-registry-ref="sessionRegistry"/> 
</session-management> 
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/> 

Ich habe dann einen Rest-ähnlichen Controller, um die Abmeldung durchzuführen.

@Controller 
@RequestMapping("/api/admin") 
public class RestAdminController { 
static final Set<SimpleGrantedAuthority> AUTHS = new HashSet<>(); 
static { 
    AUTHS.add(new SimpleGrantedAuthority("ROLE_USER")); 
} 

@Autowired 
private SessionRegistry sessionRegistry; 

@RequestMapping("/user/logout"); 
public @ResponseBody String logout(@RequestBody Account account) { 
    User user = new User(account.getUsername(), "", AUTHS); 
    List<SessionInformation> infos = sessionRegistry.getAllSessions(u, false); 

    for(SessionInformation info : infos) { 
    info.expireNow(); //expire the session 
    sessionRegistry.removeSessionInformation(info.getSessionId()); //remove session 
    } 

    return "ok"; 
} 
} 

Dieser Code "irgendwie" funktioniert, wenn ich es vom selben Computer aus teste. Nehmen wir an, wir haben einen Benutzer, USER_A, und einen Administrator, ADMIN_A.

  • USER_A verwendet Chrome, um sich bei der APP anzumelden.
  • USER_A verwendet firefox, um sich bei der APP anzumelden. Er wird abgelehnt, da ein Benutzer jeweils nur eine Anmeldesitzung haben kann.
  • ADMIN_A geht hinein und ruft den Rest-ähnlichen Dienst (Code oben) auf, um alle Sitzungen von USER_A "rauszuschmeißen".
  • USER_A kann jetzt firefox verwenden, um sich bei der APP anzumelden.
  • Allerdings ist USER_A jetzt doppelt angemeldet, einmal in Chrome und einmal in Firefox.

  • das Aktualisieren der (mit Spring-Sicherheit geschützten) Seiten für USER_A in Chrome (erstes Anmelden) erzwingt keine Umleitung (zur Anmeldeseite).
  • Aktualisierung der geschützten Seiten für USER_A in Firefox (zweite Anmeldung) zwingt ihn auch nicht umgeleitet werden.

eine Idee, auf Ansätze auf, wie die USER_A erste/vorherige Login-Sessions so vollständig entkräften/zerstören, wenn er feder geschützte Seiten zuzugreifen versucht wird Sicherheit wissen, „hey diese Sitzung Kerl ungültig oder abgelaufen ist, schicken Sie ihn an die Login-Seite "?

jede Hilfe wird geschätzt. Vielen Dank.

Antwort

10

Es sieht so aus, als ob Sie es fast haben, aber ich denke das Problem ist, dass Sie die Informationen vorzeitig aus dem SessionRegistry entfernen. Die führt eine Überprüfung der aktuellen Sitzung durch, wenn ein Benutzer eine Anforderung stellt. An diesem Punkt meldet er eine abgelaufene Sitzung ab und macht sie ungültig. Da Sie die Informationen für diese Sitzung bereits gelöscht haben, wird sie nicht gefunden und wird auch nichts tun.

Versuchen Sie, die Linie zu entfernen:

sessionRegistry.removeSessionInformation(info.getSessionId()); 
+0

danke, entfernt diese Zeile sicherlich entfernt diesen Nebeneffekt.Wenn ich die springgeschützte Seite aktualisiere, erhalte ich folgende Meldung: "Diese Sitzung ist abgelaufen (möglicherweise weil mehrere gleichzeitige Anmeldungen als derselbe Benutzer versucht wurden)." Die Umleitung ist korrekt, sie leitet nach/home um, aber anstatt den Inhalt von/home anzuzeigen, zeigt sie diese Nachricht an, die ich dann aktualisieren muss, um den richtigen Inhalt anzuzeigen. Woher kommt diese Nachricht? sieht nicht so aus, als wäre es der JEE-Container. und wie kann ich es anpassen? –

+0

ok, SO hat bereits eine Antwort auf meine Follow-up. Sie können die expired-URL in der Steuerung des gemeinsamen Zugriffs steuern. –

+0

Rechts. Der [Namespace-Anhang] (http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#nsa-concurrency-control) ist ein guter Ort, um nach einer Konfiguration zu suchen Attribute. Außerdem werden sie in einem anständigen XML-Editor angezeigt. –

Verwandte Themen