1. Обзор
В этом руководстве мы покажем, как использовать аутентификацию Run-As в Spring Security с помощью простого сценария.
Объяснение запуска от имени на очень высоком уровне выглядит следующим образом: пользователь может выполнять некоторую часть логики от имени другого принципала с другими привилегиями.
2. Менеджер запуска от имени
Первое, что нам нужно сделать, это настроить GlobalMethodSecurity
и внедрить RunAsManager
.
Это отвечает за предоставление временному объекту аутентификации
дополнительных привилегий:
@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
Теперь давайте посмотрим, как использовать замену аутентификации Run-As:
@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
заменяет существующий объект 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 .