当前位置: 首页 > 知识库问答 >
问题:

端口8443上通过ssl的Spring Security登录在使用http协议的端口8080上无法识别

轩辕天佑
2023-03-14

我在试图保护我的登录表单时遇到了一种奇怪的行为。

我的应用程序是在Spring框架和Spring Security上开发的,部署在Tomcat服务器上。只要使用http,一切都很好,但当我在成功登录和重定向后,在登录页面使用https 8443端口时http://localhost:8080/mens/index我被重定向到登录页面https://localhost:8443/mens/login.html

这是我的spring security配置的一部分。xml:

<!-- enable use-expressions -->
<http auto-config="true" use-expressions="true">
    <custom-filter position="SWITCH_USER_FILTER" ref="switchUserProcessingFilter" />
    <intercept-url pattern="/j_spring_security_switch_user" access="hasRole('ROLE_SUPERVISOR')"/>

    <session-management invalid-session-url="/login.html?invalidSession=1" session-fixation-protection="newSession">
        <concurrency-control max-sessions="10" error-if-maximum-exceeded="true"/>
    </session-management>

    <intercept-url pattern="/login.html" access="hasRole('ROLE_ANONYMOUS')" requires-channel="https"/>
    <intercept-url pattern="/resources/**" access="permitAll" requires-channel="any"/>
    <intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')" requires-channel="http"/>
    <intercept-url pattern="/rest/**" access="hasRole('ROLE_USER')" requires-channel="http"/>
    <intercept-url pattern="/index" access="hasRole('ROLE_USER')" requires-channel="http"/>
    <intercept-url pattern="/upload/**" access="hasRole('ROLE_USER')" requires-channel="http"/>

    <headers>
        <xss-protection block="false"/>
        <frame-options disabled="true"/>
        <cache-control/>
    </headers>

    <!-- access denied page -->
    <access-denied-handler error-page="/403" />
    <form-login 
        login-page="/login.html" 
        default-target-url="/index" 
        always-use-default-target="true"
        authentication-failure-url="/login.html?error=1" 
        username-parameter="username" 
        password-parameter="password"/>
    <logout logout-success-url="/login.html?logout=1" invalidate-session="false" delete-cookies="JSESSIONID"/>
    <!-- enable csrf protection -->
    <!-- <csrf disabled="true" /> -->
</http>

或者,我尝试使用channelProcessingFilter而不是requires channel属性:

<http auto-config="true" use-expressions="true">
    <custom-filter position="CHANNEL_FILTER" ref="channelProcessingFilter"/>

    <custom-filter position="SWITCH_USER_FILTER" ref="switchUserProcessingFilter" />
    <intercept-url pattern="/j_spring_security_switch_user" access="hasRole('ROLE_SUPERVISOR')"/>

    <session-management invalid-session-url="/login.html?invalidSession=1" session-fixation-protection="newSession">
        <concurrency-control max-sessions="10" error-if-maximum-exceeded="true"/>
    </session-management>

    <intercept-url pattern="/login.html" access="hasRole('ROLE_ANONYMOUS')"/>
    <intercept-url pattern="/resources/**" access="permitAll"/>
    <intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')"/>
    <intercept-url pattern="/rest/**" access="hasRole('ROLE_USER')"/>
    <intercept-url pattern="/index" access="hasRole('ROLE_USER')"/>
    <intercept-url pattern="/upload/**" access="hasRole('ROLE_USER')"/>

    <headers>
        <xss-protection block="false"/>
        <frame-options disabled="true"/>
        <cache-control/>
    </headers>

    <!-- access denied page -->
    <access-denied-handler error-page="/403" />
    <form-login 
        login-page="/login.html" 
        default-target-url="/index" 
        always-use-default-target="true"
        authentication-failure-url="/login.html?error=1" 
        username-parameter="username" 
        password-parameter="password"/>
    <logout logout-success-url="/login.html?logout=1" invalidate-session="false" delete-cookies="JSESSIONID"/>
    <!-- enable csrf protection -->
    <!-- <csrf disabled="true" /> -->
</http>

<beans:bean id="channelProcessingFilter" class="org.springframework.security.web.access.channel.ChannelProcessingFilter">
    <beans:property name="channelDecisionManager" ref="channelDecisionManager"/>
    <beans:property name="securityMetadataSource">
        <filter-security-metadata-source request-matcher="regex">
            <intercept-url pattern="\A/login.*\Z" access="REQUIRES_SECURE_CHANNEL"/>
            <intercept-url pattern="\A/login.html.*\Z" access="REQUIRES_SECURE_CHANNEL"/>
            <intercept-url pattern="\A/.*\Z" access="ANY_CHANNEL"/>
        </filter-security-metadata-source>
    </beans:property>
</beans:bean>

