1. Обзор
В этой короткой статье мы рассмотрим модуль Spring Boot Actuator и поддержку публикации событий аутентификации и авторизации в сочетании с Spring Security.
2. Зависимости Maven
Во-первых, нам нужно добавить spring-boot-starter-actuator к вашему pom.xml:
org.springframework.boot spring-boot-starter-actuator 2.2.2.RELEASE
Последняя версия доступна в репозитории Maven Central .
3. Прослушивание событий аутентификации и авторизации
Чтобы зарегистрировать все попытки аутентификации и авторизации в приложении Spring Boot, мы можем просто определить компонент с помощью метода прослушивателя:
@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()); } }
Обратите внимание, что мы просто выводим некоторые вещи, которые доступны в Аудит события приложения , чтобы показать, какая информация доступна. В реальном приложении вы можете сохранить эту информацию в репозитории или кэше для дальнейшей обработки.
Обратите внимание, что любой Spring bean будет работать; основы поддержки новых весенних событий довольно просты:
- аннотируйте метод с помощью @EventListener
- добавьте событие Audit Application в качестве единственного аргумента метода
Результат запуска приложения будет выглядеть примерно так:
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
В этом примере три Событие s приложения аудита было получено слушателем:
- Без входа в систему был запрошен доступ к странице с ограниченным доступом
- При входе в систему был использован неправильный пароль
- Правильный пароль был использован во второй раз
4. Прослушиватель Аудита Аутентификации
Если информации, предоставленной прослушивателем аудита авторизации Spring Boot, недостаточно, вы можете создать свой собственный компонент, чтобы предоставить дополнительную информацию.
Давайте рассмотрим пример, где мы также предоставляем URL-адрес запроса, к которому был получен доступ при сбое авторизации:
@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) { Mapdata = 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)); } }
Теперь мы можем зарегистрировать URL-адрес запроса в нашем прослушивателе:
@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")); } }
В результате выходные данные теперь содержат запрошенный URL-адрес:
Principal anonymousUser - AUTHORIZATION_FAILURE Remote IP address: 0:0:0:0:0:0:0:1 Session Id: null Request URL: /hello
Обратите внимание, что в этом примере мы расширили прослушиватель аудита абстрактной абстрактной авторизации , поэтому мы можем использовать метод publish из этого базового класса в нашей реализации.
Если вы хотите протестировать его, проверьте исходный код и запустите:
mvn clean spring-boot:run
После этого вы можете указать свой браузер на http://localhost:8080/ .
5. Хранение Событий Аудита
По умолчанию Spring Boot хранит события аудита в файле AuditEventRepository . Если вы не создадите боб с собственной реализацией, то для вас будет подключен In Memory AuditEventRepository .
In Memory AuditEventRepository – это своего рода циклический буфер, в котором хранятся последние 4000 событий аудита в памяти. Затем доступ к этим событиям можно получить через конечную точку управления http://localhost:8080/auditevents .
Это возвращает представление событий аудита в формате JSON:
{ "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. Заключение
С поддержкой привода в Spring Boot становится тривиальным регистрировать попытки аутентификации и авторизации пользователей. Читатель также ссылается на аудит готовности к производству для получения дополнительной информации.
Код из этой статьи можно найти на GitHub .