Spring проверка безопасности, если пользователь имеет доступ к указанному URL-адресу
Я начал использовать spring безопасность, и после многих исследований я не могу найти ответ для:
Если я явно хочу проверить, есть ли у пользователя A доступ к файлу B. Я могу проверить это с поддержкой JSP-тегов Spring Безопасность - проверить, защищен ли веб-URL/защищен like
<sec:authorize url="stuff/B">
Но что, если я хочу проверить то же самое в контроллере (класс java). Я не нахожу здесь никакой функции spring, чтобы проверить, имеет ли пользователь входа пользователя указанный URL (https://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html)
Ответы
Ответ 1
Подсказка из javadoc:
чтобы использовать этот тег, в вашем контексте приложения также должен быть экземпляр WebInvocationPrivilegeEvaluator
. Если вы используете пространство имен, оно будет автоматически зарегистрировано. Это экземпляр DefaultWebInvocationPrivilegeEvaluator
, "
И в javadoc DefaultWebInvocationPrivilegeEvaluator
мы можем видеть isAllowed
, который должен выполнить задание:
// privilegeEvaluator is a WebInvocationPrivilegeEvaluator "autowired"
boolean allowed = privilegeEvaluator.isAllowed("/stuff/B", yourAuthentication);
Ответ 2
Почему бы не использовать аннотации, подобные этому:
@PreAuthorize("hasRole('ROLE_USER')")
public void create(Contact contact);
Аннотации являются стандартными для Spring 3 +
Ответ 3
Вы смотрите на нужное место, ссылка, которую вы указали, указывает на то, что вам нужно. Поскольку вам нужен контроль доступа на вашем контроллере и проверка на пользователя (а не на роль), вы можете использовать аннотацию "@PreAuthorize" с выражением "hasPermission" или аналогичным.
Вы можете проверить здесь для управления доступом на основе выражений и здесь для примеров примера пользовательского выражения безопасности, если вы хотите настроить решение.
Ответ 4
1) Сначала нам нужно знать, может ли пользователь вводить URL-адрес вообще. Это может быть очень легко достигнуто с помощью WebInvocationPrivilegeEvaluator.
privilegeEvaluator.isAllowed(contextPath, url, "GET", currentUser);
2) Теперь нам нужно определить, может ли пользователь получить доступ к методу обработчика
private boolean isAllowedByAnnotation(Authentication currentUser, HandlerMethod method) {
PreInvocationAuthorizationAdvice advice = new ExpressionBasedPreInvocationAdvice();
PreInvocationAuthorizationAdviceVoter voter = new PreInvocationAuthorizationAdviceVoter(advice);
MethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
PrePostInvocationAttributeFactory factory = new ExpressionBasedAnnotationAttributeFactory(expressionHandler);
PrePostAnnotationSecurityMetadataSource metadataSource = new PrePostAnnotationSecurityMetadataSource(factory);
Class<?> controller = method.getBeanType();
MethodInvocation mi = MethodInvocationUtils.createFromClass(controller, method.getMethod().getName());
Collection<ConfigAttribute> attributes = metadataSource.getAttributes(method.getMethod(), controller);
return PreInvocationAuthorizationAdviceVoter.ACCESS_GRANTED == voter.vote(currentUser, mi, attributes);
}
Ответ 5
Мы можем создать пользовательский PermissionEvaluator и использовать
hasPermission (аутентификация аутентификации, объект domainObject, Разрешение объекта).
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
final DefaultMethodSecurityExpressionHandler expressionHandler =
new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(new AclPermissionEvaluator(aclService()));
return expressionHandler;
}
@Bean
public aclServiceImpl aclService() {
final AclServiceImpl mutableAclService = new AclServiceImpl
(authorizationStrategy(), grantingStrategy());
return mutableAclService;
}
AclServiceImpl - это реализация MutableAclService
Ответ 6
Наиболее очевидной полезной аннотацией является @PreAuthorize, которая решает, действительно ли метод может быть вызван или нет. Например (из примера приложения "Контакты" )
@PreAuthorize("hasRole('USER')")
public void create(Contact contact);
что означает, что доступ будет разрешен только для пользователей с ролью "ROLE_USER". Очевидно, что то же самое можно было бы легко достичь, используя традиционную конфигурацию и простой атрибут конфигурации для требуемой роли. Но как насчет:
@PreAuthorize("hasPermission(#contact, 'admin')")
public void deletePermission(Contact contact, Sid recipient, Permission permission);
Здесь фактически использовался аргумент метода как часть выражения, чтобы решить, имеет ли текущий пользователь разрешение "admin" для данного контакта. Встроенное выражение hasPermission() связано с Spring модулем ACL безопасности через контекст приложения.
Для получения более подробного пояснения обратитесь к Ссылка