0%

CAS 学习(二)--SpringBoot整合CAS

配置SpringBoot项目

  1. 修改pom文件中添加cas client依赖
    1
    2
    3
    4
    5
    <dependency>
    <groupId>org.jasig.cas.client</groupId>
    <artifactId>cas-client-support-springboot</artifactId>
    <version>3.6.2</version>
    </dependency>
  2. 修改application.properties添加如下内容
    1
    2
    3
    4
    5
    6
    7
    8
    #CAS Server URL
    cas.server-url-prefix=http://localhost:8443/cas
    #CAS Server认证登录URL
    cas.server-login-url=http://localhost:8443/cas/login
    #受保护程序的URL
    cas.client-host-url=http://localhost:8080
    #认证协议
    cas.validation-type=CAS3
  3. 在Springboot启动类中加上注解@EnableCasClient
    1
    2
    3
    4
    5
    6
    7
    8
    9
    @EnableCasClient
    @SpringBootApplication
    public class CasDemoApplication {

    public static void main(String[] args) {
    SpringApplication.run(CasDemoApplication.class, args);
    }

    }
  4. 添加测试Controller
    1
    2
    3
    4
    5
    6
    7
    8
    @RestController
    public class HelloController {

    @GetMapping("/hello")
    public String hello(){
    return "Hello CAS!";
    }
    }
  5. 启动程序并访问http://localhost:8080/hello, 发现浏览器可以正常跳转至cas登录页面, 但是会提示”Application Not Authorized to Use CAS”. 因为服务器默认启用的是https和imaps服务, 所以需要回到CAS 学习(一)–CAS Server 安装修改服务端.

配置服务端

  1. 修改application.xml内容为

    1
    2
    3
    4
    5
    6
    7
    8
    server:
    ssl:
    enabled: false

    cas:
    service-registry:
    core:
    init-from-json: true
  2. 需要在src/main/resources目录下创建services目录,新建HTTPSandIMAPS-10000001.json文件,内容如下

    1
    2
    3
    4
    5
    6
    7
    8
    {
    "@class" : "org.apereo.cas.services.RegexRegisteredService",
    "serviceId" : "^(https|http|imaps)://.*",
    "name" : "HTTPS and IMAPS",
    "id" : 10000001,
    "description" : "This service definition authorizes all application urls that support HTTPS and IMAPS protocols.",
    "evaluationOrder" : 10000
    }

    重启CAS Server并重新访问http://localhost:8080/hello, 发现任然提示”Application Not Authorized to Use CAS”错误信息. 此时需要调试程序查找原因

  3. 下载CAS Server代码进行远程调试, 端口号为5005, 发现CasServiceRegistryInitializationConfiguration.java中getServiceRegistryInitializerServices方法在验证资源文件时使用的ResourceUtils.doesResourceExist存在bug, 由于registry为Json时, location为services目录, 所以res.contentLength>0恒为false, 导致用户自定义的json文件永远不会被解压出来使用.

CasServiceRegistryInitializationConfiguration.java中检查资源文件调用的是ResourceUtils.doesResourceExist

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private Resource getServiceRegistryInitializerServicesDirectoryResource() {
val registry = casProperties.getServiceRegistry().getJson();
if (ResourceUtils.doesResourceExist(registry.getLocation())) {
LOGGER.debug("Using JSON service registry location [{}] for embedded service definitions", registry.getLocation());
return registry.getLocation();
}
val parent = new File(FileUtils.getTempDirectory(), "cas");
if (!parent.mkdirs()) {
LOGGER.warn("Unable to create folder [{}]", parent);
}
val resources = ResourcePatternUtils.getResourcePatternResolver(applicationContext)
.getResources("classpath*:/services/*.json");
Arrays.stream(resources)
.forEach(resource -> ResourceUtils.exportClasspathResourceToFile(parent, resource));
LOGGER.debug("Using service registry location [{}] for embedded service definitions", parent);
return new FileSystemResource(parent);
}

ResourceUtils.java中res.contentLength() > 0恒为false

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static boolean doesResourceExist(final Resource res) {
if (res == null) {
return false;
}
try {
IOUtils.read(res.getInputStream(), new byte[1]);
return res.contentLength() > 0;
} catch (final FileNotFoundException e) {
LOGGER.trace(e.getMessage());
return false;
} catch (final Exception e) {
LOGGER.trace(e.getMessage(), e);
return false;
}
}
  1. 修复bug后重新启动CAS Server并访问http://localhost:8080/hello,久违的登录页面终于出现了,输入用户名密码后能够成功跳转并输出Hello CAS!