Spring Security - OAuth2 и CustomAuthenticationProvider.Как настроить разные шаблоны URL для каждого? - PullRequest
0 голосов
/ 12 июля 2019

В моем проекте есть два провайдера аутентификации: клиент Google OAuth2 (начальная зависимость oauth2) и второй пользовательский AuthenticationProvider.

А у меня два antMatcher: /api/** и /app/**.

Можно ли авторизовать /app/** с OAuth2 и /api/** с моим провайдером аутентификации?

Потому что я не хочу, чтобы OAuth2 был включен для REST API, но хочу OAuth SSO для остальной части приложения.

Как мне указать разные шаблоны URL для разных провайдеров аутентификации?

Редактировать

Следуйте моей конфигурации (Spring Boot 2.0.2):

@Configuration
@EnableWebSecurity
class SecurityConfiguration : WebSecurityConfigurerAdapter() {

    override fun configure(http: HttpSecurity) {
        http.authorizeRequests()
            .antMatchers("/health").permitAll()
            .anyRequest().authenticated()
            .and()
            .oauth2Login()
            .permitAll()
    }
}

Пробовал разные конфигурации, но ни одна не работала

Ответы [ 2 ]

0 голосов
/ 16 июля 2019

Поскольку у вас есть два провайдера аутентификации, вам необходимо настроить два менеджера аутентификации. Вот пример конфигурации XML для вашей справки:

<security:authentication-manager id="appAuthenticationManager">
    <security:authentication-provider ref="appAuthenticationProvider"/>
</security:authentication-manager>

<security:authentication-manager id="apiAuthenticationManager">
    <security:authentication-provider ref="apiAuthenticationProvider"/>
</security:authentication-manager>

Затем настройте правила защиты для конечных точек.

<sec:filter-security-metadata-source id="appServerSecurityMetadataSource"
                                     request-matcher="ant"
                                     use-expressions="true">
    <sec:intercept-url pattern="/oauth/check_token" access="isFullyAuthenticated() and hasRole('PRIVATE_SERVICE')"/>
    <sec:intercept-url pattern="/oauth/token" access="isFullyAuthenticated() and hasRole('PRIVATE_SERVICE')"/>
    <sec:intercept-url pattern="/oauth/jwt-token" access="isFullyAuthenticated() and hasRole('PRIVATE_SERVICE')"/>
    <sec:intercept-url pattern="/**" access="denyAll()"/>

    <sec:expression-handler ref="securityExpressionHandler"/>
</sec:filter-security-metadata-source>


<sec:filter-security-metadata-source id="apiServerSecurityMetadataSource"
                                     request-matcher="ant"
                                     use-expressions="true">
    <sec:intercept-url pattern="/users/**" access="isFullyAuthenticated() and hasRole('ACTIVE_USER')"/>
    <sec:intercept-url pattern="/**" access="denyAll()"/>

    <sec:expression-handler ref="securityExpressionHandler"/>
</sec:filter-security-metadata-source>

Затем настройте фильтр-перехватчик безопасности: (Настройте аналогичный перехватчик также для apiAuthenticationManager)

<bean id="appSecurityInterceptorFilter" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
    <property name="authenticationManager" ref="appAuthenticationManager"/>
    <property name="accessDecisionManager" ref="accessDecisionManager"/>
    <property name="securityMetadataSource" ref="appServerSecurityMetadataSource"/>
</bean>

Последний шаг заключается в регистрации этих фильтрующих компонентов:

<bean id="appServerSecurityFilterRegistration" class="org.springframework.boot.web.servlet.FilterRegistrationBean">
    <property name="filter" ref="appSecurityInterceptorFilter"/>
    <property name="enabled" value="false"/>
</bean>

Редактировать: Чтобы обойти некоторые запросы из всей цепочки фильтров:

Создание сопоставителя пути для всех /api/** запросов.

<bean id="apiRequestMatcher" class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
    <constructor-arg index="0" value="/api/**"/>
</bean>

Создать пустую цепочку фильтров, чтобы обойти все фильтры для /api/** запросов.

<bean id="apiFilterChain" class="org.springframework.security.web.DefaultSecurityFilterChain">
    <constructor-arg name="requestMatcher" ref="apiRequestMatcher"/>
    <constructor-arg name="filters">
        <list/>
    </constructor-arg>
</bean>

Наконец, зарегистрируйте это для фильтрации прокси цепочки.

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
    <constructor-arg>
        <list>
            <ref bean="apiFilterChain"/>
        </list>
    </constructor-arg>
</bean>

Для делегирования этих запросов вашему пользовательскому провайдеру выполните шаги, о которых я рассказывал ранее.

Вы также можете попробовать <http pattern="/api/**" security="none"/> обойти цепочку фильтров. Пружина 3.1 заменена filters=”none” на security=”none”.

0 голосов
/ 12 июля 2019

AuthenticationProvider имеет метод: support (Class authentication), который принимает токен аутентификации, если он возвращает false, AuthenticationManager не будет вызывать этого провайдера.

Следовательно, вы можете поместить пользовательское поле в токен аутентификации дляуказать, какой URI вызывается, интерфейс аутентификации имеет метод getDetails (), который возвращает объект, где вы можете предоставить дополнительную информацию.

Для этого вам нужно создать пользовательские AuthenticationDetails и AuthenticationDetailsSource, вы можетерасширить WebAuthenticationDetails и WebAuthenticationDetailsSource.В WebAuthenticationDetailsSource есть метод buildDetails, который дает вам доступ к HttpServletRequest.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...