在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問(wèn)答/Java  網(wǎng)絡(luò)安全/ CAS 4.X.X 客戶端循環(huán)重定向如何查找原因以及解決方案?

CAS 4.X.X 客戶端循環(huán)重定向如何查找原因以及解決方案?

問(wèn)題描述

CAS Server(支持https)下存在client1,client2,client3多個(gè)應(yīng)用,其中client1client2可以正常支持單點(diǎn)登錄,但是client3卻不行, 出現(xiàn)的問(wèn)題是當(dāng)在CAS Server登錄后,網(wǎng)頁(yè)會(huì)在https://cas-server/login?service=https://localhost:8443/cas-client3/loginhttps://localhost:8443/cas-client3/login?ticket=ST-1645-XXXXXXX-cas01.example.org之間循環(huán)重定向,導(dǎo)致網(wǎng)頁(yè)不能正常訪問(wèn)

問(wèn)題截圖

clipboard.png

clipboard.png

spring security和CAS的配置如下

配置文件

# CAS 相關(guān)配置
app:
  login:
    url: /login
  logout:
    url: /logout
  server:
    host:
      url: https://localhost:8443/cas-client3

cas:
  server:
    host:
      url: https://cas-server
      login_url: ${cas.server.host.url}/login
      logout_url: ${cas.server.host.url}/logout?service=${app.server.host.url}

配置類

import com.cloume.mooc.security.MyPermissionEvaluator;
import com.cloume.mooc.security.SpringContextUtil;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.cas.ServiceProperties;
import org.springframework.security.cas.authentication.CasAssertionAuthenticationToken;
import org.springframework.security.cas.authentication.CasAuthenticationProvider;
import org.springframework.security.cas.web.CasAuthenticationEntryPoint;
import org.springframework.security.cas.web.CasAuthenticationFilter;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;

import javax.annotation.Resource;
import java.util.Map;

/**
 * spring security配置
 * <p>
 * Created by surpass.wei@gmail.com on 2017/7/26.
 */
