spring-security: авторизация без аутентификации

authentication session authorization spring-security

29192 просмотра

7 ответа

Я пытаюсь интегрировать Spring Security в свое веб-приложение. Это кажется довольно простым, если вы интегрируете весь процесс аутентификации и авторизации.

Тем не менее, как аутентификация, так и авторизация кажутся настолько связанными, что мне требуется очень много времени, чтобы понять, как я могу разделить эти процессы, и получить аутентификацию независимо от авторизации.

Процесс аутентификации является внешним для нашей системы (на основе единого входа), и его нельзя изменить. Тем не менее, как только пользователь успешно завершает этот процесс, он загружается в сеанс, включая роли.

То, чего мы пытаемся достичь, - это использовать эту информацию для процесса авторизации Spring Security, то есть заставить его получать роли из пользовательского сеанса, а не получать его через провайдера аутентификации.

Есть ли способ добиться этого?

Автор: markitus82 Источник Размещён: 09.06.2019 12:11

Ответы (7)


22 плюса

Решение

Если ваша аутентификация уже выполнена с использованием службы единого входа, вам следует использовать один из фильтров предварительной аутентификации Spring Security . Затем вы можете указать сервис UserDetails (возможно, пользовательский), который будет использовать предварительно аутентифицированный пользовательский принцип для заполнения GrantedAuthority

SpringSecurity включает в себя несколько фильтров предварительной аутентификации, включая J2eePreAuthenticatedProcessingFilter и RequestHeaderPreAuthenticatedProcessingFilter. Если вы не можете найти тот, который работает для вас, его также можно и не так сложно написать самостоятельно, при условии, что вы знаете, где в запросе ваша реализация SSO заполняет данные. (Это зависит от реализации, конечно.)

Просто реализуйте интерфейс Filter и сделайте что-то подобное в методе doFilter:

public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

    // principal is set in here as a header or parameter. you need to find out 
    // what it's named to extract it
    HttpServletRequest req = (HttpServletRequest) request; 

    if (SecurityContextHolder.getContext().getAuthentication() == null) {
        // in here, get your principal, and populate the auth object with 
        // the right authorities
        Authentication auth = doAuthentication(req); 
        SecurityContextHolder.getContext().setAuthentication(auth);
    }

    chain.doFilter(request, response);
}
Автор: nont Размещён: 24.08.2009 03:35

3 плюса

Да, это возможно. Spring Security (как и большинство остальной части Spring) управляется интерфейсом, так что вы можете выборочно подключать свои собственные реализации для различных частей инфраструктуры.

Обновление: механизмы авторизации и аутентификации Spring работают вместе - механизм аутентификации будет аутентифицировать пользователя и вставлять различные GrantedAuthorityэкземпляры в контекст безопасности. Затем они будут проверены механизмом авторизации, чтобы разрешить / запретить определенные операции.

Используйте ответ не для деталей о том, как использовать ранее существующую аутентификацию. Детали того, как вы получаете детали из вашей сессии (например, роли), конечно, будут зависеть от вашей конкретной настройки. Но если вы добавите GrantedAuthorityэкземпляры, полученные из ролей, предварительно заполненных в вашем сеансе вашей системой единого входа, вы сможете использовать их в логике авторизации.

Из справочной документации (слегка отредактировано, с моим акцентом):

Вы можете (и многие пользователи делают) писать свои собственные фильтры или контроллеры MVC для обеспечения взаимодействия с системами аутентификации, которые не основаны на Spring Security. Например, вы можете использовать управляемую контейнером аутентификацию, которая делает текущего пользователя доступным из местоположения ThreadLocalили JNDI. Или вы можете работать в компании, которая имеет устаревшую проприетарную систему аутентификации, которая является корпоративным «стандартом», над которым у вас мало контроля. В таких ситуациях довольно просто заставить Spring Security работать и при этом предоставлять возможности авторизации. Все, что вам нужно сделать, это написать фильтр (или эквивалентный), который считывает информацию о сторонних пользователях из местоположения, построить специфичный для Spring Security Authentication объект и поместить его в SecurityContextHolder, Это довольно легко сделать, и это полностью поддерживаемый подход к интеграции.

Автор: Vinay Sajip Размещён: 24.08.2009 01:08

2 плюса

Сервер, который обрабатывает аутентификацию, должен перенаправить пользователя к приложению, передав ему какой-то ключ (токен в CAS SSO). Затем приложение использует ключ для запроса к серверу аутентификации имени пользователя и связанных ролей. С помощью этой информации создайте контекст безопасности, который передается менеджеру авторизации. Это очень упрощенная версия рабочего процесса входа в систему единого входа.
Взгляните на CAS SSO и CAS 2 Architecture .
Скажите, если вам нужна дополнительная информация.

Автор: rodrigoap Размещён: 24.08.2009 02:58

1 плюс

