前两篇介绍了 Apereo CAS 以及服务器端的安装,但还不够完整,服务端还没有 Application 真正用起来呢!这篇文章将介绍怎么用起来
集成的目的
客户端我们想要与 Apereo CAS 做什么集成呢?回顾一下 Apereo CAS 是做什么的?Apereo CAS 的一个功能就是单点登录,统一的登录登出接口与页面,让系统中的模块只需要关注在业务点,而把安全认证的功能交给统一认证来做。所以客户端的集成主要是单点登录的集成,客户端指定需要做安全认证的页面,然后 Apereo CAS 的安全包检测校验用户登录情况,并自动与 CAS 登录页面进行跳转交互。
客户端的配置
Apereo CAS 提供了 Springboot 的包,可以让我们的集成些微方便了那么一丢丢!首先我们创建一个 Springboot 的 application,里面带了 Apereo CAS start 的依赖
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas</artifactId>
</dependency>
同时在 application.properties 文件里面指定启动的端口 server.port = 9000
有了 Apereo CAS 的包之后,我们就可以进行代码的配置。客户端的配置按照 SpringSecurity 的安全检验流程进行的:
用户尝试打开一个受保护的 url,比如 /admin/user
AuthenticationEntryPoint 被触发了,把用户重定向到配置好的 CAS 登录页面 https://localhost:6443/cas
用户输入用户名密码,登录成功后,CAS 会跳转回 application 指定的回调 url http://localhost:9000/login/cas,并带上 ticket 作为查询参数
CasAuthenticationFilter 一直在监听 /login/cas 这个路径,当发现有请求后,它会触发 CasTicketValidator,由 CasTickerValidator 检验 ticket 的有效性
当 ticket 也验证成功后,用户将会被跳转回原来请求的受保护 url
下面代码大致描述了这个过程:
@Bean
public ServiceProperties serviceProperties() {
ServiceProperties serviceProperties = new ServiceProperties();
serviceProperties.setService(“http://localhost:9000/login/cas”);
serviceProperties.setSendRenew(false);
return serviceProperties;
}
@Bean
@Primary
public AuthenticationEntryPoint authenticationEntryPoint(
ServiceProperties sP) {
CasAuthenticationEntryPoint entryPoint
= new CasAuthenticationEntryPoint();
entryPoint.setLoginUrl(“https://localhost:6443/cas/login”);
entryPoint.setServiceProperties(sP);
return entryPoint;
}
@Bean
public TicketValidator ticketValidator() {
return new Cas30ServiceTicketValidator(
“https://localhost:6443/cas”);
}
@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
CasAuthenticationProvider provider = new CasAuthenticationProvider();
provider.setServiceProperties(serviceProperties());
provider.setTicketValidator(ticketValidator());
provider.setUserDetailsService(
s -> new User(“casuser”, “Mellon”, true, true, true, true,
AuthorityUtils.createAuthorityList(“ROLE_ADMIN”)));
provider.setKey(“CAS_PROVIDER_LOCALHOST_9000”);
return provider;
}
@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(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;
}
}
下面这个文件配置了 application 中所有 /secured/*,login 的 URL 都是受保护资源,都要经过 CAS 认证过才可以访问:
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.regexMatchers(“/secured.*”, “/login”)
.authenticated()
.and()
.authorizeRequests()
.regexMatchers(“/”)
.permitAll()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
}
// …
}
服务端 Apereo CAS 的配置
跟所有统一认证平台一样,所有 application 想要跟 CAS 做集成的,都需要在 CAS 配置相应的参数才可以使用。Apereo CAS 提供了很多配置的方式,有 YML,JSON,MongoDB 以及其他(可查官网)。但高度自由的 CAS 一如既往的,没有提供可视化操作的界面。比如我们采用 JSON 的方式。首先我们需要通知 Apereo CAS 我们采用的是 JSON 的方式,并通知 JSON 文件的路径在哪里
cas.serviceRegistry.initFromJson=true
cas.serviceRegistry.config.location=classpath:/services
然后我们在这个目录里面,创建一个对应的 JSON 文件,保存我们的客户端信息,为了方面管理,建议文件名为 application_id.json, 比如 ”secureApp_9991.json”, 内容如下:
{
“@class” : “org.apereo.cas.services.RegexRegisteredService”,
“serviceId” : “^http://localhost:9000/login/cas”,
“name” : “CAS Spring Secured App”,
“description”: “This is a Spring App that usses the CAS Server for it’s authentication”,
“id” : 19991,
“evaluationOrder” : 1
}
第一次配置从 JSON 加载客户端配置的话,需要重启 Apereo CAS。之后再加新的客户端的话就不用再重启,Apereo CAS 会自动监测这个文件夹的变动
小结
至此我们对于 Apereo CAS 就有了一个稍微完整一点点的了解,从服务端安装部署,到配置,以及客户端如何集成等。但从这个短时间的学习来看,如果企业已经重度使用了 Apereo CAS,那相信它可以很好地服务支撑企业的应用。但如果是新的项目,特别是项目周期比较紧张的项目,并且团队之前没有对统一认证有技术积累的话,不是很建议采用 Apereo CAS,这些细微的配置以及无所不在的隐藏功能,会让你给项目经理催死的!后面我会介绍另外一个统一认证的框架,个人感觉能弥补 Apereo CAS 的短板的