Как разрешить любую другую роль в весенней безопасности?

#xml #spring #spring-security

Вопрос:

Как бы вы сделали выражение, чтобы разрешить доступ ко всем ролям, кроме одной, без объявления их всех в spring-security.xml?

У нас есть четыре роли: private , user1 , user2 и user3 . private это единственная роль, которая может выполнять определенные службы. Другим разрешается только user1 , user2 и user3 .

 <http pattern="/priv/**">
    <intercept-url pattern="/**" access="hasRole('private')"/>
    <http-basic/>
</http>

<http pattern="/pub/**">
    <intercept-url pattern="/**" access="!hasRole('private')"/>
    <http-basic/>
</http>
 

Я знаю, что при этом проблема была бы решена, но в случае пользователя, имеющего private , user2 например, и, этот пользователь должен выполнить /priv/ /pub/ операцию и. Как можно настроить xml-файл?
Если у пользователя есть две роли ( private и еще одна из других), будут разрешены обе операции.

Ответ №1:

Вы можете использовать RoleHierarchy это для упрощения настройки безопасности.

 <bean id="roleVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter">
    <constructor-arg ref="roleHierarchy" />
</bean>
<bean id="roleHierarchy"
        class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
    <property name="hierarchy">
        <value>
            ROLE_PRIVATE > ROLE_USER
            ROLE_USER > ROLE_USER1 > ROLE_USER2 > ROLE_USER3
        </value>
    </property>
</bean>
 

А затем в вашей http конфигурации:

 <http pattern="/priv/**">
            <intercept-url pattern="/**" access="hasRole('PRIVATE')"/>
            <http-basic/>
 </http>

<http pattern="/pub/**">
            <intercept-url pattern="/**" access="hasRole('USER')"/>
            <http-basic/>
 </http>
 

Таким образом, вы ROLE_USER «встроите» все остальные ROLE_USERX правила и ROLE_PRIVATE встроите все из ROLE_USER них .

Вам также следует обратиться к справочнику по безопасности Spring.

Комментарии:

1. Но дело в следующем: у меня могут быть новые различные разрешения, и все они, кроме частных, могут выполнять /pub/**. Я нахожу способ добавить новые разрешения и присоединиться к /pub без изменения spring-secutiry.xml избегая развертываний при каждом добавлении роли

2. Почему вы добавляете новую роль без другого доступа к управлению?

3. Поскольку единственная роль, которая не может получить доступ к /pub/, будет только «ЧАСТНОЙ», доступ будут иметь остальные, фактические и будущие роли. Кроме того, пользователь с частной и другой ролью должен получить доступ /паб/

Ответ №2:

Вы можете реализовать расширение WebSecurityExpressionRoot с помощью метода boolean hasAnyRoleExcept(String... ignoredRoles)


эскиз (написан без поддержки IDE):

 import org.springframework.security.core.authority.AuthorityUtils;

public class MyWebSecurityExpressionRoot extends WebSecurityExpressionRoot {

   public MyWebSecurityExpressionRoot(final Authentication a, final FilterInvocation fi) {
      super(a, fi);
   }

   public boolean hasAnyRoleExcept(String... ignoredRoles) {
        //see SecurityExpressionRoot.hasAnyRole
        Set<String> roles = 
            AuthorityUtils.authorityListToSet(
               getAuthentication().getAuthorities());

        //find a not ignored role
        for (String role : roles) {
            if (!ignoredRoles.contains(role)) {
                return true;
            }
        }

        return false;
   }
}
 

Чтобы зарегистрировать его:

 public class MyWebSecurityExpressionHandler extends DefaultWebSecurityExpressionHandler {

    //Attention: override setTrustResolver too.
    private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();

    @Override
    protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) {
        MyWebSecurityExpressionRoot root = new MyWebSecurityExpressionRoot(authentication, fi);
        root.setPermissionEvaluator(getPermissionEvaluator());
        root.setTrustResolver(trustResolver);
        root.setRoleHierarchy(getRoleHierarchy());
        return root;
    }
}
 
 <security:http use-expressions="true" ...>
    ...

    <security:expression-handler ref="myWebSecurityExpressionHandler"/>

    <security:intercept-url pattern="/**" access="hasAnyRoleExcept('private')"/>
</security:http>

<bean id="myWebSecurityExpressionHandler" class="MyWebSecurityExpressionHandler"/>