gpt4 book ai didi

java - Spring MVC 页面中嵌入式 Flex 应用程序远程调用时出现 Spring 安全错误

转载 作者:行者123 更新时间:2023-12-02 00:42:17 29 4
gpt4 key购买 nike

我希望有人能帮我解决这个问题。我有一个 Spring MVC 应用程序 (Spring 3) 与 Spring Security 3 完美运行,我们现在添加对 Flex 的支持,并将 BlazeDS 添加到应用程序和 Spring Integration (1.5.0 M2),一切都开始正常工作,直到我们想要集成通过 Spring Security 进行身份验证。 Flex 应用程序是一个“迷你”UI,充当两个用户之间的 P2P 聊天(通过消息传递),它嵌入在 Spring MVC 应用程序的 JSP 页面中,我们要做的是确保(从 Flex 应用程序)用户在显示聊天 UI 之前已登录。身份验证是从 Spring MVC 应用程序(Web 表单)完成的,并且工作正常,但每次我们访问包含 Flex 应用程序的 Spring MVC 页面并从 Flex 进行远程调用以获取当前用户详细信息时,我们都会得到一个异常(exception):

flex.messaging.security.SecurityException: An Authentication object was not found in the SecurityContext

我们假设远程处理请求(从经过身份验证的 session 发出)将以某种方式被拾取并识别,并且 Flex 客户端不需要再次进行身份验证。这里可能出了什么问题?这是我的 Spring Security 配置和 Flex 配置文件以及 web.xml:

安全.xml:

<bean id="springSecurityFilterChain"
class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain filters="none" pattern="/styles/**" />
<sec:filter-chain filters="none" pattern="/js/**" />
<sec:filter-chain filters="none" pattern="/images/**" />
<sec:filter-chain
filters="securityContextPersistenceFilter,
logoutFilter,
usernamePasswordAuthenticationFilter,
anonymousAuthenticationFilter,
exceptionTranslationFilter,
menuLoaderRequestFilter,
filterSecurityInterceptor"
pattern="/web/**" />
<sec:filter-chain
filters="securityContextPersistenceFilter,
usernamePasswordAuthenticationFilter,
exceptionTranslationFilter"
pattern="/do_login" />
<sec:filter-chain
filters="securityContextPersistenceFilter,
logoutFilter,
exceptionTranslationFilter"
pattern="/do_logout" />
</sec:filter-chain-map>
</bean>

<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter" />

<bean id="usernamePasswordAuthenticationFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager"
ref="authenticationManager" />
<property name="filterProcessesUrl" value="/do_login"/>
<property name="authenticationFailureHandler">
<ref bean="loginFailureHandler" />
</property>
<property name="authenticationSuccessHandler">
<ref bean="loginSuccessHandler" />
</property>
<property name="usernameParameter" value="login_user" />
<property name="passwordParameter" value="login_password" />
</bean>

<bean id="loginFailureHandler"
class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/web/login?error=login.failure"/>
<property name="exceptionMappings">
<map>
<entry>
<key>
<value>org.springframework.security.authentication.AuthenticationServiceException</value>
</key>
<value>/web/login?error=login.database.failure</value>
</entry>
</map>
</property>
</bean>

<bean id="loginSuccessHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/web/index"/>
</bean>

<bean id="anonymousAuthenticationFilter"
class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
<property name="userAttribute"
value="anonymousUser,ROLE_ANONYMOUS" />
<property name="key" value="AD17JFJ005P00Z7MK" />
</bean>

<bean id="logoutFilter"
class="org.springframework.security.web.authentication.logout.LogoutFilter">
<!-- the post-logout destination -->
<constructor-arg value="/web/login?success=login.loggedout"/>
<constructor-arg>
<array>
<ref bean="logoutHandler" />
</array>
</constructor-arg>
<property name="filterProcessesUrl" value="/do_logout"/>
</bean>

<bean id="logoutHandler"
class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />

<bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint"
ref="mainEntryPoint"/>
<property name="accessDeniedHandler" ref="accessDeniedHandler"/>
</bean>


<bean id="mainEntryPoint"
class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
<constructor-arg>
<map>
<entry>
<key>
<value>hasHeader('X-Requested-With', 'XMLHttpRequest')</value>
</key>
<ref bean="ajaxEntryPoint"/>
</entry>
<entry>
<key>
<value>hasHeader('Content-type', 'application/x-amf')</value>
</key>
<ref bean="flexEntryPoint" />
</entry>
</map>
</constructor-arg>
<property name="defaultEntryPoint" ref="defaultEntryPoint" />
</bean>

<bean id="entryPointTemplate" abstract="true">
<property name="loginFormUrl" value="/web/login"/>
</bean>

<bean id="ajaxEntryPoint" parent="entryPointTemplate"
class="com.saes.support.security.AjaxAuthenticationEntryPoint" >
</bean>

<bean id="defaultEntryPoint" parent="entryPointTemplate"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
</bean>

<bean id="flexEntryPoint" class="org.springframework.flex.security3.FlexAuthenticationEntryPoint">
</bean>

<bean id="accessDeniedHandler"
class="com.saes.support.security.SAESAccessDeniedHandler">
<property name="errorPage"
value="/web/errors/accessDenied"/>
</bean>

<bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager"
ref="authenticationManager"/>
<property name="accessDecisionManager" ref="decisionManager"/>
<property name="securityMetadataSource">
<sec:filter-security-metadata-source>
<sec:intercept-url pattern="/web/profile/**"
access="ROLE_USER" />
<sec:intercept-url pattern="/web/doctor/**"
access="ROLE_DOCTOR" />
</sec:filter-security-metadata-source>
</property>
</bean>

