Автоматический вход в веб-приложение Hybris на основе токена доступа OAuth2 - PullRequest
0 голосов
/ 23 января 2020

Справочная информация
У нас есть веб-сайт, работающий с использованием SAP Hybris commerce , где пользователи могут войти (basi c Spring Security) и просмотреть сайт. У нас также есть собственное мобильное приложение, которое снова аутентифицирует пользователя в системе Hybris с помощью Oauth2 и работает без сохранения состояния.

Постановка проблемы
Пользователь вошел в мобильное собственное приложение и должен выполнять некоторые аутентифицированные операции в Интернете в стандартном веб-браузере (ie. с использованием некоторых функций, которые пока не поддерживаются нативными приложениями). Собственное приложение должно открыть браузер и убедиться, что пользователь вошел в браузер с той же учетной записью, которую он / она имеет в собственном приложении.

Текущий веб security-config. xml

<http access-decision-manager-ref="accessDecisionManager" use-expressions="false">
    <session-management session-authentication-strategy-ref="fixation"/>
    <intercept-url pattern="/login.jsp" access="PERMIT_ALL"/>
    <intercept-url pattern="/**" access="HYBRIS_NOT_INITIALIZED,ROLE_CUSTOMERGROUP"/>
    <http-basic />
    <form-login 
        always-use-default-target="false" 
        login-page="/login.jsp" 
        username-parameter="j_username"
        password-parameter="j_password"
        login-processing-url="/j_spring_security_check"
        authentication-failure-url="/login.jsp?login_error=1"
    />
    <remember-me services-ref="rememberMeServices" key="adminweb"/>
    <logout logout-url="/j_spring_security_logout" logout-success-url="/login.jsp"/>
    <csrf />
    <headers>
        <frame-options disabled="true"/>
    </headers>
</http>

Конфигурация Oauth2

<!-- Generating token -->
    <sec:http pattern="/oauth/token" create-session="stateless" entry-point-ref="oauthAuthenticationEntryPoint"
              authentication-manager-ref="clientAuthenticationManager" use-expressions="false">
        <sec:csrf disabled="true"/>
        <sec:intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" requires-channel="${webservicescommons.required.channel:https}"/>
        <sec:anonymous enabled="false" />
        <sec:port-mappings>
            <sec:port-mapping http="#{configurationService.configuration.getInt('tomcat.http.port',9091)}"
                              https="#{configurationService.configuration.getInt('tomcat.ssl.port',9092)}" />
            <sec:port-mapping http="#{configurationService.configuration.getInt('embeddedserver.http.port',9091)}"
                              https="#{configurationService.configuration.getInt('embeddedserver.ssl.port',9092)}" />
        </sec:port-mappings>
        <sec:http-basic entry-point-ref="oauthAuthenticationEntryPoint" />
        <sec:custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />
        <sec:access-denied-handler ref="oauthAccessDeniedHandler" />
        <sec:headers>
            <sec:frame-options disabled="true"/>
        </sec:headers>
    </sec:http>

<!-- Accessing APIs using V2 -->
    <http pattern="/v2/**" entry-point-ref="oauthAuthenticationEntryPointV2"
              access-decision-manager-ref="webSecurityAccessDecisionManager"
              xmlns="http://www.springframework.org/schema/security" create-session="stateless">

            <anonymous username="anonymous" granted-authority="ROLE_ANONYMOUS"/>
            <!--<session-management session-authentication-strategy-ref="fixation"/>-->

            <intercept-url pattern="/**" requires-channel="https"/>

            <port-mappings>
                <port-mapping http="#{configurationService.configuration.getProperty('tomcat.http.port')}"
                              https="#{configurationService.configuration.getProperty('tomcat.ssl.port')}"/>
                <port-mapping http="#{configurationService.configuration.getProperty('embeddedserver.http.port')}" 
                              https="#{configurationService.configuration.getProperty('embeddedserver.ssl.port')}" />
            </port-mappings>

            <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>
            <access-denied-handler ref="oauthAccessDeniedHandlerV2"/>

            <headers >
                <content-type-options />
                <hsts include-subdomains="true" max-age-seconds="16070400" />
                <xss-protection />
                <security:frame-options disabled="true"/>
            </headers>
            <security:csrf disabled="true"/>
        </http>

Вопросы

  1. Как изменить конфигурацию веб-безопасности так, чтобы при наличии access-token параметр запроса, он аутентифицирует пользователя на основе токена доступа и создает сеанс для того же пользователя.
  2. Я думаю, что у меня будет publi c отображение контроллера, подобное /login/autologin?token=<token>&redirect=<url>, которое в основном аутентифицирует пользователя и называет стратегию аутологина. Но я не знаю, какие все классы / стратегии мне нужно вызывать для аутентификации пользователя с использованием токена доступа здесь и как?

Любые другие предложения для достижения этой цели?

1 Ответ

0 голосов
/ 25 февраля 2020

Я выполнил это требование примерно так

  1. Напишите контроллер, который захватывает access_token и вызывает ниже TokenAuthenticationValidator
  2. Напишите TokenAuthenticationValidator, ссылаясь на OAuth2AuthenticationProcessingFilter, где вам нужно извлечь токен базовый объект аутентификации и передайте его OAuth2AuthenticationManager для его аутентификации.
  3. Если токен аутентифицирован, вызовите autoLoginStrategy, который автоматически вводит пользователя. Вам нужно написать свой собственный autoLoginStrategy, который автоматически авторизует пользователя без проверки пароля. Как

    oauthUserAutoLoginStrategy.login(authResult.getPrincipal().toString(), request, response);

...