Unterstützung der Spring Boot-Authentifizierungsprüfung
1. Überblick
In diesem kurzen Artikel werden das Spring Boot Actuator-Modul und die Unterstützung für das Veröffentlichen von Authentifizierungs- und Autorisierungsereignissen in Verbindung mit Spring Security erläutert.
2. Maven-Abhängigkeiten
Zuerst müssen wir diespring-boot-starter-actuator zu unserenpom.xml: hinzufügen
org.springframework.boot
spring-boot-starter-actuator
2.1.7.RELEASE
Die neueste Version ist im Repository vonMaven Centralverfügbar.
3. Abhören von Authentifizierungs- und Autorisierungsereignissen
Um alle Authentifizierungs- und Autorisierungsversuche in einer Spring Boot-Anwendung zu protokollieren, können Sie einfach eine Bean mit einer Listener-Methode definieren:
@Component
public class LoginAttemptsLogger {
@EventListener
public void auditEventHappened(
AuditApplicationEvent auditApplicationEvent) {
AuditEvent auditEvent = auditApplicationEvent.getAuditEvent();
System.out.println("Principal " + auditEvent.getPrincipal()
+ " - " + auditEvent.getType());
WebAuthenticationDetails details =
(WebAuthenticationDetails) auditEvent.getData().get("details");
System.out.println("Remote IP address: "
+ details.getRemoteAddress());
System.out.println(" Session Id: " + details.getSessionId());
}
}
Beachten Sie, dass wir nur einige der inAuditApplicationEvent verfügbaren Elemente ausgeben, um anzuzeigen, welche Informationen verfügbar sind. In einer tatsächlichen Anwendung möchten Sie diese Informationen möglicherweise in einem Repository oder Cache speichern, um sie weiter zu verarbeiten.
Beachten Sie, dass jede Springbohne funktioniert. Die Grundlagen der neuen Spring-Event-Unterstützung sind ganz einfach:
-
Kommentieren Sie die Methode mit@EventListener
-
Fügen SieAuditApplicationEvent als einziges Argument der Methode hinzu
Die Ausgabe der Anwendung sieht ungefähr so aus:
Principal anonymousUser - AUTHORIZATION_FAILURE Remote IP address: 0:0:0:0:0:0:0:1 Session Id: null Principal user - AUTHENTICATION_FAILURE Remote IP address: 0:0:0:0:0:0:0:1 Session Id: BD41692232875A5A65C5E35E63D784F6 Principal user - AUTHENTICATION_SUCCESS Remote IP address: 0:0:0:0:0:0:0:1 Session Id: BD41692232875A5A65C5E35E63D784F6
In diesem Beispiel wurden dreiAuditApplicationEvents vom Listener empfangen:
-
Ohne Anmeldung wurde der Zugriff auf eine eingeschränkte Seite angefordert
-
Beim Anmelden wurde ein falsches Passwort verwendet
-
Beim zweiten Mal wurde ein korrektes Passwort verwendet
4. Ein Authentication Audit Listener
Wenn die vonAuthorizationAuditListener von Spring Boot bereitgestellten Informationen nicht ausreichen, können Siecreate your own bean to expose more information. verwenden
Schauen wir uns ein Beispiel an, in dem wir auch die Anforderungs-URL offenlegen, auf die zugegriffen wurde, als die Autorisierung fehlschlug:
@Component
public class ExposeAttemptedPathAuthorizationAuditListener
extends AbstractAuthorizationAuditListener {
public static final String AUTHORIZATION_FAILURE
= "AUTHORIZATION_FAILURE";
@Override
public void onApplicationEvent(AbstractAuthorizationEvent event) {
if (event instanceof AuthorizationFailureEvent) {
onAuthorizationFailureEvent((AuthorizationFailureEvent) event);
}
}
private void onAuthorizationFailureEvent(
AuthorizationFailureEvent event) {
Map data = new HashMap<>();
data.put(
"type", event.getAccessDeniedException().getClass().getName());
data.put("message", event.getAccessDeniedException().getMessage());
data.put(
"requestUrl", ((FilterInvocation)event.getSource()).getRequestUrl() );
if (event.getAuthentication().getDetails() != null) {
data.put("details",
event.getAuthentication().getDetails());
}
publish(new AuditEvent(event.getAuthentication().getName(),
AUTHORIZATION_FAILURE, data));
}
}
Wir können jetzt die Anforderungs-URL in unserem Listener protokollieren:
@Component
public class LoginAttemptsLogger {
@EventListener
public void auditEventHappened(
AuditApplicationEvent auditApplicationEvent) {
AuditEvent auditEvent = auditApplicationEvent.getAuditEvent();
System.out.println("Principal " + auditEvent.getPrincipal()
+ " - " + auditEvent.getType());
WebAuthenticationDetails details
= (WebAuthenticationDetails) auditEvent.getData().get("details");
System.out.println(" Remote IP address: "
+ details.getRemoteAddress());
System.out.println(" Session Id: " + details.getSessionId());
System.out.println(" Request URL: "
+ auditEvent.getData().get("requestUrl"));
}
}
Folglich enthält die Ausgabe jetzt die angeforderte URL:
Principal anonymousUser - AUTHORIZATION_FAILURE Remote IP address: 0:0:0:0:0:0:0:1 Session Id: null Request URL: /hello
Beachten Sie, dass wir in diesem Beispiel das abstrakteAbstractAuthorizationAuditListener erweitert haben, damit wir in unserer Implementierung diepublish-Methode dieser Basisklasse verwenden können.
Wenn Sie es testen möchten, überprüfen Sie den Quellcode und führen Sie Folgendes aus:
mvn clean spring-boot:run
Danach können Sie Ihren Browser aufhttp://localhost:8080/
richten.
5. Speichern von Überwachungsereignissen
Standardmäßig speichert Spring Boot die Überwachungsereignisse inAuditEventRepository. Wenn Sie keine Bean mit einer eigenen Implementierung erstellen, wird einInMemoryAuditEventRepository für Sie verkabelt.
InMemoryAuditEventRepository ist eine Art Umlaufpuffer, in dem die letzten 4000 Überwachungsereignisse gespeichert werden. Auf diese Ereignisse kann dann über den Verwaltungsendpunkthttp://localhost:8080/auditevents
zugegriffen werden.
Dies gibt eine JSON-Darstellung der Überwachungsereignisse zurück:
{
"events": [
{
"timestamp": "2017-03-09T19:21:59+0000",
"principal": "anonymousUser",
"type": "AUTHORIZATION_FAILURE",
"data": {
"requestUrl": "/auditevents",
"details": {
"remoteAddress": "0:0:0:0:0:0:0:1",
"sessionId": null
},
"type": "org.springframework.security.access.AccessDeniedException",
"message": "Access is denied"
}
},
{
"timestamp": "2017-03-09T19:22:00+0000",
"principal": "anonymousUser",
"type": "AUTHORIZATION_FAILURE",
"data": {
"requestUrl": "/favicon.ico",
"details": {
"remoteAddress": "0:0:0:0:0:0:0:1",
"sessionId": "18FA15865F80760521BBB736D3036901"
},
"type": "org.springframework.security.access.AccessDeniedException",
"message": "Access is denied"
}
},
{
"timestamp": "2017-03-09T19:22:03+0000",
"principal": "user",
"type": "AUTHENTICATION_SUCCESS",
"data": {
"details": {
"remoteAddress": "0:0:0:0:0:0:0:1",
"sessionId": "18FA15865F80760521BBB736D3036901"
}
}
}
]
}
6. Fazit
Mit der Aktorunterstützung in Spring Boot wird es einfach, die Authentifizierungs- und Autorisierungsversuche von Benutzern zu protokollieren. Der Leser wird für einige zusätzliche Informationen auch aufproduction ready auditing verwiesen.
Der Code aus diesem Artikel istover on GitHub.