【问题标题】:CAS + Spring Security Detect localhostCAS + Spring Security 检测本地主机
【发布时间】:2013-12-24 16:49:45
【问题描述】:

我正在尝试使用 Spring 安全性和 CAS 实现应用程序,它在 localhost 上运行良好,但是当我尝试从外部机器访问它并且应用程序需要身份验证时,它也重定向到 localhost。

意义

我使用https://172.16.1.50:8443/isxannouncements/ 访问应用程序 当它需要身份验证时,它应该去https://172.16.1.50:8443/cas/login/ 而是转到https://localhost:8443/isxannouncements/

这当然会破坏应用程序流程。

我的配置是

安全-cas.xml

<bean id="serviceProperties"
      class="org.springframework.security.cas.ServiceProperties">
    <property name="service"
              value="https://localhost:8443/isxannouncements/login"/>
</bean>
<!--
    Allows changing where the CAS Server and CAS Service are easily
    by specifying System Arguments or replacing the values only in one place.
    Could also use external properties file -->
<context:property-placeholder
        system-properties-mode="OVERRIDE" properties-ref="environment"/>
<util:properties id="environment">
    <prop key="cas.service.host">localhost:8443</prop>
    <prop key="cas.server.host">localhost:8443</prop>
</util:properties>

<!-- sends to the CAS Server, must be in entry-point-ref of security.xml -->
<bean id="casEntryPoint"
      class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
    <property name="serviceProperties" ref="serviceProperties"/>
    <property name="loginUrl" value="https://localhost:8443/cas/login" />
</bean>

<!-- authenticates CAS tickets, must be in custom-filter of security.xml -->
<bean id="casFilter"
      class="org.springframework.security.cas.web.CasAuthenticationFilter">
    <property name="authenticationManager" ref="authenticationManager"/>
    <property name="filterProcessesUrl" value="/login"/>
</bean>

<bean id="casAuthProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
    <property name="ticketValidator" ref="ticketValidator"/>
    <property name="serviceProperties" ref="serviceProperties"/>
    <property name="key" value="isxannouncements"/>
    <property name="authenticationUserDetailsService" ref="DBUserServiceDetails"/>
    <property name="statelessTicketCache" ref="statelessTicketCache"/>
</bean>

<bean id="statelessTicketCache" class="org.springframework.security.cas.authentication.EhCacheBasedTicketCache">
    <property name="cache">
        <bean class="net.sf.ehcache.Cache"
              init-method="initialise" destroy-method="dispose">
            <constructor-arg value="casTickets"/>
            <constructor-arg value="50"/>
            <constructor-arg value="true"/>
            <constructor-arg value="false"/>
            <constructor-arg value="3600"/>
            <constructor-arg value="900"/>
        </bean>
    </property>
</bean>

<bean id="ticketValidator" class="org.jasig.cas.client.validation.Saml11TicketValidator">
    <constructor-arg value="https://localhost:8443/cas" />
    <property name="encoding" value="utf8" />
</bean>

<!-- Handles a Single Logout Request from the CAS Server must be in custom-filter of security.xml -->
<bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/>

还有我的security.xml

<security:http pattern="/resources/images" security="none"/>
<security:http use-expressions="true" entry-point-ref="casEntryPoint">
    <security:intercept-url pattern="/login/*"
                            access="permitAll"/>
    <security:intercept-url pattern="/resources/**"
                            access="permitAll"/>
    <security:intercept-url pattern="/logout"
                            access="permitAll"/>
    <security:intercept-url pattern="/errors/**"
                            access="permitAll"/>
    <security:intercept-url pattern="/approve-announcement**"
                            access="hasRole('ROLE_USER')"/>
    <security:intercept-url pattern="/delete-announcement**"
                            access="hasRole('ROLE_USER')"/>
    <security:intercept-url pattern="/edit-announcement**"
                            access="hasRole('ROLE_USER')"/>
    <security:intercept-url pattern="/admin/**"
                            access="hasRole('ROLE_ADMIN')"/>
    <security:intercept-url pattern="/META-INF"
                            access="hasRole('ROLE_USER')"/>
    <security:access-denied-handler error-page="/errors/403"/>

    <security:custom-filter ref="singleLogoutFilter" before="LOGOUT_FILTER"/>
    <security:custom-filter ref="casFilter" position="CAS_FILTER"/>
    <security:port-mappings>
        <security:port-mapping http="8080" https="8443"/>
    </security:port-mappings>

    <security:logout logout-url="/logout"
                     logout-success-url="https://localhost:8443/cas/logout"/>
</security:http>
<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider ref="casAuthProvider" />
</security:authentication-manager>

如何解决这个问题??

【问题讨论】:

    标签: java spring spring-security cas


    【解决方案1】:

    好的,我找到了一种解决方法,但我没有正确测试它,

    answer的启发,我做了以下事情

    由于我有两个域可供用户访问我的应用程序,因此获取用户使用的域的唯一方法是从请求中获取,然后将其返回给安全提供者。

    我创建了一个名为serviceProperties的bean,并用它代替了spring的serviceproperties,并重写了getService的方法,根据用户访问应用的域名返回服务。

    然后我在 Web Application Context 中提供了这个 bean,并传入了 session,我已经从 Request 中提取了域并将其放入 Session。

    因此,当CasAuthenticationEntryPoint 尝试获取服务时,我将通过附加到它的会话创建的服务 URL 传递给服务名称。

    【讨论】:

      【解决方案2】:

      我们使用属性文件来处理这个问题。特定于特定环境的任何内容(即您的本地计算机与您的测试服务器)都应该在属性文件中。

      例如,为每个环境创建属性文件,如下所示:

      localhost.properties:

          cas.service.url=http://localhost/login
      

      test.properties:

          cas.service.url=http://mytestserver/login
      

      然后使用属性文件中的值配置spring security,而不是像上面那样直接配置:

      然后,您的构建过程将为每个环境设置一个目标,以将适当的文件随机放置在最终工件中。

      【讨论】:

      • 但我们有 2 个域
      • 对,所以你需要以某种方式在两者之间切换。一种方法是使用构建过程生成特定于环境的工件。这就是我在回答中的建议。
      【解决方案3】:

      CAS 在域下工作。所以你应该使用 cas.example.com 并在 cas.properties 中定义它

      【讨论】:

        猜你喜欢
        • 2012-12-02
        • 1970-01-01
        • 2016-07-14
        • 2015-12-28
        • 2014-01-28
        • 1970-01-01
        • 2012-04-07
        • 2020-02-02
        • 2016-06-05
        相关资源
        最近更新 更多