Spring MVC 页面中嵌入式 Flex 应用程序远程调用时出现 Spring 安全错误
我希望有人能帮助我解决这个问题。我有一个 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 进行远程调用以获取当前用户详细信息时,我们都会得到一个例外:
flex.messaging.security.SecurityException: An Authentication object was not found in the SecurityContext
我们假设远程处理请求(从经过身份验证的会话发出)将以某种方式被拾取并识别,并且 Flex 客户端不需要再次进行身份验证。这里可能出了什么问题?这是我的 spring security 配置和我的 flex 配置文件以及 web.xml:
security.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));
前面的代码总是结束在错误处理程序中,并在提示开头提到错误
其他配置文件:
services-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>
消息传递-config.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>
I wish someone can help me with this one. I have a Spring MVC application (Spring 3) running perfectly fine with Spring Security 3, we are now adding support for Flex and added BlazeDS to the application and Spring Integration (1.5.0 M2), all started working fine until we wanted to integrate authentication through Spring Security. The Flex application is a "mini" UI that serves as a P2P chat (through messaging) between two users and it is embedded in a JSP page in the Spring MVC application, what we want to do is ensure (from the Flex application) that the user is logged in before showing the chat UI. The authentication is done from the Spring MVC application (a web form) and it works fine, but every time we access to the Spring MVC page that holds the Flex application and make a remoting call from Flex to get the current user details we get an exception:
flex.messaging.security.SecurityException: An Authentication object was not found in the SecurityContext
We assumed that the remoting request (made from an authenticated session) will be somehow picked up and recognized and that the Flex client doesn't need to authenticate again. What could be wrong here? Here is my spring security config and my flex configuration file as well as the web.xml:
security.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>
And here is the relevant part of the Flex code:
<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));
The previous code always ends up in the Fault handler with the error mentioned at the beginning of the cuestion
Other configuration files:
services-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>
messaging-config.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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
经过深入研究配置后,我发现了问题,我会将解决方案发布给可能需要它的每个人。我必须明确告诉 Spring Security 在我的“/messagebroker/**”url 的过滤器链中包含“securityContextPersistenceFilter”,以便安全上下文正确填充身份验证信息(正如我们从一开始就假设的那样)。配置已添加到“springSecurityFilterChain”bean,如下所示:
将该过滤器链配置添加到 Spring Security 后,过滤器中来自 Flex UI 的所有请求都会自动填充通过 Spring MVC Web 表单从先前登录创建的现有身份验证。
After some digging into the configuration I found the problem, and I will post the solution for everyone who might need it. I had to explicitly tell Spring Security to include the "securityContextPersistenceFilter" in the filter chain for my "/messagebroker/**" urls so the security context gets properly populated with the authentication information (as we assumed from the beginning). The configuration was added to the "springSecurityFilterChain" bean as follows:
After adding that filter chain configuration to the Spring Security filter all requests from the Flex UI where automatically populated with the existing authentication created from a previous login through the Spring MVC web form.
快速给出答案 - 您能否将 Flex 内容设置为搭载现有的基于 Spring Security HTML 的登录表单?是的,绝对可以。我已经做到了,如果您有一些应用程序需要保护但不能通过 Flex 应用程序提供服务,那么它会非常有效。
我没有使用
消息代理配置的一部分(当我第一次设置它时它不存在,也许我现在可以切换到它,但由于我的设置正在工作,我不觉得有任何强烈的需要那一刻)。我已将消息代理 URL 模式设置为安全。我的消息代理是这样保护的:
(swf-loading-page 只是包装 swf 的页面的占位符名称...并且 .do 映射到我的视图解析器)
当您在 Flex 端调用时:
被调用的内容在java端的服务器上?
对于我来说,我做了类似的事情 - 我拉出本地用户将其返回到 Flex 客户端(以显示当前登录的用户等) -
在你的 Java 端,你可以使用 SpringSecurityContextHolder 来获取 SecurityContext,然后从SecurityContext 你可以拉出
如果你的应用程序服务器使用 jpda 调试,你可以在该方法上设置一个断点并查看你的安全上下文并确保它被正确填充(但似乎不是 - 这很奇怪)
To give a quick answer - can you set up your Flex stuff to piggyback on an existing Spring Security HTML-based login form? Yes, absolutely you can. I've done it and it works quite nicely if you have some of your app that needs to be protected but doesn't get served through a flex app.
I'm NOT using the
part of the the message-broker config (it didn't exist when I first set this up, perhaps I could switch to it now but since my setup is working I don't feel any strong need to at the moment). I have my my messagebroker url pattern set up to be secured. My messagebroker is secured like so:
(the swf-loading-page is just a placeholder name for a page that wraps the swf... and .do is mapped to my view resolver)
When on the flex side you call:
What gets called on the server in the java side?
For mine, I do something similar - I pull out the local user to return it to the flex client (to display the current logged in user, etc) -
On your Java side you can use the SpringSecurityContextHolder to get the SecurityContext and then from the SecurityContext you can pull out the
If you your your app server with jpda debugging you can set a breakpoint on that method and peek into your security context and make sure it is being correctly populated (but it seems that it is not - which is odd)