spring-security - 基于 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>
问题
- 如何修改网络安全配置,以便每当有
access-token
请求参数时,它都会根据访问令牌对用户进行身份验证并为同一用户创建会话。 - 我正在考虑使用公共控制器映射
/login/autologin?token=<token>&redirect=<url>
,它基本上可以对用户进行身份验证并调用自动登录策略。但是,我不知道,我需要调用哪些类/策略来在此处使用访问令牌对用户进行身份验证以及如何?
还有其他建议来实现这一目标吗?
解决方案
我已经管理了这样的要求
Write a controller which capture the access_token and call below TokenAuthenticationValidator
Write a TokenAuthenticationValidator by referring OAuth2AuthenticationProcessingFilter where you need to extract the token base authentication object and pass it to OAuth2AuthenticationManager to authenticate it.
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);
推荐阅读
- elasticsearch - 如何在elasticsearch中查询数组内的空日期?
- javascript - 在表单中向用户询问金额和用户价值
- matlab - 存储交点 - Matlab
- firebase - Firebase:第一次写入很慢
- c# - 在 C# 中我已经实现了一个自定义异常,我现在如何实现它?
- java - IF 和赋值语句是线程安全的
- python - 如何通过reportlab将表格定位在特定的x和y坐标
- c++ - Swapchain 和 Render Pass 创建成功,但验证层在使用时出错
- javascript - Spring 控制器在测试环境中被调用两次
- java - Hazelcast反序列化:反序列化后父类属性值为空