In meiner Feder-Anwendung möchte ich, dass eine SecurityContext
immer eine Authentication
hält. Wenn es kein reguläres UsernamePasswordAuthenticationToken
ist, wird es ein PreAuthenticatedAuthenticationToken
sein, der den "Systembenutzer" beschreibt. Dies hat Gründe innerhalb verschiedener Systemfunktionen, die einen Benutzer erfordern. Um eine spezielle Behandlung zu vermeiden, wenn es keinen Benutzerkontext gibt, möchte ich lediglich den Systemkontext hinzufügen. IMHO, das hat auch mit dem Grundsatz der einheitlichen Verantwortung zu tun.SecurityContext mit Standard-System-Authentifizierung/Benutzer
Um dies zu erreichen, kann ich einfach meine eigenen SecurityContextHolderStrategy
und stellen Sie die es die SecurityContextHolder
mit SecurityContextHolder.setStrategyName(MyStrategyClassName);
Nun zum Problem implementieren:
Der Standard SecurityContextHolderStrategy
die ThreadLocalSecurityContextHolderStrategy
ist. Ich bin glücklich mit dieser Strategie und wie es funktioniert. Das einzige, was ich ändern würde, ist die getContext()
Methode.
public SecurityContext getContext() {
SecurityContext ctx = CONTEXT_HOLDER.get();
if (ctx == null) {
ctx = createEmptyContext();
CONTEXT_HOLDER.set(ctx);
}
return ctx;
}
zu
public SecurityContext getContext() {
SecurityContext ctx = CONTEXT_HOLDER.get();
if (ctx == null) {
ctx = createEmptyContext();
Authentication authentication = new PreAuthenticatedAuthenticationToken("system", null);
authentication.setAuthenticated(true);
ctx.setAuthentication(authentication);
CONTEXT_HOLDER.set(ctx);
}
return ctx;
}
Dies ist nicht möglich, da die ThreadLocalSecurityContextHolderStrategy
Klasse ist nicht public
. Natürlich kann ich einfach den Code der ThreadLocalSecurityContextHolderStrategy
in meine eigene SecurityContextHolderStrategy
einfügen und die getContext()
Methode so implementieren, wie ich will. Aber das gibt mir das Gefühl, als wäre ich auf dem falschen Weg.
Wie konnte ich einen "Systembenutzer" Authentication
als Standard für eine neue SecurityContext
erreichen?
aktualisieren
oben Mein Ansatz ist offenbar keine Lösung, da es extrem invasiv ist, schafft redundanten Code und benötigt spezielle Behandlung innerhalb der Web-Filterkette. Aber es sollte mein Ziel verstehen. Ich suche nach einer Lösung, die so nahtlos wie möglich in die native Spring Security Implementierung passt. Mein Problem ist, dass ich ziemlich auf den invasiven Ansatz fixiert bin. Wie kann das gut gelöst werden? Ich kann mir nicht vorstellen, dass ich die erste Person mit dieser Anforderung bin. Oder ist das ganze Konzept insgesamt falsch?
Die Zuordnung eines Authentifizierungsobjekts zum SecuruityContext für eine bestimmte Sitzung erfolgt normalerweise über die Spring-Sicherheits-HTTP-Filter. Wenn der Systembenutzer über eine Anfrage zugreift, versuchen Sie möglicherweise einen zusätzlichen Authentifizierungsfilter, der das Authentifizierungsobjekt entsprechend konfiguriert. Wenn nicht (programmatisch usw.), wäre es viel sauberer, in Refactoring-Verwendungen zu schauen, wo Sie die secruityContext.getAuthenitiation() verwenden und sich mit der Abwesenheit in der Anwendungslogik befassen, anstatt zu versuchen, das Auth-Framework-Verhalten zu massieren. – tom01
Das Problem ist, dass ich Aufgaben geplant habe. Diese geplante Aufgabe wird keine 'HttpSecurity' übergeben, da sie intern ausgeführt werden. Auch die 'InheritableThreadLocalSecurityContextHolderStrategy' wird es nicht tun, da eine geplante Aufgabe vom System direkt nach einem Neustart instanziiert werden kann. –
Stellen Sie sich auch einen anfänglichen Systemstart vor, bei dem einige Standardbenutzerdatensätze erstellt werden. Dies sollte auch mit einem Sicherheitskontext für Systembenutzer geschehen. –