у нас было такое же требование, когда мы должны были использовать пружинную защиту только для авторизации. Мы использовали Siteminder для аутентификации. Вы можете найти более подробную информацию о том, как использовать часть авторизации Spring Security, а не аутентификацию, здесь по адресу http://codersatwork.wordpress.com/2010/02/13/use-spring-security-for-authorization-only-not-for- аутентификация/

Я также добавил исходный код и контрольные примеры по адресу http://code.google.com/p/spring-security-with-authorization-only/source/browse/

Автор: Saurabh Размещён: 17.02.2010 05:07

1 плюс

Я пытаюсь понять аутентификацию CAS с нашей собственной авторизацией, и меня это сбивает с толку, поскольку объект User в Spring Security всегда ожидает, что пароль будет заполнен, и в нашем сценарии нас это не волнует. После прочтения поста Сураба кажется, что хитрость заключается в том, чтобы вернуть пользовательский объект User без введенного пароля. Я попробую это и посмотрю, работает ли он в моем случае. Надеемся, что никакой другой код в цепочке не будет ожидать пароль в объекте User.

Автор: SinusRhythm Размещён: 18.02.2010 04:36

1 плюс

Я использую авторизацию по этому:

  1. Вставьте компонент, связанный с авторизацией, в мой собственный компонент:

    @Autowired
    private AccessDecisionManager    accessDecisionManager;
    @Autowired
    FilterSecurityInterceptor        filterSecurityInterceptor;
    
  2. Используйте этот компонент следующим образом:

    FilterInvocation fi = new FilterInvocation(rundata.getRequest(), rundata.getResponse(), new FilterChain() {
    
        public void doFilter(ServletRequest arg0, ServletResponse arg1) throws IOException, ServletException {
            // TODO Auto-generated method stub
    
        }
    });
    FilterInvocationDefinitionSource objectDefinitionSource = filterSecurityInterceptor.getObjectDefinitionSource();
    ConfigAttributeDefinition attr = objectDefinitionSource.getAttributes(fi);
    Authentication authenticated = new Authentication() {
    
        ...........
    
        public GrantedAuthority[] getAuthorities() {
            GrantedAuthority[] result = new GrantedAuthority[1];
            result[0] = new GrantedAuthorityImpl("ROLE_USER");
            return result;
        }
    };
    accessDecisionManager.decide(authenticated, fi, attr);
    
Автор: Aimar Размещён: 16.09.2011 12:06

0 плюса

Я тоже потратил много часов на изучение того, как реализовать пользовательскую авторизацию без аутентификации.
Процесс аутентификации является внешним для нашей системы (на основе единого входа). Я сделал это, как указано ниже, и это работает !!! (Я уверен, что есть много других способов сделать это лучше, но этот способ достаточно хорошо подходит для моего сценария)

Сценарий: пользователь уже аутентифицирован во внешней системе, и вся информация, необходимая для авторизации, присутствует в запросе

1. Необходимо создать конфигурацию безопасности, включив глобальный метод безопасности, как показано ниже.

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
class SpringWebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
    }
}

2.) Внедрите Spring PermissionEvaluator, чтобы разрешить, следует ли разрешить или отклонить запрос

@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {

    public boolean authorize(final String groups, final String role) {
        boolean allowed = false;
        System.out.println("Authorizing: " + groups + "...");
        if (groups.contains(role)) {
            allowed = true;
            System.out.println(" authorized!");
        }
        return allowed;
    };

    @Override
    public boolean hasPermission(final Authentication authentication, final Object groups, final Object role) {
        return authorize((String) groups, (String) role);
    };

    @Override
    public boolean hasPermission(final Authentication authentication, final Serializable targetId, final String targetType, final Object permission) {
        return authorize((String) targetId, (String) permission);
    };
}

3.) Добавить MethodSecurityConfig

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator());
        return expressionHandler;
    }
}

4.) Добавьте @PreAuthorize в свой контроллер, как показано ниже. В этом примере все группы пользователей присутствуют в заголовке запроса с ключом «availableUserGroups». Затем он передается в CustomPermissionEvaluator для проверки авторизации. Обратите внимание, что spring автоматически передает объект аутентификации в метод hasPermission. Так что, если вы хотите загрузить пользователя и проверить с помощью метода пружины hasRole, то это можно использовать.

@PreAuthorize("hasPermission(#userGroups, 'ADMIN')")
@RequestMapping(value = "/getSomething")
public String getSomething(@RequestHeader(name = "availableUserGroups") final String userGroups) {
    return "resource allowed to access";
}

Обработка других сценариев: 1.) В сценарии, в котором вы хотите загрузить пользователя, прежде чем сможете выполнить авторизацию. Вы можете использовать пружинные фильтры предварительной аутентификации и делать это аналогичным образом. Пример ссылки: http://www.learningthegoodstuff.com/2014/12/spring-security-pre-authentication-and.html

Автор: tigersagar Размещён: 27.11.2018 08:21
Вопросы из категории :
32x32