«1. Обзор
В этом руководстве мы покажем, как использовать аутентификацию Run-As в Spring Security с помощью простого сценария.
Объяснение Run-As на очень высоком уровне выглядит следующим образом: пользователь может выполнять некоторую часть логики от имени другого принципала с другими привилегиями.
2. RunAsManager
Первое, что нам нужно сделать, это настроить GlobalMethodSecurity и внедрить RunAsManager.
Это отвечает за предоставление временному объекту Authentication дополнительных привилегий:
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected RunAsManager runAsManager() {
RunAsManagerImpl runAsManager = new RunAsManagerImpl();
runAsManager.setKey("MyRunAsKey");
return runAsManager;
}
}
Переопределяя runAsManager, мы заменяем реализацию по умолчанию в базовом классе, которая просто возвращает null.
Также обратите внимание на свойство ключа — фреймворк использует его для защиты/проверки временных объектов аутентификации (созданных с помощью этого менеджера).
Наконец, результирующий объект Authentication представляет собой RunAsUserToken.
3. Конфигурация безопасности
Чтобы аутентифицировать наш временный объект Authentication, мы настроим RunAsImplAuthenticationProvider:
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
...
auth.authenticationProvider(runAsAuthenticationProvider());
}
@Bean
public AuthenticationProvider runAsAuthenticationProvider() {
RunAsImplAuthenticationProvider authProvider = new RunAsImplAuthenticationProvider();
authProvider.setKey("MyRunAsKey");
return authProvider;
}
Мы, конечно, настроим его с тем же ключом, который мы использовали в менеджере — \», чтобы провайдер мог проверить, что объект аутентификации RunAsUserToken создан с использованием того же ключа.
4. Контроллер с @Secured
Теперь давайте посмотрим, как использовать замену аутентификации запуска от имени:
@Controller
@RequestMapping("/runas")
class RunAsController {
@Secured({ "ROLE_USER", "RUN_AS_REPORTER" })
@RequestMapping
@ResponseBody
public String tryRunAs() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
return "Current User Authorities inside this RunAS method only " +
auth.getAuthorities().toString();
}
}
Ключевым моментом здесь является новая роль – RUN_AS_REPORTER. Это триггер функции запуска от имени, поскольку фреймворк обрабатывает ее по-разному из-за префикса.
Когда запрос выполняется с помощью этой логики, у нас будет:
-
Текущие права пользователя перед методом tryRunAs(): [ROLE_USER] Текущие права пользователя внутри метода tryRunAs(): [ROLE_USER, ROLE_RUN_AS_REPORTER] Временная аутентификация объект заменяет существующий объект Authentication только на время вызова метода tryRunAS()
5. Служба
Наконец, давайте реализуем реальную логику — простой уровень службы, который также защищен:
@Service
public class RunAsService {
@Secured({ "ROLE_RUN_AS_REPORTER" })
public Authentication getCurrentUser() {
Authentication authentication =
SecurityContextHolder.getContext().getAuthentication();
return authentication;
}
}
~~ ~ Обратите внимание, что:
-
Чтобы получить доступ к методу getCurrentUser(), нам нужно ROLE_RUN_AS_REPORTER Таким образом, мы можем вызывать метод getCurrentUser() только внутри нашего метода контроллера tryRunAs()
6. Внешний интерфейс
Далее мы используйте простой внешний интерфейс для тестирования нашей функции запуска от имени:
<html>
<body>
Current user authorities:
<span sec:authentication="principal.authorities">user</span>
<br/>
<span id="temp"></span>
<a href="#" onclick="tryRunAs()">Generate Report As Super User</a>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript">
function tryRunAs(){
$.get( "/runas" , function( data ) {
$("#temp").html(data);
});
}
</script>
</body>
</html>
Итак, теперь, когда пользователь инициирует действие «Создать отчет как суперпользователь», он получит временные полномочия ROLE_RUN_AS_REPORTER.
7. Заключение
В этом кратком руководстве мы рассмотрели простой пример использования функции замены аутентификации Spring Security Run-As.
Это руководство основано на кодовой базе, доступной на GitHub.