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 безопасности через контекст приложения.

Для получения более подробного пояснения обратитесь к Ссылка