如何从 Spring Security 中删除过滤器?

St.*_*rio 3 java spring spring-security

其中Spring Security 4.0有所谓的Default Login Page,如下所示:

在此输入图像描述

深入研究源代码,我发现了 Filter org.springframework.security.web.authentication.ui.DefaultLoginPageGenerateFilter

它呈现该登录页面。实际上,它有 private String generateLoginPageHtml(HttpServletRequest request, boolean loginError, boolean logoutSuccess)方法,其中包含以下代码片段:

if (formLoginEnabled) {
    sb.append("<h3>Login with Username and Password</h3>");
    sb.append("<form name='f' action='").append(request.getContextPath()).append(authenticationUrl).append("' method='POST'>\n");
    sb.append(" <table>\n");
    sb.append("    <tr><td>User:</td><td><input type='text' name='");
    sb.append(usernameParameter).append("' value='").append("'></td></tr>\n");
    sb.append("    <tr><td>Password:</td><td><input type='password' name='").append(passwordParameter).append("'/></td></tr>\n");

    if (rememberMeParameter != null) {
        sb.append("    <tr><td><input type='checkbox' name='").append(rememberMeParameter).append("'/></td><td>Remember me on this computer.</td></tr>\n");
    }

    sb.append("    <tr><td colspan='2'><input name=\"submit\" type=\"submit\" value=\"Login\"/></td></tr>\n");
    renderHiddenInputs(sb, request);
    sb.append("  </table>\n");
    sb.append("</form>");
}
Run Code Online (Sandbox Code Playgroud)

问题是我想从过滤器链中删除该过滤器,以便自定义由 url 定位的登录页面http://my-domain/login。是否可以?

我的安全配置:

<http auto-config="true">
    <intercept-url pattern="/admin**" 
                    access="hasRole('ROLE_USER')" />
    <form-login login-page="/login" 
                default-target-url="/admin" 
                authentication-failure-url="/login?error=true" 
                username-parameter="user"
                password-parameter="password" 
                login-processing-url="/login"/>
    <logout logout-success-url="/login?logout" logout-url="/logout" />
</http>
Run Code Online (Sandbox Code Playgroud)

Bor*_*der 6

为什么你要“深入研究源代码”而不是文档,它非常清楚地涵盖了这一点:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .loginPage("/login");
}
Run Code Online (Sandbox Code Playgroud)

仅当您未设置登录页面时才会生成默认登录页面。

如果你检查源代码AbstractAuthenticationFilterConfigurer你会看到:

protected T loginPage(String loginPage) {
    this.loginPage = loginPage;
    this.authenticationEntryPoint = new LoginUrlAuthenticationEntryPoint(loginPage);
    this.customLoginPage = true;
    return getSelf();
}
Run Code Online (Sandbox Code Playgroud)

如果你再看一下源代码FormLoginConfigurer

private void initDefaultLoginFilter(H http) {
    DefaultLoginPageViewFilter loginPageGeneratingFilter = http.getSharedObject(DefaultLoginPageViewFilter.class);
    if(loginPageGeneratingFilter != null && !isCustomLoginPage()) {
        //stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

所以你看,调用loginPageset customLoginPage = true。这会禁用 DefaultLoginPageGeneratingFilter.

  • 你还觉得有点幽默,你问他为什么要“深入挖掘源头”,然后你的回答建议他用 2 个类来挖掘源头;) (5认同)