<bean id="menuLoaderRequestFilter"
class="com.saes.security.menu.MenuPermissionsAdapterRequestFilter">
</bean>

<bean id="decisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false" />
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
<ref bean="authenticatedVoter"/>
</list>
</property>
</bean>

<bean id="roleVoter"
class="org.springframework.security.access.vote.RoleVoter" />

<bean id="authenticatedVoter"
class="org.springframework.security.access.vote.AuthenticatedVoter" />

<bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService">
<ref bean="userDetailsService" />
</property>
</bean>

<bean id="anonymousAuthenticationProvider"
class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
<property name="key" value="AD17JFJ005P00Z7MK"/>
</bean>

<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<list>
<ref bean="daoAuthenticationProvider" />
<ref bean="anonymousAuthenticationProvider" />
</list>
</property>
</bean>

flex-servlet.xml:

<flex:message-broker 
services-config-path="/WEB-INF/config/flex/services-config.xml">

<flex:secured authentication-manager="authenticationManager"
access-decision-manager="decisionManager">
<flex:secured-endpoint-path pattern="**/messagebroker/*" access="ROLE_USER"/>
</flex:secured>

</flex:message-broker>

web.xml:

    <context-param>     
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/spring/persistence.xml
/WEB-INF/config/spring/security.xml
/WEB-INF/config/spring/services.xml
/WEB-INF/config/spring/facade.xml
/WEB-INF/config/spring/validator.xml
/WEB-INF/config/flex/flex-context.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>mainServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mainServlet</servlet-name>
<url-pattern>/web/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>flex</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>flex</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/jsp/errors/critical-error.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/jsp/errors/404.jsp</location>
</error-page>

这是 Flex 代码的相关部分:

<s:ChannelSet id="chatChannelSet">
<s:StreamingAMFChannel url="http://192.168.1.3:8080/MyApp/messagebroker/streamamf">
</s:StreamingAMFChannel>
</s:ChannelSet>

<s:ChannelSet id="remotingChannelSet">
<s:AMFChannel url="http://192.168.1.3:8080/MyApp/messagebroker/amf">
</s:AMFChannel>
</s:ChannelSet>
<s:RemoteObject id="remoteService"
destination="remoteService"
channelSet="{remotingChannelSet}">
</s:RemoteObject>

var asyncCall:AsyncToken = remoteService.getTicketForCurrentUser();
asyncCall.addResponder(new Responder(getTicket_Result, getTicket_Fault));

前面的代码总是以错误处理程序结束,并在提示开头提到错误

其他配置文件:

服务-config.xml:

<services-config> 

<services>
<service-include file-path="messaging-config.xml" />
</services>

<channels>
<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
<endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>

<channel-definition id="streaming-amf" class="mx.messaging.channels.StreamingAMFChannel">
<endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/streamamf" class="flex.messaging.endpoints.StreamingAMFEndpoint"/>
<properties>
<idle-timeout-minutes>0</idle-timeout-minutes>
<max-streaming-clients>10</max-streaming-clients>
<server-to-client-heartbeat-millis>5000</server-to-client-heartbeat-millis>
<user-agent-settings>
<user-agent match-on="MSIE" kickstart-bytes="2048" max-streaming-connections-per-session="3" />
<user-agent match-on="Firefox" kickstart-bytes="2048" max-streaming-connections-per-session="3" />
</user-agent-settings>
</properties>
</channel-definition>
</channels>

<logging>
<target class="flex.messaging.log.ConsoleTarget" level="Debug">
<properties>
<prefix>[BlazeDS] </prefix>
<includeDate>false</includeDate>
<includeTime>false</includeTime>
<includeLevel>false</includeLevel>
<includeCategory>false</includeCategory>
</properties>
<filters>
<pattern>Endpoint.*</pattern>
<pattern>Service.*</pattern>
<pattern>Configuration</pattern>
</filters>
</target>
</logging>

<system>
<redeploy>
<enabled>false</enabled>
</redeploy>
</system>

消息配置.xml:

<service id="message-service" 
class="flex.messaging.services.MessageService">

<adapters>
<adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true" />
</adapters>

<destination id="chat-destination">
<properties>
<server>
<message-time-to-live>0</message-time-to-live>
<allow-subtopics>true</allow-subtopics>
<subtopic-separator>.</subtopic-separator>
<disallow-wildcard-subtopics>true</disallow-wildcard-subtopics>
</server>
</properties>
<channels>
<channel ref="streaming-amf" />
</channels>
</destination>

<default-channels>
<channel ref="streaming-amf"/>
</default-channels>

最佳答案

经过深入研究配置后,我发现了问题,我会将解决方案发布给每个可能需要它的人。我必须明确告诉 Spring Security 在我的“/messagebroker/**”url 的过滤器链中包含“securityContextPersistenceFilter”,以便安全上下文正确填充身份验证信息(正如我们从一开始就假设的那样)。配置已添加到“springSecurityFilterChain”bean,如下所示:

<bean id="springSecurityFilterChain"
class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<!-- other filter chain maps and options here (see the entire file in comment above -->
<sec:filter-chain
filters="securityContextPersistenceFilter"
pattern="/messagebroker/**" />
</bean>

将该过滤器链配置添加到 Spring Security 后,过滤器中来自 Flex UI 的所有请求都会自动填充先前通过 Spring MVC Web 表单登录创建的现有身份验证。

关于java - Spring MVC 页面中嵌入式 Flex 应用程序远程调用时出现 Spring 安全错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6031519/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com