Spring Security OAuth2, что определяет безопасность?

Я пытался реализовать сервер аутентификации OAuth2, используя руководства Дэйва Сайера, вдохновленные JHipster. Но я не могу понять, как все это работает вместе.

Похоже, что настройка безопасности с использованием WebSecurityConfigurerAdapter перезаписывается, когда я использую ResourceServerConfigurerAdapter.

@Configuration
@EnableResourceServer
public class OAuth2ResourceConfig extends ResourceServerConfigurerAdapter {

    private TokenExtractor tokenExtractor = new BearerTokenExtractor();

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .addFilterAfter(contextClearer(), AbstractPreAuthenticatedProcessingFilter.class)
                .authorizeRequests()
                .anyRequest().authenticated().and().httpBasic();
    }

    private OncePerRequestFilter contextClearer() {
        return new OncePerRequestFilter() {
            @Override
            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
                if (tokenExtractor.extract(request) == null) {
                    SecurityContextHolder.clearContext();
                }
                filterChain.doFilter(request, response);
            }
        };
    }

@Component
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    private final AuthenticationManager authenticationManager;

    @Autowired
    public CustomWebSecurityConfigurerAdapter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .parentAuthenticationManager(authenticationManager);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .formLogin()
                    .loginPage("/login").permitAll()
                .and()
                    .authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .and()
                    .requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
                .and()
                    .authorizeRequests().anyRequest().authenticated();
    }
}

Это код, взятый из нескольких разных примеров, поэтому они могут не так хорошо смешиваться. Но я не могу найти хороший список документации / примеров для OAuth2 (в отличие от Spring Boot, у которого есть отличная документация), поэтому у меня проблемы с пониманием того, как все они сочетаются друг с другом. Если я не добавлю loginForm в ResourceServerConfigurerAdapter, он просто выдаст мне несанкционированный доступ. Но я определил его в WebSecurityConfigurererAdapter как permissionAll ().

Это AuthorizationServerConfigurerAdapter:

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("acme")
                .secret("acmesecret")
                .authorizedGrantTypes("authorization_code", "refresh_token",
                        "password").scopes("openid");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints)  throws Exception {
        endpoints.authenticationManager(authenticationManager).accessTokenConverter(jwtAccessTokenConverter);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
    }
}

Что я делаю не так? Нужно ли мне настраивать всю безопасность в ResourceServerConfigurerAdapter? Нужен ли мне вообще WebSecurityConfigurerAdapter?

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

С уважением, Кеннет.


person LG87    schedule 16.02.2015    source источник
comment
Насколько я понимаю, ваш OAuth2ResourceConfig лишний. Просто говорю.   -  person Dave Syer    schedule 19.02.2015
comment
Каковы симптомы (по каким путям вы идете и что вы видите)? Использование curl (-v для просмотра заголовков) и ведение журнала DEBUG для Spring Security должно сообщить вам все, что вам нужно знать.   -  person Dave Syer    schedule 19.02.2015
comment
Симптомы заключались в том, что он в основном игнорировал WebSecurityConfigurerAdapter. Но после прочтения вашего объяснения ниже я немного больше понимаю, как это работает.   -  person LG87    schedule 22.02.2015
comment
У меня нет настройки CustomWebSecurityConfigurerAdapter для перехода к форме входа в систему, у меня 404. Как вы это тестировали?   -  person Dimitri Kopriwa    schedule 21.09.2016


Ответы (1)


Вам нужен WebSecurityConfigurerAdapter, чтобы защитить конечную точку / authorize и предоставить пользователям способ аутентификации. Приложение Spring Boot сделает это за вас (добавив свой собственный WebSecurityConfigurerAdapter с базовой аутентификацией HTTP). Он создает цепочку фильтров с порядком = 0 по умолчанию и защищает все ресурсы, если вы не предоставите сопоставление запросов. @EnableResourceServer делает нечто подобное, но цепочка фильтров, которую он добавляет, по умолчанию имеет порядок = 3. WebSecurityConfigurerAdapter имеет аннотацию @Order (100). Итак, сначала будет проверен ResourceServer (аутентификация), а затем будут проверены ваши чеки в вашем расширении WebSecurityConfigureAdapter.

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

person Dave Syer    schedule 19.02.2015
comment
Мне пришлось сделать мой WebSecurityConfigurerAdapter order = 2, чтобы заставить его работать. - person Robin Elvin; 16.07.2015
comment
Указываете ли вы порядок с аннотацией Order или где вы это указываете? У меня такая же проблема, и аннотирование конфигурации с помощью Order не имеет никакого эффекта, ResourceServerConfigurerAdapter - единственный используемый класс, а WebSecurityConfigurerAdapter полностью игнорируется. - person Cenobyte321; 05.12.2015
comment
@ Cenobyte321 implements Ordered, @Order(1) или @Order(2) - person robinhowlett; 05.02.2016
comment
@DaveSyer, можно ли использовать два уровня безопасности (базовый + носитель) поверх каждого? - person Dimitri Kopriwa; 20.03.2017
comment
@ Lg87 Можете ли вы иметь свои учетные данные в файле свойств, а не в самом исходном коде Java? - person Jesse; 28.03.2017
comment
Аннотируется ли WebSecurityConfigurerAdapter по умолчанию @Order (100)? - person meobeo173; 19.09.2017
comment
@DaveSyer, как узнать значения по умолчанию для этих ResourceServerConfigurer @order как в WebSecurityConfigurerAdapter, так и в ResourceServerConfigurerAdapter? Я изучил эти классы, но вижу только @Order(value = 100) в WebSecurityConfigurerAdapter, но ничего в ResourceServerConfigurerAdapter - person kavrosis; 06.03.2018
comment
Для RSCA вам нужно взглянуть на WSCA, который он создает для вас. IIRC по умолчанию - 3, но Spring Boot изменяет его (и имеет для него свойство config). - person Dave Syer; 06.03.2018
comment
Просто небольшое дополнение, на которое я наткнулся: org.springframework.core.annotation.Order: Более низкие значения имеют более высокий приоритет. Это означает, что ResourceServerConfiguration(order = 3) будет использоваться ДО WebSecurityConfigurarerAdapter @Order(100) Что имеет смысл: сначала проверьте аутентификацию, затем проверьте значения по умолчанию. - person Robert; 24.10.2018