当前位置: 动力学知识库 > 问答 > 编程问答 >

java - PRE_AUTH_FILTER + Login form authentication

问题描述:

I'm new with spring security and it seems I have a question which is too difficult for me, for faqs and for other sites.

Task is:

  1. I have spring app with login form. Everything works good.

  2. Now I need to have ability to get any permitted page from app but with auth via URL... something like: http://myapp.de?login=test&password=test. I made it with PRE_AUTH_FILTER. Everything works with URL.

  3. Problem is I need both auth way in my app. Let's say if PRE_AUTH_FILTER failed then standard login form is loaded. So: http://myapp.de will show my login form and in point 1).

Now with my security configuration I only have PRE_AUTH_FILTER working.

What did I miss?

<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>

UPDATE 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;

}

}

网友答案:
<sec:custom-filter before="FORM_LOGIN_FILTER" ref="preAuthFilter" />

EDIT:

Yeah, the filter is a mess. Did you even look at the javadoc or source of the AbstractPreAuthenticatedProcessingFilter? PreAuthentication is used when an external system has done the authentication already. For instance, if you use Java EE authentication provided by your container or you have a web-front that authenticates, like fronting with IIS for NTLM/kerberos.

Also, you have implemented it incorrectly, getPreAuthenticatedPrincipal() should return the user name, aka Principal and getPreAuthenticatedCredentials should return the password, aka Credentials. But more importantly, the AbstractPreAuthenticatedProcessingFilter does not do any authentication. From the first line of the 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.

So, scrap your filter and use the standard 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>

Then replace your custom filter declaration with

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

Disclaimer: passing passwords in the URL is a really, really bad idea and you shouldn't do it in the first place. It will show up in access-logs and it introduces a whole bunch of really unnecessary security concerns.

分享给朋友:
您可能感兴趣的文章:
随机阅读: