Как проверить «hasRole» в коде Java с помощью Spring Security? - PullRequest
110 голосов
/ 11 июня 2010

Как проверить полномочия пользователя или разрешение в Java Code? Например - я хочу показать или скрыть кнопку для пользователя в зависимости от роли. Есть аннотации типа:

@PreAuthorize("hasRole('ROLE_USER')")

Как сделать это в коде Java? Что-то вроде:

if(somethingHere.hasRole("ROLE_MANAGER")) {
   layout.addComponent(new Button("Edit users"));
}

Ответы [ 16 ]

2 голосов
/ 08 декабря 2014

Лучший ответ @gouki!

Просто подсказка о том, как весна действительно делает это.

Существует класс с именем SecurityContextHolderAwareRequestWrapper, который реализует класс ServletRequestWrapper.

SecurityContextHolderAwareRequestWrapper переопределяет isUserInRole и выполняет поиск пользователя Authentication (которым управляет Spring), чтобы определить, есть ли у пользователя роль или нет.

SecurityContextHolderAwareRequestWrapper кодкак:

    @Override
    public boolean isUserInRole(String role) {
        return isGranted(role);
    }

 private boolean isGranted(String role) {
        Authentication auth = getAuthentication();

        if( rolePrefix != null ) {
            role = rolePrefix + role;
        }

        if ((auth == null) || (auth.getPrincipal() == null)) {
            return false;
        }

        Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();

        if (authorities == null) {
            return false;
        }

        //This is the loop which do actual search
        for (GrantedAuthority grantedAuthority : authorities) {
            if (role.equals(grantedAuthority.getAuthority())) {
                return true;
            }
        }

        return false;
    }
2 голосов
/ 22 сентября 2010

Лучше поздно, чем никогда, позвольте мне положить свои 2 цента.

В мире JSF, в рамках моего управляемого компонента, я сделал следующее:


HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
SecurityContextHolderAwareRequestWrapper sc = new SecurityContextHolderAwareRequestWrapper(req, "");

Как упоминалось вышеНасколько я понимаю, это можно сделать длинным путем следующим образом:


Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserDetails userDetails = null;
if (principal instanceof UserDetails) {
    userDetails = (UserDetails) principal;
    Collection  authorities = userDetails.getAuthorities();
}
2 голосов
/ 11 июня 2010

Как ни странно, я не думаю, что есть стандартное решение этой проблемы, поскольку контроль доступа spring-security основан на выражениях , а не на Java. Вы можете проверить исходный код для DefaultMethodSecurityExpressionHandler , чтобы посмотреть, сможете ли вы повторно использовать то, что они там делают

1 голос
/ 25 августа 2016

В нашем проекте мы используем иерархию ролей, в то время как большинство приведенных выше ответов нацелены только на проверку конкретной роли, т. Е. Будут проверять только определенную роль, но не на эту роль и не повышать иерархию.

Решение для этого:

@Component
public class SpringRoleEvaluator {

@Resource(name="roleHierarchy")
private RoleHierarchy roleHierarchy;

public boolean hasRole(String role) {
    UserDetails dt = AuthenticationUtils.getSessionUserDetails();

    for (GrantedAuthority auth: roleHierarchy.getReachableGrantedAuthorities(dt.getAuthorities())) {
        if (auth.toString().equals("ROLE_"+role)) {
            return true;
        }
    }
    return false;
}

RoleHierarchy определяется как bean-компонент в spring-security.xml.

1 голос
/ 03 июня 2014

Это что-то вроде вопроса с другого конца, но я подумал, что я его добавлю, потому что мне действительно пришлось копать в Интернете, чтобы это выяснить.

Есть много вещей о том, как проверять роли, но мало что говорит о том, что вы на самом деле проверяете, когда говорите hasRole ("бла")

HasRole проверяет предоставленные полномочия для аутентифицированного в настоящее время принципала

Так что на самом деле, когда вы видите hasRole ("бла") действительно означает hasAuthority ("бла") .

В случае, который я видел, вы делаете это с классом, который реализует UserDetails, который определяет метод с именем getAuthorities. В этом вы в основном добавите немного new SimpleGrantedAuthority("some name") в список, основанный на некоторой логике. Имена в этом списке - это вещи, проверенные операторами hasRole.

Я предполагаю, что в этом контексте объект UserDetails является в настоящее время аутентифицированным принципалом. Есть некоторая магия, которая происходит внутри и вокруг провайдеров аутентификации и, в частности, менеджера аутентификации, который делает это возможным.

0 голосов
/ 19 июня 2018

Мой подход с помощью Java8, Передача разделенных комой ролей даст вам истину или ложь

    public static Boolean hasAnyPermission(String permissions){
    Boolean result = false;
    if(permissions != null && !permissions.isEmpty()){
        String[] rolesArray = permissions.split(",");
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        for (String role : rolesArray) {
            boolean hasUserRole = authentication.getAuthorities().stream().anyMatch(r -> r.getAuthority().equals(role));
            if (hasUserRole) {
                result = true;
                break;
            }
        }
    }
    return result;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...