Spring Security OAuth2 修改登录失败后跳转的 URL 链接

Spring Security OAuth2 Spring Boot About 2,965 words

Spring Security 配置

拦截/web/**请求,使用OAtuh2的登录方式未认证的请求。登录页修改为指定的路径,失败后跳转的路径是/web/login

@Bean
SecurityFilterChain securityFilterChain0(HttpSecurity http) throws Exception {
    http
            .securityMatcher("/web/**")
            .authorizeHttpRequests(authorizeHttpRequests -> {
                authorizeHttpRequests.anyRequest().authenticated();
            })
            .oauth2Login(oauth2 -> {
                oauth2.loginPage("/oauth2/authorization/keycloak");
                oauth2.failureUrl("/web/login");
            });
    return http.build();
}

登录失败场景

  • 登录页Session过期
  • 后端服务器重启

登录失败后的处理

理想状态:登录失败后跳转到/web/login,由于/web/login也在Spring Security OAuth2拦截规则之内,所以又跳到OAuth2提供的登录页。

现实情况:OAuth2登录失败后的跳转链接是登录页,默认loginPageAbstractAuthenticationFilterConfigurer中设置的/login?error。所以Spring Security没有拦截到/login,没有跳转到OAtuh2登录页。

结论

需设置oauth2.loginPageoauth2.failureUrl

源码

public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
        extends AbstractAuthenticationFilterConfigurer<B, OAuth2LoginConfigurer<B>, OAuth2LoginAuthenticationFilter> {

    private String loginPage;

    private String loginProcessingUrl = OAuth2LoginAuthenticationFilter.DEFAULT_FILTER_PROCESSES_URI; // "/login/oauth2/code/*"

    @Override
    public OAuth2LoginConfigurer<B> loginPage(String loginPage) {
        this.loginPage = loginPage;
        return this;
    }

    @Override
    public void init(B http) throws Exception {
        if (this.loginPage != null) {
            // Set custom login page
            super.loginPage(this.loginPage);
            super.init(http);
        }
    }

}

public abstract class AbstractAuthenticationFilterConfigurer ...{

    private String loginPage;

    protected AbstractAuthenticationFilterConfigurer() {
        setLoginPage("/login");
    }

    protected T loginPage(String loginPage) {
        setLoginPage(loginPage);
        updateAuthenticationDefaults();
        this.customLoginPage = true;
        return getSelf();
    }

    private void setLoginPage(String loginPage) {
        this.loginPage = loginPage;
        this.authenticationEntryPoint = new LoginUrlAuthenticationEntryPoint(loginPage);
    }

    protected final void updateAuthenticationDefaults() {
        if (this.loginProcessingUrl == null) {
            loginProcessingUrl(this.loginPage);
        }
        if (this.failureHandler == null) {
            failureUrl(this.loginPage + "?error");
        }
        LogoutConfigurer<B> logoutConfigurer = getBuilder().getConfigurer(LogoutConfigurer.class);
        if (logoutConfigurer != null && !logoutConfigurer.isCustomLogoutSuccess()) {
            logoutConfigurer.logoutSuccessUrl(this.loginPage + "?logout");
        }
    }

}

public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoint, InitializingBean {

    private String loginFormUrl;

    public LoginUrlAuthenticationEntryPoint(String loginFormUrl) {
        this.loginFormUrl = loginFormUrl;
    }

}
Views: 528 · Posted: 2024-05-16

————        END        ————

Give me a Star, Thanks:)

https://github.com/fendoudebb/LiteNote

扫描下方二维码关注公众号和小程序↓↓↓

扫描下方二维码关注公众号和小程序↓↓↓
Today On History
Browsing Refresh