@Configuration
@EnableWebSecurity //   啟用web權(quán)限(spring boot無(wú)須該注解)
@EnableGlobalMethodSecurity(prePostEnabled = true) //啟用方法驗(yàn)證
@Profile("cas")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Resource
    private CasProperties casProperties;

    /**
     * 用戶認(rèn)證配置
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        super.configure(auth);
        auth.authenticationProvider(casAuthenticationProvider());
    }

    /**
     * 請(qǐng)求授權(quán)配置
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 允許所有用戶訪問(wèn)的路徑
                .antMatchers("/html/**")
                .permitAll()
                .expressionHandler(httpSecurityExpressionHandler())
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()
                .loginProcessingUrl("/login")
                .permitAll()
                .and()
                .rememberMe()
                .tokenValiditySeconds(31536000)
                .and()
                .csrf()
                .disable()
                .logout()
                .permitAll();

        http.exceptionHandling().authenticationEntryPoint(casAuthenticationEntryPoint())
                .and()
                .addFilter(casAuthenticationFilter())
                .addFilterBefore(casLogoutFilter(), LogoutFilter.class)
                .addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class);

        http.csrf().disable(); //禁用CSRF
    }

    /**
     * 指定service相關(guān)信息
     */
    @Bean
    public ServiceProperties serviceProperties() {
        ServiceProperties serviceProperties = new ServiceProperties();
        serviceProperties.setService(casProperties.getAppServerUrl() + casProperties.getAppLoginUrl());
        serviceProperties.setAuthenticateAllArtifacts(true);
        return serviceProperties;
    }

    @Bean
    public SessionRegistry getSessionRegistry() {
        return new SessionRegistryImpl();
    }

    @Bean
    public DefaultWebSecurityExpressionHandler httpSecurityExpressionHandler() {

        DefaultWebSecurityExpressionHandler expressionHandler = new DefaultWebSecurityExpressionHandler();
        expressionHandler.setPermissionEvaluator(new MyPermissionEvaluator());

        return expressionHandler;
    }

    @Bean
    public DefaultWebSecurityExpressionHandler webSecurityExpressionHandler() {

        final Map<String, DefaultWebSecurityExpressionHandler> expressionHandlers =
                SpringContextUtil.getApplicationContext().getBeansOfType(DefaultWebSecurityExpressionHandler.class);
        if (expressionHandlers.values().toArray()[0] != null) {
            ((DefaultWebSecurityExpressionHandler) expressionHandlers.values().toArray()[0]).setPermissionEvaluator(new MyPermissionEvaluator());
        }

        return (DefaultWebSecurityExpressionHandler) expressionHandlers.values().toArray()[0];
    }

    /**
     * CAS認(rèn)證過(guò)濾器
     */
    @Bean
    public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
        CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
        casAuthenticationFilter.setAuthenticationManager(authenticationManager());
        casAuthenticationFilter.setFilterProcessesUrl(casProperties.getAppLoginUrl());
        //  認(rèn)證成功后的處理
        //casAuthenticationFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler("/html/user.html"));
        return casAuthenticationFilter;
    }

    /**
     * cas 認(rèn)證 Provider
     */
    @Bean
    public CasAuthenticationProvider casAuthenticationProvider() {
        CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
        casAuthenticationProvider.setAuthenticationUserDetailsService(customUserDetailsService());
        //casAuthenticationProvider.setUserDetailsService(customUserDetailsService()); //這里只是接口類型,實(shí)現(xiàn)的接口不一樣,都可以的。
        casAuthenticationProvider.setServiceProperties(serviceProperties());
        casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator());
        casAuthenticationProvider.setKey("casAuthenticationProviderKey");
        return casAuthenticationProvider;
    }

    /**
     * 用戶自定義的AuthenticationUserDetailsService
     */
    @Bean
    public AuthenticationUserDetailsService<CasAssertionAuthenticationToken> customUserDetailsService() {
        return new CustomUserDetailsService();
    }

    @Bean
    public Cas20ServiceTicketValidator cas20ServiceTicketValidator() {
        return new Cas20ServiceTicketValidator(casProperties.getCasServerUrl());
    }

    /**
     * CAS認(rèn)證的入口
     */
    @Bean
    public CasAuthenticationEntryPoint casAuthenticationEntryPoint() {
        CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
        casAuthenticationEntryPoint.setLoginUrl(casProperties.getCasServerLoginUrl());
        casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
        return casAuthenticationEntryPoint;
    }

    /**
     * CAS請(qǐng)求單點(diǎn)退出過(guò)濾器
     */
    @Bean
    public LogoutFilter casLogoutFilter() {
        LogoutFilter logoutFilter = new LogoutFilter(casProperties.getCasServerLogoutUrl(), new SecurityContextLogoutHandler());
        logoutFilter.setFilterProcessesUrl(casProperties.getAppLogoutUrl());    //  設(shè)置處理登出的路徑
        return logoutFilter;
    }

    /**
     * CAS單點(diǎn)登出過(guò)濾器
     */
    @Bean
    public SingleSignOutFilter singleSignOutFilter() {
        SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
        singleSignOutFilter.setCasServerUrlPrefix(casProperties.getCasServerUrl());
        singleSignOutFilter.setIgnoreInitConfiguration(true);
        return singleSignOutFilter;
    }
}
回答
編輯回答
尋仙

每次提交完問(wèn)題, 總是就可以自己找到解決方案, 是運(yùn)氣好嗎? 折磨了我三天的問(wèn)題終于解決了, 而導(dǎo)致這個(gè)問(wèn)題的原因居然是spring boot(1.3.x)與cas(4.2.x)版本不兼容導(dǎo)致, 解決方案很簡(jiǎn)單, 升級(jí)spring boot版本到1.5.x, cas不用指定版本號(hào)(會(huì)根據(jù)spring-boot-starter-parent自動(dòng)適應(yīng))

2017年3月15日 06:17