• CAS单点登录:动态添加service(四)


    1.简介

    在CAS系统中,主要分为三部分,User、Web应用、SSO认证中心。

    User就是我们普通用户,Web应用就是需要接入SSO认证中心的应用也就是这里的Service,而SSO认证中心就是CAS服务端。

    简单来说就是CAS分为服务端和客户端,而Service就是指具体的多个客户端(CAS Clients)。

    我们整合客户端的时候,需要在cas服务端注册,使用的是json文件的方式。不是很方便,这里我们提供接口,动态操作。

    2.引入依赖

    修改pom.xml,如下:

    <dependency>
        <groupId>org.apereo.cas</groupId>
        <artifactId>cas-server-support-jpa-service-registry</artifactId>
        <version>${cas.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apereo.cas</groupId>
        <artifactId>cas-server-core-services-api</artifactId>
        <version>${cas.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apereo.cas</groupId>
        <artifactId>cas-server-core-authentication-attributes</artifactId>
        <version>${cas.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apereo.cas</groupId>
        <artifactId>cas-server-support-jdbc</artifactId>
        <version>${cas.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apereo.cas</groupId>
        <artifactId>cas-server-support-jdbc-drivers</artifactId>
        <version>${cas.version}</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.36</version>
    </dependency>

    排除war包自带的两个json,添加节点:dependentWarExcludes

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.6</version>
        <configuration>
            <warName>cas</warName>
            <failOnMissingWebXml>false</failOnMissingWebXml>
            <recompressZippedFiles>false</recompressZippedFiles>
            <archive>
                <compress>false</compress>
                <manifestFile>${manifestFileToUse}</manifestFile>
            </archive>
            <overlays>
                <overlay>
                    <groupId>org.apereo.cas</groupId>
                    <artifactId>cas-server-webapp${app.server}</artifactId>
                </overlay>
            </overlays>
            <dependentWarExcludes>
                **/services/*.json
            </dependentWarExcludes>
        </configuration>
    </plugin>

    3.application.properties添加以下属性

    第一次启动使用create-drop,二次运行时改为update

    ##
    # Jpa配置
    #
    cas.serviceRegistry.jpa.user=root
    cas.serviceRegistry.jpa.password=123456
    cas.serviceRegistry.jpa.driverClass=com.mysql.jdbc.Driver
    cas.serviceRegistry.jpa.url=jdbc:mysql://127.0.0.1:3306/cas?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
    cas.serviceRegistry.jpa.dialect=org.hibernate.dialect.MySQL5Dialect
    #连接池配置
    cas.serviceRegistry.jpa.pool.suspension=false
    cas.serviceRegistry.jpa.pool.minSize=6
    cas.serviceRegistry.jpa.pool.maxSize=18
    cas.serviceRegistry.jpa.pool.maxWait=2000
    cas.serviceRegistry.jpa.pool.timeoutMillis=1000
    #设置配置的服务,一直都有,不会给清除掉,第一次使用,需要配置为 create-drop
    #create-drop 重启cas服务的时候,就会给干掉
    #create  没有表就创建,有就不创建
    #none 一直都有
    #update 更新
    cas.serviceRegistry.jpa.ddlAuto=create-drop

    4.添加rest接口

    其实主要是使用ServiceManager中的接口,包名:org.apereo.cas.services.ServicesManager

    public interface ServicesManager {
        RegisteredService save(RegisteredService registeredService);
    
        RegisteredService save(RegisteredService registeredService, boolean publishEvent);
    
        void deleteAll();
    
        RegisteredService delete(long id);
    
        RegisteredService delete(RegisteredService svc);
    
        RegisteredService findServiceBy(String serviceId);
    
        RegisteredService findServiceBy(Service service);
    
        Collection<RegisteredService> findServiceBy(Predicate<RegisteredService> clazz);
    
        <T extends RegisteredService> T findServiceBy(Service serviceId, Class<T> clazz);
    
        <T extends RegisteredService> T findServiceBy(String serviceId, Class<T> clazz);
    
        RegisteredService findServiceBy(long id);
    
        Collection<RegisteredService> getAllServices();
    
        boolean matchesExistingService(Service service);
    
        boolean matchesExistingService(String service);
    
        Collection<RegisteredService> load();
    
        default int count() {
            return 0;
        }
    
        default Collection<RegisteredService> getServicesForDomain(String domain) {
            return this.getAllServices();
        }
    
        default Collection<String> getDomains() {
            return (Collection)Stream.of("default").collect(Collectors.toList());
        }
    }

     接口的具体实现类:

    import com.fdzang.cas.service.domain.ServiceDO;
    import com.fdzang.cas.service.framework.ApiResult;
    import com.fdzang.cas.service.framework.BaseController;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.collections4.CollectionUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.apereo.cas.services.RegexRegisteredService;
    import org.apereo.cas.services.RegisteredService;
    import org.apereo.cas.services.ReturnAllAttributeReleasePolicy;
    import org.apereo.cas.services.ServicesManager;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.web.bind.annotation.*;
    
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    @Slf4j
    @RestController
    @RequestMapping("/service")
    public class ServiceController extends BaseController {
    
        @Autowired
        @Qualifier("servicesManager")
        private ServicesManager servicesManager;
    
        @PostMapping
        public ApiResult addService(@RequestBody ServiceDO service) throws Exception {
            RegisteredService registeredService = findByServiceId(service.getServiceId());
            if (registeredService != null) {
                return fail("serviceId:" + service.getServiceId() + " 已存在");
            }
    
            RegexRegisteredService regexRegisteredService = covertService(service);
            servicesManager.save(regexRegisteredService, true);
            servicesManager.load();
    
            registeredService = findByServiceId(service.getServiceId());
    
            return ok(covertRegisteredService(registeredService));
        }
    
        @DeleteMapping
        public ApiResult delService(@RequestParam("serviceId") String serviceId) {
            boolean flag = false;
            RegisteredService registeredService = findByServiceId(serviceId);
            if (registeredService != null) {
                try {
                    servicesManager.delete(registeredService);
                } catch (Exception e) {
                    //这里会报审计错误,直接进行捕获即可,不影响删除逻辑
                    log.error(e.getMessage());
                }
                if (null == findByServiceId(serviceId)) {
                    servicesManager.load();
                    flag = true;
                }
            }else{
                return fail("serviceId:" + serviceId + " 不存在");
            }
    
            if (flag){
                return ok("删除成功");
            }else{
                return fail("删除失败");
            }
        }
    
        @GetMapping("/all")
        public ApiResult getAllService() {
            Collection<RegisteredService> allServices = servicesManager.getAllServices();
    
            return ok(covertRegisteredServiceList(allServices));
        }
    
        @GetMapping
        public ApiResult getByServiceId(@RequestParam("serviceId") String serviceId) {
            RegisteredService service = findByServiceId(serviceId);
            return ok(covertRegisteredService(service));
        }
    
        private ServiceDO covertRegisteredService(RegisteredService registeredService) {
            ServiceDO service = new ServiceDO();
    
            service.setServiceId(registeredService.getServiceId());
            service.setDescription(registeredService.getDescription());
            service.setEvaluationOrder(registeredService.getEvaluationOrder());
            service.setId(registeredService.getId());
            service.setName(registeredService.getName());
            service.setTheme(registeredService.getTheme());
    
            return service;
        }
    
        private List<ServiceDO> covertRegisteredServiceList(Collection<RegisteredService> registeredServices) {
            if (CollectionUtils.isEmpty(registeredServices)) {
                return null;
            }
            List<ServiceDO> services = new ArrayList<>();
            for (RegisteredService registeredService : registeredServices) {
                services.add(covertRegisteredService(registeredService));
            }
    
            return services;
        }
    
        private RegexRegisteredService covertService(ServiceDO service) throws Exception {
            RegexRegisteredService regexRegisteredService = new RegexRegisteredService();
    
            String serviceId = "^(https|imaps|http)://" + service.getServiceId() + ".*";
            ReturnAllAttributeReleasePolicy returnAllAttributeReleasePolicy = new ReturnAllAttributeReleasePolicy();
    
            regexRegisteredService.setServiceId(serviceId);
            regexRegisteredService.setId(service.getId());
            regexRegisteredService.setDescription(service.getDescription());
            regexRegisteredService.setEvaluationOrder(service.getEvaluationOrder());
            if (StringUtils.isNotBlank(service.getTheme())) {
                regexRegisteredService.setTheme(service.getTheme());
            }
            regexRegisteredService.setAttributeReleasePolicy(returnAllAttributeReleasePolicy);
            regexRegisteredService.setName(service.getName());
            regexRegisteredService.setLogoutUrl(new URL("http://" + service.getServiceId()));
    
            return regexRegisteredService;
        }
    
        public RegisteredService findByServiceId(String serviceId){
            RegisteredService service = null;
            serviceId = "http://" + serviceId;
            try {
                service = servicesManager.findServiceBy(serviceId);
            } catch (Exception e) {
                log.error(e.getMessage());
            }
    
            return service;
        }
    }

    这个地方,我自定义了ServiceDO用来数据的接收及展示。

    自定义了ApiResult,统一返回结果。

    5.添加包扫描配置

    cas项目,其实也是集成的Springboot,这里我们自定义注解完成包扫描工作,后续新的类加进来,无需再修改spring.factories

    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @ComponentScan("com.fdzang.cas")
    public class SpringConfig {
    }

    修改spring.factories,加入我们的包扫描配置。

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=
      org.apereo.cas.config.CasEmbeddedContainerTomcatConfiguration,
      org.apereo.cas.config.CasEmbeddedContainerTomcatFiltersConfiguration,
      com.fdzang.cas.service.config.SpringConfig

    参考:https://blog.csdn.net/qq_34021712/article/details/81638090

  • 相关阅读:
    数据库设计三大范式
    MYSQL语句
    PHP数据库环境配置
    java空心菱形
    java基础练习2
    java基础练习
    java 控制台输入
    java 基础功能
    Java包装
    JS里的DOM操作注意点
  • 原文地址:https://www.cnblogs.com/fdzang/p/12921388.html
Copyright © 2020-2023  润新知