1

我为我的 Web 应用程序使用 Spring Security 默认情况下,身份验证机制将用户重定向到“主页”,但可以通过 URL 直接访问应用程序的一个屏幕。

如果您在网络浏览器中填写 URL,则一切正常。

但是,如果我在 Excel 表中有一个具有相同 URL 的超链接,我会得到登录页面,然后我会转到“主页”,而我想访问我的特定屏幕。

如果我用 OpenOffice 打开 Excel 工作表,一切正常;就像我在网络浏览器中填写 URL 一样。

这是我的配置:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
     http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> 

<security:http auto-config="true" access-denied-page="/accessDenied.jsp" use-expressions="true" access-decision-manager-ref="accessDecisionManager" entry-point-ref="entryPoint">
<security:intercept-url pattern="/css/*.css" access="permitAll" />
<security:intercept-url pattern="/images/**" access="permitAll" />
<security:intercept-url pattern="/javascript/*.js" access="permitAll" />
<security:intercept-url pattern="/j_spring_security_check" access="permitAll"/>
<security:intercept-url pattern="/register.*" access="permitAll" />
<security:intercept-url pattern="/registerUser.*" access="permitAll" />
<security:intercept-url pattern="/login.*" access="permitAll" />
<security:intercept-url pattern="/restore/*" access="permitAll" />
<security:intercept-url pattern="/customer/**" access="permitAll" />
<security:intercept-url pattern="/logout.*" access="isAuthenticated()" />
<security:intercept-url pattern="/j_spring_security_logout"  access="isAuthenticated()"/>
<security:intercept-url pattern="/index.*"  access="isAuthenticated()" />
<security:intercept-url pattern="/admin/**" access="hasRole('ADMIN')" />
<security:intercept-url pattern="/template/*" access="isAuthenticated()" />
<security:intercept-url pattern="/editor/*" access="hasRole('EDITOR')" />
<security:intercept-url pattern="/creator/*" access="hasRole('CREATOR')" />
<security:intercept-url pattern="/task/*" access="hasAnyRole('CREATOR','EDITOR')"/>
<security:intercept-url pattern="/ajax/*" access="hasAnyRole('CREATOR','EDITOR')"/>
<security:intercept-url pattern="/**" access="isAuthenticated()" />
<security:form-login default-target-url="/index.jsp" authentication-failure-url="/login.jsp?login_error=true"/>
<security:logout  invalidate-session="true" logout-url="/logout.jsp" logout-success-url="/login.jsp"/>
</security:http>

<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider ref="userEnvironmenttStatisticService" />
</security:authentication-manager>

<security:global-method-security secured-annotations="enabled" pre-post-annotations="enabled">
    <security:expression-handler ref="expressionHandler" />
</security:global-method-security>

<bean id="userEnvironmenttStatisticService" class="com.epam.crs.security.UserEnvironmenttStatisticService">
    <property name="userDetailsService" ref="userDetailsService" />
</bean>

<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
    <constructor-arg>
        <list>
            <ref bean="notDeletedVoter" />
        </list>
    </constructor-arg>
</bean>

<bean id="notDeletedVoter" class="com.epam.crs.security.NotDeletedVoter" />

<bean id="entryPoint" class="com.epam.crs.security.ParameterizedLoginUrlAuthenticationEntryPoint">
    <constructor-arg value="/login.jsp"/>
</bean>

<bean id="customPermissionEvaluator" class="com.epam.crs.security.CustomPermissionEvaluator" />

<bean id="expressionHandler"
    class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <property name="permissionEvaluator" ref="customPermissionEvaluator" />
</bean>
</beans>

任何人都可以帮助我吗?也许您知道如何解决它?

4

3 回答 3

3

我在类似的系统上遇到了同样的问题。这是我修复它的方法以及我的调查背后的更多细节。

我如何为我的类似应用修复它

我更新了入口点,因此它使用转发。您更新的代码将是:

<bean id="entryPoint" class="com.epam.crs.security.ParameterizedLoginUrlAuthenticationEntryPoint">
    <constructor-arg value="/login.jsp"/>
    <property name="useForward" value="true" />
</bean>

注意:这要求您的入口点来自LoginUrlAuthenticationEntryPoint

更多细节..

典型的执行流程:

这是像您这样的 Spring Security 设置的典型执行流程:

  1. 匿名用户点击安全页面。
  2. AnAccessDeniedException被抛出并被ExceptionTranslationFilter. 该过滤器在会话中添加来自匿名用户的请求。
  3. 安全入口点(即您的ParameterizedLoginUrlAuthenticationEntryPointbean)然后将用户重定向到登录页面。此重定向是作为HTTP 302重定向完成的。
  4. 用户输入有效凭据。
  5. SavedRequestAwareAuthenticationSuccessHandler调用默认值。此处理程序加载保存的请求(存储在步骤 2 中的会话中)并将用户重定向到该页面(再次使用HTTP 302重定向。)

Excel是如何解决这个问题的

由于超出范围的原因, Excel在将 url 传递给默认浏览器之前使用了一个简单的 http 客户端。

该 http 客户端将传递第一个返回HTTP 200代码的 url。

http 客户端将触发流程中的前 3 个步骤,登陆登录页面。

由于登录页面会发出HTTP 200, 这是 Excel 的 http 客户端将发送到您的浏览器的 url。

浏览器打开登录页面,但它收到一个新的会话 id:它不共享 Excel 的 http 客户端的会话 cookie。

当用户输入有效凭据时,将SuccessHandler调用 ,就像在步骤 5 中一样,除了用户会话中没有保存的请求(保存的请求保存在 Excel 的 http 客户端会话中,而不是用户的会话中)。处理程序默认将用户发送到默认页面:您的home页面。

为什么转发可以解决这个问题?

转发只是处理服务器端的重定向,不包括进程中的浏览器/客户端。因此,在典型的流程示例中,所有重定向都是在服务器端作为转发完成的。

具体来说,这意味着 URL 不会改变。这允许 Excel 的 http 客户端将正确的 url 传递给浏览器,从而允许您的用户完成 5 个步骤的过程而不会出现任何问题。

于 2014-01-07T20:57:18.240 回答
1

我遇到了同样的问题,对我来说这对我有帮助:http: //support.microsoft.com/kb/218153

安装 Microsoft Fix it 50655: http: //go.microsoft.com/ ?linkid=9769998

于 2013-08-28T11:30:05.077 回答
0

如果您在网络浏览器中填写 URL,则一切正常。

但是,如果我在 Excel 表中有一个具有相同 URL 的超链接,我会得到登录页面,然后我会转到“主页”,而我想访问我的特定屏幕。

这根本不是由弹簧决定的。您的 URL 必须不同,否则您的会话已过期。

于 2013-06-11T09:17:31.130 回答