CAS Java:单点登录的终极解决方案

发布时间:2023-05-22

一、什么是CAS Java?

CAS(Central Authentication Service)是一个企业级开源单点登录解决方案,包括多种客户端和服务器的实现。它能够为不同的应用程序提供单点登录(SSO)服务,尤其擅长企业内部多个Web应用的统一认证。 CAS Java是基于Java语言实现的CAS客户端和服务端,它包含CAS Server、CAS Client以及CAS Protocol。理解CAS Protocol是理解CAS Java的关键。

二、CAS Protocol是什么?

CAS Protocol是由CAS Java提供的基于HTTP和XML的协议。它定义了一种用于认证和授权的通用标准,包括认证请求、认证响应等。CAS Server和CAS Client之间通过HTTP协议进行通信,CAS Server根据CAS Protocol中定义的规则对请求进行认证,CAS Client则负责将CAS Server认证的结果返回给Web应用程序。

三、CAS Java的客户端如何实现单点登录?

CAS Java的客户端实现了多个适配器,能够与各种不同类型的Web应用程序交互。基本的SSO流程如下:

  1. 用户访问应用程序A,被重定向到CAS Client
  2. CAS Client将用户重定向到CAS Server进行认证
  3. CAS Server对用户进行认证,如果成功就生成一个TGT(Ticket Granting Ticket)并返回给CAS Client
  4. CAS Client将TGT保存在浏览器的Cookie中,并将用户重定向回应用程序A,并将TGT作为参数传递到应用程序A
  5. 应用程序A通过CAS Client验证TGT,如果合法则将用户与应用程序A的会话绑定

四、CAS Java的服务端如何对用户进行认证?

CAS Java的服务端实现了多个模块,包括用户信息存储模块、认证模块、授权模块等。基本的认证流程如下:

  1. CAS Server接收到CAS Protocol请求后,从请求中获取用户凭证信息
  2. CAS Server查询用户信息存储模块,判断用户凭证信息的合法性
  3. 认证模块对用户进行认证,如果成功就生成一个ST(Service Ticket)并返回给CAS Client
  4. 授权模块根据用户的权限信息进行授权

五、CAS Java有哪些优点?

  1. 简单易用。CAS Java提供了完整的SSO解决方案,用户只需要按照官方文档正确配置即可实现SSO。
  2. 可扩展性好。CAS Java的客户端和服务端都提供了丰富的API和插件机制,用户可以根据自己的需求进行定制。
  3. 安全性高。CAS Protocol有良好的安全性,可以有效防止认证信息泄露。
  4. 支持多种客户端和服务器。CAS Java提供了多种客户端和服务器的实现,用户可以根据自己的需要选择。

六、CAS Java在实际应用中的例子

1、单点登录

@Configuration
@EnableWebSecurity
public class CasSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private CasProperties casProperties;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .csrf().disable()
                .apply(new CasAuthenticationConfigurer<>(casAuthenticationProvider()));
    }
    @Bean
    public CasAuthenticationProvider casAuthenticationProvider() {
        CasAuthenticationProvider provider = new CasAuthenticationProvider();
        provider.setAuthenticationUserDetailsService(authenticationUserDetailsService());
        provider.setServiceProperties(ServiceProperties());
        provider.setTicketValidator(cas20ServiceTicketValidator());
        provider.setKey("casAuthProviderKey");
        return provider;
    }
    @Bean
    public UserDetailsByNameServiceWrapper userDetailsByNameServiceWrapper() {
        return new UserDetailsByNameServiceWrapper(userDetailsService());
    }
    @Bean
    public AuthenticationUserDetailsService<CasAssertionAuthenticationToken> authenticationUserDetailsService() {
        return new UserDetailsServiceImpl();
    }
    @Bean
    public ServiceProperties ServiceProperties() {
        ServiceProperties serviceProperties = new ServiceProperties();
        serviceProperties.setService(casProperties.getServerName() + "/login/cas");
        serviceProperties.setAuthenticateAllArtifacts(true);
        return serviceProperties;
    }
    @Bean
    public Cas20ServiceTicketValidator cas20ServiceTicketValidator() {
        return new Cas20ServiceTicketValidator(casProperties.getCasServerUrlPrefix());
    }
}

2、CAS Server配置

<bean id="userDetailsService" class="org.jasig.cas.userdetails.JdbcPersonAttributeDao">
    <constructor-arg index="0" ref="dataSource"></constructor-arg>
    <constructor-arg index="1" value="SELECT * FROM users WHERE username = ?"></constructor-arg>
    <property name="order" value="1" />
    <property name="queryAttributeMapping">
        <map>
            <entry key="username" value="username" />
            <entry key="password" value="password" />
            <entry key="email" value="mail" />
            <entry key="department" value="department" />
        </map>
    </property>
</bean>
<bean id="myAuthenticationPolicy" class="org.jasig.cas.authentication.policy.AcceptAnyAuthenticationPolicy" />
<bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager">
    <!--策略,即一个通过就行,要么不行-->
    <constructor-arg>
        <map>
            <entry key-ref="myAuthenticationPolicy" value-ref="ldapAuthenticationHandler" />
            <entry key-ref="myAuthenticationPolicy" value-ref="proxyAuthenticationHandler" />
            <entry key-ref="myAuthenticationPolicy" value-ref="acceptUsersAuthenticationHandler" />
            <entry key-ref="myAuthenticationPolicy" value-ref="simpleTest" />
            <entry key-ref="myAuthenticationPolicy" value-ref="localDatabaseAuthenticationHandler" />
            <entry key-ref="myAuthenticationPolicy" value-ref="kerberosAuthenticationHandler" />
            <entry key-ref="myAuthenticationPolicy" value-ref="adAuthenticationHandler" />
        </map>
    </constructor-arg>
    <property name="authenticationPolicy" ref="myAuthenticationPolicy" />
</bean>

七、总结

CAS Java是一个功能强大且易于使用的SSO解决方案,它为企业内部的多个Web应用提供了一致的认证和授权服务。通过它实现单点登录,可以极大地提高企业内部工作效率和用户体验。