我是春天安全的新手,似乎我有一个问题,对我来说,常见问题和其他网站都很难。
任务是:
我有登录表单的春季应用程序。一切都很好。
现在我需要能够从应用中获取任何允许的页面,但需要通过URL使用auth ...类似于:http://myapp.de?login=test&password=test。我用PRE_AUTH_FILTER创建了它。一切都适用于URL。
问题是我需要在我的应用中使用auth方式。假设PRE_AUTH_FILTER失败,则加载标准登录表单。因此:http://myapp.de将显示我的登录表单,并在第1点中显示。
现在我的安全配置只有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;
}
}
答案 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中传递密码是一个非常非常糟糕的主意,你不应该首先这样做。它将显示在访问日志中,它引入了一大堆真正不必要的安全问题。