springSecurity集成cas

cas是Central Authentication Service的简写.提供中央认证服务,实现企业级单点登录.详细参考:https://www.apereo.org/projects/cas .下面是入门测试

一.客户端核心配置.

package org.exam.config;
import org.jasig.cas.client.validation.Cas20ProxyTicketValidator;
import org.jasig.cas.client.validation.TicketValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.core.env.Environment;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.cas.ServiceProperties;
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.method.configuration.GlobalMethodSecurityConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.annotation.Resource;

/**
 * Created by on 16/6/18.
 */
@Configuration
public class SecurityConfig {
    @Configuration
    @EnableWebSecurity
    @PropertySource("classpath:config.properties")
    protected static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Resource
        private Environment env;

        @Bean
        public ReloadableResourceBundleMessageSource messageSource() {//本地化(不完全)
            ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
            messageSource.setBasename("classpath:org/springframework/authentication/messages");
            return messageSource;
        }

        //配置ServiceProperties
        @Bean
        public ServiceProperties serviceProperties() {
            ServiceProperties serviceProperties = new ServiceProperties();
            serviceProperties.setService(env.getProperty("cas.service"));
            return serviceProperties;
        }
        //配置认证切入点
        @Bean
        public CasAuthenticationEntryPoint authenticationEntryPoint() {
            CasAuthenticationEntryPoint authenticationEntryPoint = new CasAuthenticationEntryPoint();
            authenticationEntryPoint.setServiceProperties(serviceProperties());
            authenticationEntryPoint.setLoginUrl(env.getProperty("cas.loginUrl"));
            return authenticationEntryPoint;
        }
        //配置从cas认证回来的请求拦截器
        @Bean
        public CasAuthenticationFilter authenticationFilter() throws Exception {
            CasAuthenticationFilter authenticationFilter = new CasAuthenticationFilter();
            authenticationFilter.setAuthenticationManager(authenticationManager());
            authenticationFilter.setFilterProcessesUrl(env.getProperty("cas.processesUrl"));
            return authenticationFilter;
        }
        //提供用户数据源
        @Autowired
        private UserDetailsService userDetailsService;
        //断言
        @Bean
        public TicketValidator ticketValidator(){
            return new Cas20ProxyTicketValidator(env.getProperty("cas.serverUrlPrefix"));
        }
        //配置认证提供者
        @Bean
        public CasAuthenticationProvider authenticationProvider() {
            CasAuthenticationProvider authenticationProvider = new CasAuthenticationProvider();
            authenticationProvider.setServiceProperties(serviceProperties());
            authenticationProvider.setUserDetailsService(userDetailsService);
            authenticationProvider.setTicketValidator(ticketValidator());
            authenticationProvider.setKey(env.getProperty("cas.key"));
            return authenticationProvider;
        }
        //将认证提供者加入到认证管理器
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(authenticationProvider());
        }

        //配置
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().authenticated()
                    .and().logout().logoutUrl("/logout").logoutSuccessUrl(env.getProperty("cas.logoutUrl")).permitAll()
                    .and().exceptionHandling().accessDeniedPage("/exclude/403").authenticationEntryPoint(authenticationEntryPoint())
                    .and().addFilterAt(authenticationFilter(), CasAuthenticationFilter.class);
        }
        //配置忽略ant表达式
        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/static/**", "/exclude/**");
        }

        //暴露AuthenticationManager注册成Bean供@EnableGlobalMethodSecurity使用
        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    }

    @Configuration
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    protected static class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    }
}
#cas.service=https://localhost:8443/cas-client/login/cas
cas.service=http://localhost:8080/cas-client/login/cas
cas.processesUrl=/login/cas
cas.loginUrl=https://localhost:443/cas-server/login
cas.serverUrlPrefix=https://localhost:443/cas-server
cas.key=123456

二.服务端必须配置ssl(可以不启用客户端认证)

可能遇到的问题:
1.从cas服务端到cas客户端必须使用https,从cas客户端到cas服务端使用http也可以.

2.断言客户端抛错java.lang.RuntimeException: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching localhost found
解决思路:将cas服务端的keystore文件的CN设为localhost
d:\jdk8\bin\keytool -genkeypair -alias server -keystore server.p12 -storetype PKCS12 -keyalg RSA -storepass changeit -keypass changeit -validity 365 -dname "CN=localhost, OU=test, O=test, L=TH, ST=GZ, C=CN"

3.客户端抛错java.lang.RuntimeException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
解决思路(http://stackoverflow.com/questions/9619030/resolving-javax-net-ssl-sslhandshakeexception-sun-security-validator-validatore) :将cas服务端的证书导入到%JAVA_HOME%\lib\security\cacerts
a.查看个修改前的cacerts:d:\jdk8\bin\keytool -list -keystore "d:/jdk8/jre/lib/security/cacerts"
b.备份一下cacerts,将cacerts命令为cacerts.160618
c:
导出证书:
d:\jdk8\bin\keytool -exportcert -alias server -file server.cer -keystore server.p12 -storetype PKCS12 -storepass changeit
导入到cacerts:
d:\jdk8\bin\keytool -import -noprompt -trustcacerts -alias server -file server.cer -keystore cacerts -storepass changeit
e:再次运行d:\jdk8\bin\keytool -list -keystore "d:/jdk8/jre/lib/security/cacerts"查看导入结果,并和之前的查看进行对比,确认是否导入

源码:http://download.csdn.net/detail/xiejx618/9553037

猜你喜欢

转载自blog.csdn.net/xiejx618/article/details/51703469