首页 > 解决方案 > 基于 OAuth2 访问令牌自动登录 Hybris Web 应用程序

问题描述

背景
我们有一个使用SAP Hybris commerce运行的网站,用户可以在其中登录(基本 Spring Security)并浏览该网站。我们还有一个原生移动应用程序,它将再次使用 Oauth2 对 Hybris 系统中的用户进行身份验证,并且可以无状态工作。

问题陈述
用户登录移动原生应用程序,需要在标准网络浏览器中在网络上执行一些经过身份验证的操作(即使用原生应用程序尚不支持的某些功能)。本机应用程序应打开浏览器并确保用户使用他/她在本机应用程序中的相同帐户登录浏览器。

当前的网络安全配置.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. 我正在考虑使用公共控制器映射/login/autologin?token=<token>&redirect=<url>,它基本上可以对用户进行身份验证并调用自动登录策略。但是,我不知道,我需要调用哪些类/策略来在此处使用访问令牌对用户进行身份验证以及如何?

还有其他建议来实现这一目标吗?

标签: spring-securityoauth-2.0hybris

解决方案


我已经管理了这样的要求

  1. Write a controller which capture the access_token and call below TokenAuthenticationValidator

  2. Write a TokenAuthenticationValidator by referring OAuth2AuthenticationProcessingFilter where you need to extract the token base authentication object and pass it to OAuth2AuthenticationManager to authenticate it.

  3. If the token is authenticated, call the autoLoginStrategy which autologin the user. You need to write your custom autoLoginStrategy, which autologin the user without a password check. Like

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


推荐阅读