PRE_AUTH_FILTER +登录表单身份验证

时间:2012-08-29 10:13:49

标签: java authentication spring-security

我是春天安全的新手,似乎我有一个问题,对我来说,常见问题和其他网站都很难。

任务是:

  1. 我有登录表单的春季应用程序。一切都很好。

  2. 现在我需要能够从应用中获取任何允许的页面,但需要通过URL使用auth ...类似于:http://myapp.de?login=test&password=test。我用PRE_AUTH_FILTER创建了它。一切都适用于URL。

  3. 问题是我需要在我的应用中使用auth方式。假设PRE_AUTH_FILTER失败,则加载标准登录表单。因此:http://myapp.de将显示我的登录表单,并在第1点中显示。

  4. 现在我的安全配置只有PRE_AUTH_FILTER工作。

    我错过了什么?

    <sec:http auto-config="true" use-expressions="true">
        <sec:form-login login-page="/login.jsp" default-target-url="/start" authentication-failure-url="/login.jsp?error=true"/>
        <sec:logout logout-url="/logout" logout-success-url="/login.jsp"/>
        <sec:anonymous username="guest" granted-authority="ROLE_ANONYMOUS"/>
        <sec:access-denied-handler error-page="/error403.jsp"/>
        <sec:intercept-url pattern="/login*" access="permitAll"/>   
        <sec:intercept-url pattern="/objautocomplete*" access="hasRole('ROLE_USER')"/>
        <sec:intercept-url pattern="/start*" access="hasRole('ROLE_USER')"/>
        <sec:intercept-url pattern="/u*" access="hasRole('ROLE_USER')"/>
        <sec:intercept-url pattern="/crosstable*" access="hasRole('ROLE_USER')"/>
        <sec:intercept-url pattern="/objcen*" access="hasRole('ROLE_USER')"/>
        <sec:intercept-url pattern="/objchecks*" access="hasRole('ROLE_USER')"/>
        <sec:intercept-url pattern="/globalcen*" access="hasRole('ROLE_USER')"/>
        <sec:custom-filter position="PRE_AUTH_FILTER" ref="preAuthFilter" />
        <sec:remember-me/>
    </sec:http>
    
        <!-- PRE_ AUTHENTICATION -->        
    <beans:bean id="userDetailsServiceImpl"
        class="com.grsnet.qvs.auth.UserDetailsServiceImpl" />
    
    <beans:bean id="preAuthenticatedProcessingFilterEntryPoint"
        class="com.grsnet.qvs.auth.LinkForbiddenEntryPoint" />
    
    <beans:bean id="preAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
        <beans:property name="preAuthenticatedUserDetailsService" ref="userDetailsServiceImpl" />
    </beans:bean>
    
    <beans:bean id="preAuthFilter"
        class="com.grsnet.qvs.auth.UrlParametersAuthenticationFilter">
        <beans:property name="authenticationManager" ref="appControlAuthenticationManager" />
    </beans:bean>
    
    <sec:authentication-manager alias="appControlAuthenticationManager">
        <sec:authentication-provider ref="preAuthenticationProvider" />
    </sec:authentication-manager>
    
        <!-- LOGIN FORM AUTHENTICATION -->  
    
    <sec:authentication-manager>
        <sec:authentication-provider user-service-ref="qvsUserDetailsService"/>
    </sec:authentication-manager>
    
    <beans:bean id="qvsUserDetailsService" class="com.grsnet.qvs.auth.QVSUserDetailsService"/>
    
    </beans:beans>
    

    更新 UrlParametersAuthenticationFilter.java

    public class UrlParametersAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {
    
        @Override
        protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
            if (request.getParameterMap().size() == 2) {
                return true;
            }
            return false;
        }
    
        @Override
        protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
            String[] credentials = new String[2];
            credentials[0] = request.getParameter("j_username");
            credentials[1] = request.getParameter("j_password");
            return credentials;
        }
    }
    

1 个答案:

答案 0 :(得分:1)

<sec:custom-filter before="FORM_LOGIN_FILTER" ref="preAuthFilter" />

编辑:

是的,过滤器很乱。您是否查看了AbstractPreAuthenticatedProcessingFilter的javadoc或源代码?当外部系统已经完成身份验证时,将使用PreAuthentication。例如,如果您使用容器提供的Java EE身份验证,或者您具有进行身份验证的Web前端,例如使用IIS进行NTLM / kerberos前端。

此外,您已经错误地实现了它,getPreAuthenticatedPrincipal()应该返回用户名,即Principal和getPreAuthenticatedCredentials应该返回密码,即Credentials。但更重要的是,AbstractPreAuthenticatedProcessingFilter 不进行任何身份验证。从Javadoc的第一行开始:

Base class for processing filters that handle pre-authenticated authentication requests, where it is assumed that the principal has already been authenticated by an external system.

因此,请废弃过滤器并使用标准UsernamePasswordAuthenticationFilter

<beans:bean id="urlParameterAuthFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
    <beans:property name="usernameParameter" value="username" />
    <beans:property name="passwordParameter" value="password" />
    <beans:property name="postOnly" value="false" />
    <beans:property name="authenticationManager" ref="appControlAuthenticationManager" />
</beans:bean>

然后用

替换自定义过滤器声明
<sec:custom-filter before="FORM_LOGIN_FILTER" ref="urlParameterAuthFilter" />

免责声明:在URL中传递密码是一个非常非常糟糕的主意,你不应该首先这样做。它将显示在访问日志中,它引入了一大堆真正不必要的安全问题。