<beans:bean id="channelDecisionManager" class="org.springframework.security.web.access.channel.ChannelDecisionManagerImpl">
    <beans:property name="channelProcessors">
        <beans:list>
            <beans:ref bean="secureChannelProcessor"/>
            <beans:ref bean="insecureChannelProcessor"/>
            <beans:ref bean="anyChannelProcessor"/>
        </beans:list>
    </beans:property>
</beans:bean>

<beans:bean id="secureChannelProcessor" class="com.mycompany.mens.springsecurity.MensSecureChannelProcessor"/>
<beans:bean id="insecureChannelProcessor" class="com.mycompany.mens.springsecurity.MensInsecureChannelProcessor"/>
<beans:bean id="anyChannelProcessor" class="com.mycompany.mens.springsecurity.MensAnyChannelProcessor">
    <beans:property name="entryPoint" ref="mensRetryWithHttpEntryPoint"/>
</beans:bean>

<beans:bean name="mensRetryWithHttpEntryPoint" class="com.mycompany.mens.springsecurity.MensRetryWithHttpEntryPoint"/>

调试我发现身份验证成功了,入口点将流重定向到http端口8080上的索引页,但在那之后,有东西将我重定向到另一次登录。

有什么建议吗?

非常感谢您的帮助!

共有1个答案

南门正祥
2023-03-14

您的登录页面需要HTTPS:

<intercept-url pattern="/login.html" access="hasRole('ROLE_ANONYMOUS')" requires-channel="https"/>

但您的索引页面需要HTTP:

<intercept-url pattern="/index" access="hasRole('ROLE_USER')" requires-channel="http"/>

这就是您丢失会话cookie的原因,请参阅Spring Security-常见问题解答(FAQ):

2.3。我正在使用Tomcat(或其他一些servlet容器)并为我的登录页面启用了HTTPS,之后切换回HTTP。它不起作用——我只是在身份验证后回到登录页面。

发生这种情况是因为在HTTPS下创建的会话(会话cookie被标记为“安全”)随后不能在HTTP下使用。浏览器不会将cookie发送回服务器,并且任何会话状态都将丢失(包括安全上下文信息)。首先在HTTP中启动会话应该可以工作,因为会话cookie不会被标记为安全(您还必须禁用Spring Security的会话固定保护支持,以防止它在登录时创建新的安全会话(您始终可以在稍后阶段自己创建新的会话)。请注意,在HTTP和HTTPS之间切换通常不是一个好主意,因为任何使用HTTP的应用程序都容易受到中间人攻击。为了真正安全,用户应该开始在HTTPS中访问您的站点并继续使用它,直到他们注销。即使从通过HTTP访问的页面单击HTTPS链接也有潜在风险。如果您需要更令人信服的内容,请查看sslstrie等工具。

 类似资料:
  • Tomcat启动失败,服务器端口8080已在使用中。 请帮助解决这个问题。我已经下载了mysql-connector-java-8.0.17.zip并解压了它。

  • 问题内容: 我正在使用Jenkins,从昨天开始它已经停止工作。我看着Windows服务,它已被停止(以某种方式)。我重新启动了它,但此后它立即停止了。 我查看了从(C:\ Program Files \ Jenkins)运行服务的目录,并在其中打开了名为jenkins.out.log的日志文件。这就是它的意思 问题答案: 已修复- 适用于将来可能会遇到此问题的其他任何人。我用了这篇Techrep

  • axis 2的欢迎页面工作正常。本地主机:8443/Axis2/ 如果我在可用服务页面上使用8080端口,它工作得很好。localhost:8080/axis2/services/ 有什么解决这个问题的小窍门吗?提前谢了。

  • 我是Spring靴的初学者。当我运行spring boot应用程序时,遇到了配置为侦听端口8080的Tomcat连接器无法启动的问题。Spring靴 我不知道如何解决这个问题。我已经安装了mysql当我运行mysql it端口也是8080。那么如何理清问题。

  • 尽管我的应用程序在本地运行良好,但我突然开始出现这个错误。 我正在Azure应用程序服务上运行rails应用程序。 我曾尝试将应用程序设置端口设置为80,将我的网站设置端口设置为8080,但没有成功。 puma.rb包括这个 部署到Azure后,我尝试将其更改为8080,但没有成功。 在网上看了之后,我真的很困惑为什么这是突然发生的

  • 在云服务器上写一个linux上运行的Http服务器时,绑定了任意IP和8080端口, 云服务器上的telnet是能直接和这个服务器交互的, 但是在浏览器 或者 在我windows上的telnet不能连接这个Http服务器(云服务器的公网ip可以ping通) 浏览器向服务器发请求时,我是会把请求的报文全打印出来的,这里没打印是没有连接上 我的防火墙全部关了也连不了,怎么办? 求大佬指教 。。。