如何使 Spring 安全在 CAS 服务器成功验证后将用户重定向到原始请求的页面

How to make Spring security to redirect user to the original requested page after successfully authenticated by the CAS server

我有一个 spring 引导 RESTFul Web 应用程序,它使用 CAS 服务器进行企业单一登录。如果未登录的用户尝试访问安全页面,该用户将被重定向到 CAS 服务器以进行身份​​验证。身份验证成功后,用户将被重定向到 spring boot RESTFul Web 应用程序的主页 - 而不是安全页面,用户会尝试访问。我们如何直接将用户重定向到用户登录成功后想要访问的安全页面?

spring-security-cas-client用于实现CAS认证。实施 AuthenticationSuccessHandler 以将 UseReferer 设置为 true。 spring安全配置class如下:

package com.example.app

import java.util.Arrays;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.cas.ServiceProperties;
import org.springframework.security.cas.authentication.CasAuthenticationProvider;
import org.springframework.security.cas.web.CasAuthenticationFilter;    
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutFilter;

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

private AuthenticationProvider authenticationProvider;
private AuthenticationEntryPoint authenticationEntryPoint;
private SingleSignOutFilter singleSignOutFilter;
private LogoutFilter logoutFilter;

@Autowired
public SecurityConfig(CasAuthenticationProvider casAuthenticationProvider, 
AuthenticationEntryPoint 
eP,
                      LogoutFilter lF
                      , SingleSignOutFilter ssF
) {
    this.authenticationProvider = casAuthenticationProvider;
    this.authenticationEntryPoint = eP;

    this.logoutFilter = lF;
    this.singleSignOutFilter = ssF;

}

@Override
protected void configure(HttpSecurity http) throws Exception {
  http
    .authorizeRequests()
    .antMatchers("/api/**", "/path-1", "/path-2")
    .authenticated()
    .and()
    .authorizeRequests()
    .regexMatchers("/")
    .permitAll()
    .and()
    .httpBasic()
    .authenticationEntryPoint(authenticationEntryPoint)
    .and()
    .logout().logoutSuccessUrl("/logout")
    .and()
    .addFilterBefore(singleSignOutFilter, CasAuthenticationFilter.class)
    .addFilterBefore(logoutFilter, LogoutFilter.class);

}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  auth.authenticationProvider(authenticationProvider);
}

@Override
protected AuthenticationManager authenticationManager() throws Exception {
  return new ProviderManager(Arrays.asList(authenticationProvider));
}

@Bean
public CasAuthenticationFilter casAuthenticationFilter(ServiceProperties sP) throws Exception {
  CasAuthenticationFilter filter = new CasAuthenticationFilter();
  filter.setServiceProperties(sP);
  filter.setAuthenticationManager(authenticationManager());
  return filter;
}

@Bean
public AuthenticationSuccessHandler successHandler() {
    SimpleUrlAuthenticationSuccessHandler handler = new SimpleUrlAuthenticationSuccessHandler();
    handler.setUseReferer(true);
    return handler;
}

}

使用 SavedRequestAwareAuthenticationSuccessHandler 而不是 SimpleUrlAuthenticationSuccessHandler 可能会帮助您实现重定向。

@Bean
public AuthenticationSuccessHandler successHandler() {
    SavedRequestAwareAuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler();
    handler.setTargetUrlParameter("redirectTo");
    handler.setDefaultTargetUrl("/");
    return handler;
}