博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cas5.3.2单点登录-动态添加services(十三)
阅读量:3784 次
发布时间:2019-05-22

本文共 25343 字,大约阅读时间需要 84 分钟。

原文地址,转载请注明出处:      © 

前面我们整合客户端的时候,需要在cas服务端注册,使用的是json文件的方式,更简单的一点,直接配置为只要是http或者https的请求,都表示注册,那也就没有本篇的动态添加services了,哈哈 不过,这也是一个不错的方法。

假如,我们以域名配置的,比如: 注册,那么又有新的模块为 我们总不能每次修改配置,重启cas服务吧。这很不现实,官网给出了如下的解决方式,将数据库来存储这些数据。

具体参考官网

配置过程

pom添加依赖

org.apereo.cas
cas-server-support-jpa-service-registry
${cas.version}
org.apereo.cas
cas-server-core-services-api
${cas.version}
org.apereo.cas
cas-server-core-authentication-attributes
${cas.version}

application.properties添加以下属性

#数据库用户名cas.serviceRegistry.jpa.user=root#数据库密码cas.serviceRegistry.jpa.password=123456#mysql驱动cas.serviceRegistry.jpa.driverClass=com.mysql.jdbc.Driver#数据库连接cas.serviceRegistry.jpa.url=jdbc:mysql://127.0.0.1:3306/testshiro?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=falsecas.serviceRegistry.dialect=org.hibernate.dialect.MySQLDialect#连接池配置cas.serviceRegistry.jpa.pool.suspension=falsecas.serviceRegistry.jpa.pool.minSize=6cas.serviceRegistry.jpa.pool.maxSize=18cas.serviceRegistry.jpa.pool.maxWait=2000cas.serviceRegistry.jpa.pool.timeoutMillis=1000#默认为create-drop,表示每次启动服务都会清除你之前注册的cas服务cas.serviceRegistry.jpa.ddlAuto=create-drop

修改service/HTTPSandIMAPS-10000001.json

为了方便测试,将服务注册只允许app1.cas.com

{  "@class" : "org.apereo.cas.services.RegexRegisteredService",  "serviceId" : "^(https|imaps|http)://app1.cas.com.*",  "name" : "测试客户端",  "id" : 10000001,  "description" : "这是一个测试客户端的服务,所有的https访问都允许通过",  "evaluationOrder" : 10000}

增加http接口,操作数据库添加或删除service

这里为了方便直接在地址栏操作增加或删除。代码如下:

package com.wangsaichao.cas.controller;import org.apereo.cas.services.*;import org.json.JSONObject;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import java.net.URL;/** * @author: wangsaichao * @date: 2018/8/10 * @description: */@RestControllerpublic class ServiceController {
private Logger logger = LoggerFactory.getLogger(ServiceController.class); @Autowired @Qualifier("servicesManager") private ServicesManager servicesManager; /** * 注册service * @param serviceId 域名 * @param id 顺序 * @return */ @RequestMapping(value = "/addClient/{serviceId}/{id}",method = RequestMethod.GET) public Object addClient(@PathVariable("serviceId") String serviceId, @PathVariable("id") int id) { try { String a="^(https|imaps|http)://"+serviceId+".*"; RegexRegisteredService service = new RegexRegisteredService(); ReturnAllAttributeReleasePolicy re = new ReturnAllAttributeReleasePolicy(); service.setServiceId(a); service.setId(id); service.setAttributeReleasePolicy(re); service.setName("login"); //这个是为了单点登出而作用的 service.setLogoutUrl(new URL("http://"+serviceId)); servicesManager.save(service); //执行load让他生效 servicesManager.load(); ReturnMessage returnMessage = new ReturnMessage(); returnMessage.setCode(200); returnMessage.setMessage("添加成功"); return returnMessage; } catch (Exception e) { logger.error("注册service异常",e); ReturnMessage returnMessage = new ReturnMessage(); returnMessage.setCode(500); returnMessage.setMessage("添加失败"); return returnMessage; } } /** * 删除service异常 * @param serviceId * @return */ @RequestMapping(value = "/deleteClient/{serviceId}/{id}",method = RequestMethod.GET) public Object deleteClient(@PathVariable("serviceId") String serviceId,@PathVariable("id") int id) { try {// String a="^(https|imaps|http)://"+serviceId+".*";// String a="^(https|imaps|http)://"+serviceId+".*";// RegexRegisteredService service = new RegexRegisteredService();// ReturnAllAttributeReleasePolicy re = new ReturnAllAttributeReleasePolicy();// service.setServiceId(a);// service.setId(id);// service.setAttributeReleasePolicy(re);// service.setName("login");// //这个是为了单点登出而作用的// service.setLogoutUrl(new URL("http://"+serviceId)); String aa = "http://app2.cas.com:8082"; RegisteredService service = servicesManager.findServiceBy(aa); servicesManager.delete(service); //执行load生效 servicesManager.load(); ReturnMessage returnMessage = new ReturnMessage(); returnMessage.setCode(200); returnMessage.setMessage("删除成功"); return returnMessage; } catch (Exception e) { logger.error("删除service异常",e); ReturnMessage returnMessage = new ReturnMessage(); returnMessage.setCode(500); returnMessage.setMessage("删除失败"); return returnMessage; } } public class ReturnMessage{
private Integer code; private String message; public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }}

启动服务

1.启动服务报错

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘type=MyISAM’ at line 5

这里写图片描述
原因是上面的配置:cas.serviceRegistry.dialect=org.hibernate.dialect.MySQLDialect 应该改为:
cas.serviceRegistry.dialect=org.hibernate.dialect.MySQL5Dialect

2.停止服务,将会删除之前创建的service

为了避免重启服务,导致之前的services丢失,需要将

cas.serviceRegistry.jpa.ddlAuto=update
每次启动之后,会在mysql中自动生成以下表格
这里写图片描述

测试过程中的问题

在添加service的时候没问题,但是在删除service的时候报以下异常:

java.lang.IllegalArgumentException: ‘actionPerformed’ cannot be null.
Check the correctness of @Audit annotation at the following audit point: execution(public synchronized org.apereo.cas.services.RegisteredService
经过debug发现,代码其实是没问题的,可以正常删除,但是在执行AuditTrailManagementAspect类中下面这段代码的时候报异常:
这里写图片描述
我们发现auditActionResolver和auditResourceResolver是null,经过搜索,找到了下面这篇文章,在此感谢作者,博客地址:

原文如下:

搜了一下Audit这玩意叫什么审计日志,google了半天也没看到源码(github上面有个,但cas的应该是在此基础上修改过的),无奈之下看了 WEB-INF/spring-configuration/auditTrailContext.xml 这个文件,这才发现,里面根本就没有 DELETE_SERVICE_ACTION_RESOLVER和DELETE_SERVICE_RESOURCE_RESOLVER这两个值对应的Resolver。。。 这可能跟cas的版本或者编译情况有关,真是不明白为什么save方法有但是delete方法就没有了,在这上面卡了好久。

解决办法:

因为我用的是cas5.3.2是springboot版本的,已经没有文中所说的那个文件了,通过查看源码,打算使用以下方式解决。

自定义starter,跟之前自定义cas-client-starter一样。中间整合的过程,出现很多错误,没有一步一步,记录,到时候请看源码。只是依赖了原始audit的api包,至于下面的CasCoreAuditConfiguration类是从原始cas-server-core-audit包中拷贝出来的,然后需要自定义一个cas-server-core-audit的starter包来覆盖原来的包,这个包必须也叫cas-server-core-audit因为在cas-server-webapp${app.server}中依赖了这个包,并且scope是runtime类型的,没办法,只能写一个一模一样的包了。

自定义cas-server-core-audit包

pom.xml

4.0.0
org.apereo.cas
cas-server-core-audit
5.3.2
jar
cas-server-core-audit
cas-server-core-audit
org.springframework.boot
spring-boot-starter-parent
2.0.0.RELEASE
5.3.2
org.springframework.boot
spring-boot-configuration-processor
true
org.springframework.boot
spring-boot-autoconfigure
org.apereo.cas
cas-server-core-api-configuration-model
${cas.version}
org.apereo.cas
cas-server-core-util-api
${cas.version}
org.apereo.cas
cas-server-core-audit-api
${cas.version}
org.aspectj
aspectjrt
1.9.1
javax.servlet
servlet-api
2.5
org.apache.maven.plugins
maven-compiler-plugin
3.5.1
1.8
1.8
maven-source-plugin
2.1
true
compile
jar

CasCoreAuditConfiguration.java

package org.apereo.cas.audit.spi.config;import org.apache.commons.lang3.StringUtils;import org.apereo.cas.audit.*;import org.apereo.cas.audit.spi.*;import org.apereo.cas.configuration.CasConfigurationProperties;import org.apereo.cas.configuration.model.core.audit.AuditProperties;import org.apereo.cas.configuration.model.core.audit.AuditSlf4jLogProperties;import org.apereo.cas.util.CollectionUtils;import org.apereo.inspektr.audit.AuditTrailManagementAspect;import org.apereo.inspektr.audit.spi.AuditActionResolver;import org.apereo.inspektr.audit.spi.AuditResourceResolver;import org.apereo.inspektr.audit.spi.support.DefaultAuditActionResolver;import org.apereo.inspektr.audit.support.Slf4jLoggingAuditTrailManager;import org.apereo.inspektr.common.spi.PrincipalResolver;import org.apereo.inspektr.common.web.ClientInfoThreadLocalFilter;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;import org.springframework.boot.context.properties.EnableConfigurationProperties;import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.EnableAspectJAutoProxy;import org.springframework.core.Ordered;import org.springframework.core.annotation.AnnotationAwareOrderComparator;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/** * This is {@link CasCoreAuditConfiguration}. * * @author Misagh Moayyed * @since 5.0.0 */@Configuration("casCoreAuditConfiguration")@EnableAspectJAutoProxy@EnableConfigurationProperties(CasConfigurationProperties.class)public class CasCoreAuditConfiguration implements AuditTrailExecutionPlanConfigurer, AuditTrailRecordResolutionPlanConfigurer {
private static final Logger LOGGER = LoggerFactory.getLogger(CasCoreAuditConfiguration.class); private static final String AUDIT_ACTION_SUFFIX_FAILED = "_FAILED"; @Autowired private CasConfigurationProperties casProperties; @Autowired private ApplicationContext applicationContext; @Bean public AuditTrailManagementAspect auditTrailManagementAspect(@Qualifier("auditTrailExecutionPlan") final AuditTrailExecutionPlan auditTrailExecutionPlan, @Qualifier("auditTrailRecordResolutionPlan") final AuditTrailRecordResolutionPlan auditTrailRecordResolutionPlan) { final AuditTrailManagementAspect aspect = new AuditTrailManagementAspect( casProperties.getAudit().getAppCode(), auditablePrincipalResolver(auditPrincipalIdProvider()), auditTrailExecutionPlan.getAuditTrailManagers(), auditTrailRecordResolutionPlan.getAuditActionResolvers(), auditTrailRecordResolutionPlan.getAuditResourceResolvers()); aspect.setFailOnAuditFailures(!casProperties.getAudit().isIgnoreAuditFailures()); return aspect; } @Autowired @ConditionalOnMissingBean(name = "auditTrailRecordResolutionPlan") @Bean public AuditTrailRecordResolutionPlan auditTrailRecordResolutionPlan(final List
configurers) { final DefaultAuditTrailRecordResolutionPlan plan = new DefaultAuditTrailRecordResolutionPlan(); configurers.forEach(c -> { final String name = StringUtils.removePattern(c.getClass().getSimpleName(), "\\$.+"); LOGGER.debug("Registering audit trail manager [{}]", name); c.configureAuditTrailRecordResolutionPlan(plan); }); return plan; } @Autowired @ConditionalOnMissingBean(name = "auditTrailExecutionPlan") @Bean public AuditTrailExecutionPlan auditTrailExecutionPlan(final List
configurers) { final DefaultAuditTrailExecutionPlan plan = new DefaultAuditTrailExecutionPlan(); configurers.forEach(c -> { final String name = StringUtils.removePattern(c.getClass().getSimpleName(), "\\$.+"); LOGGER.debug("Registering audit trail manager [{}]", name); c.configureAuditTrailExecutionPlan(plan); }); return plan; } @Bean public FilterRegistrationBean casClientInfoLoggingFilter() { final AuditProperties audit = casProperties.getAudit(); final FilterRegistrationBean bean = new FilterRegistrationBean(); bean.setFilter(new ClientInfoThreadLocalFilter()); bean.setUrlPatterns(CollectionUtils.wrap("/*")); bean.setName("CAS Client Info Logging Filter"); bean.setAsyncSupported(true); bean.setOrder(Ordered.HIGHEST_PRECEDENCE); final Map
initParams = new HashMap<>(); if (StringUtils.isNotBlank(audit.getAlternateClientAddrHeaderName())) { initParams.put(ClientInfoThreadLocalFilter.CONST_IP_ADDRESS_HEADER, audit.getAlternateClientAddrHeaderName()); } if (StringUtils.isNotBlank(audit.getAlternateServerAddrHeaderName())) { initParams.put(ClientInfoThreadLocalFilter.CONST_SERVER_IP_ADDRESS_HEADER, audit.getAlternateServerAddrHeaderName()); } initParams.put(ClientInfoThreadLocalFilter.CONST_USE_SERVER_HOST_ADDRESS, String.valueOf(audit.isUseServerHostAddress())); bean.setInitParameters(initParams); return bean; } @ConditionalOnMissingBean(name = "deleteServiceActionResolver") @Bean public AuditActionResolver deleteServiceActionResolver() { return new DeleteServiceActionResolver(); } @ConditionalOnMissingBean(name = "deleteServiceResourceResolver") @Bean public AuditResourceResolver deleteServiceResourceResolver() { return new DeleteServiceResourceResolver(); } @ConditionalOnMissingBean(name = "authenticationActionResolver") @Bean public AuditActionResolver authenticationActionResolver() { return new DefaultAuditActionResolver("_SUCCESS", AUDIT_ACTION_SUFFIX_FAILED); } @ConditionalOnMissingBean(name = "ticketCreationActionResolver") @Bean public AuditActionResolver ticketCreationActionResolver() { return new DefaultAuditActionResolver("_CREATED", "_NOT_CREATED"); } @ConditionalOnMissingBean(name = "ticketValidationActionResolver") @Bean public AuditActionResolver ticketValidationActionResolver() { return new DefaultAuditActionResolver("D", AUDIT_ACTION_SUFFIX_FAILED); } @ConditionalOnMissingBean(name = "returnValueResourceResolver") @Bean public AuditResourceResolver returnValueResourceResolver() { return new ShortenedReturnValueAsStringResourceResolver(); } @ConditionalOnMissingBean(name = "nullableReturnValueResourceResolver") @Bean public AuditResourceResolver nullableReturnValueResourceResolver() { return new NullableReturnValueAuditResourceResolver(returnValueResourceResolver()); } @ConditionalOnMissingBean(name = "serviceAccessEnforcementAuditResourceResolver") @Bean public ServiceAccessEnforcementAuditResourceResolver serviceAccessEnforcementAuditResourceResolver() { return new ServiceAccessEnforcementAuditResourceResolver(); } /** * Extension point for deployers to define custom AuditActionResolvers to extend the stock resolvers. * * @return the map */ @ConditionalOnMissingBean(name = "customAuditActionResolverMap") @Bean public Map
customAuditActionResolverMap() { return new HashMap<>(0); } /** * Extension point for deployers to define custom AuditResourceResolvers to extend the stock resolvers. * * @return the map */ @ConditionalOnMissingBean(name = "customAuditResourceResolverMap") @Bean public Map
customAuditResourceResolverMap() { return new HashMap<>(0); } @ConditionalOnMissingBean(name = "auditablePrincipalResolver") @Bean public PrincipalResolver auditablePrincipalResolver(@Qualifier("auditPrincipalIdProvider") final AuditPrincipalIdProvider auditPrincipalIdProvider) { return new ThreadLocalPrincipalResolver(auditPrincipalIdProvider); } @ConditionalOnMissingBean(name = "ticketResourceResolver") @Bean public AuditResourceResolver ticketResourceResolver() { return new TicketAsFirstParameterResourceResolver(); } @ConditionalOnMissingBean(name = "ticketValidationResourceResolver") @Bean public AuditResourceResolver ticketValidationResourceResolver() { final AuditProperties audit = casProperties.getAudit(); if (audit.isIncludeValidationAssertion()) { return new TicketValidationResourceResolver(); } return ticketResourceResolver(); } @ConditionalOnMissingBean(name = "messageBundleAwareResourceResolver") @Bean public AuditResourceResolver messageBundleAwareResourceResolver() { return new MessageBundleAwareResourceResolver(applicationContext); } @ConditionalOnMissingBean(name = "auditPrincipalIdProvider") @Bean public AuditPrincipalIdProvider auditPrincipalIdProvider() { final Map
resolvers = applicationContext.getBeansOfType(AuditPrincipalIdProvider.class, false, true); final List
providers = new ArrayList<>(resolvers.values()); AnnotationAwareOrderComparator.sort(providers); return new ChainingAuditPrincipalIdProvider(providers); } @Override public void configureAuditTrailExecutionPlan(final AuditTrailExecutionPlan plan) { final AuditSlf4jLogProperties audit = casProperties.getAudit().getSlf4j(); final Slf4jLoggingAuditTrailManager slf4j = new Slf4jLoggingAuditTrailManager(); slf4j.setUseSingleLine(audit.isUseSingleLine()); slf4j.setEntrySeparator(audit.getSinglelineSeparator()); slf4j.setAuditFormat(audit.getAuditFormat()); plan.registerAuditTrailManager(slf4j); } @Override public void configureAuditTrailRecordResolutionPlan(final AuditTrailRecordResolutionPlan plan) { final AuditActionResolver deleteServiceActionResolver = deleteServiceActionResolver(); plan.registerAuditActionResolver("DELETE_SERVICE_ACTION_RESOLVER",deleteServiceActionResolver); final AuditResourceResolver deleteServiceResourceResolver = deleteServiceResourceResolver(); plan.registerAuditResourceResolver("DELETE_SERVICE_RESOURCE_RESOLVER",deleteServiceResourceResolver); /* Add audit action resolvers here. */ final AuditActionResolver resolver = authenticationActionResolver(); plan.registerAuditActionResolver("AUTHENTICATION_RESOLVER", resolver); plan.registerAuditActionResolver("SAVE_SERVICE_ACTION_RESOLVER", resolver); final AuditActionResolver defResolver = new DefaultAuditActionResolver(); plan.registerAuditActionResolver("DESTROY_TICKET_GRANTING_TICKET_RESOLVER", defResolver); plan.registerAuditActionResolver("DESTROY_PROXY_GRANTING_TICKET_RESOLVER", defResolver); final AuditActionResolver cResolver = ticketCreationActionResolver(); plan.registerAuditActionResolver("CREATE_PROXY_GRANTING_TICKET_RESOLVER", cResolver); plan.registerAuditActionResolver("GRANT_SERVICE_TICKET_RESOLVER", cResolver); plan.registerAuditActionResolver("GRANT_PROXY_TICKET_RESOLVER", cResolver); plan.registerAuditActionResolver("CREATE_TICKET_GRANTING_TICKET_RESOLVER", cResolver); final AuditActionResolver authResolver = new DefaultAuditActionResolver("_TRIGGERED", StringUtils.EMPTY); plan.registerAuditActionResolver("AUTHENTICATION_EVENT_ACTION_RESOLVER", authResolver); plan.registerAuditActionResolver("VALIDATE_SERVICE_TICKET_RESOLVER", ticketValidationActionResolver()); final AuditActionResolver serviceAccessResolver = new DefaultAuditActionResolver("_TRIGGERED", StringUtils.EMPTY); plan.registerAuditActionResolver("SERVICE_ACCESS_ENFORCEMENT_ACTION_RESOLVER", serviceAccessResolver); /* Add audit resource resolvers here. */ plan.registerAuditResourceResolver("AUTHENTICATION_RESOURCE_RESOLVER", new CredentialsAsFirstParameterResourceResolver()); final AuditResourceResolver messageBundleAwareResourceResolver = messageBundleAwareResourceResolver(); plan.registerAuditResourceResolver("CREATE_TICKET_GRANTING_TICKET_RESOURCE_RESOLVER", messageBundleAwareResourceResolver); plan.registerAuditResourceResolver("CREATE_PROXY_GRANTING_TICKET_RESOURCE_RESOLVER", messageBundleAwareResourceResolver); final AuditResourceResolver ticketResourceResolver = ticketResourceResolver(); plan.registerAuditResourceResolver("DESTROY_TICKET_GRANTING_TICKET_RESOURCE_RESOLVER", ticketResourceResolver); plan.registerAuditResourceResolver("DESTROY_PROXY_GRANTING_TICKET_RESOURCE_RESOLVER", ticketResourceResolver); plan.registerAuditResourceResolver("GRANT_SERVICE_TICKET_RESOURCE_RESOLVER", new ServiceResourceResolver()); plan.registerAuditResourceResolver("GRANT_PROXY_TICKET_RESOURCE_RESOLVER", new ServiceResourceResolver()); plan.registerAuditResourceResolver("VALIDATE_SERVICE_TICKET_RESOURCE_RESOLVER", ticketValidationResourceResolver()); plan.registerAuditResourceResolver("SAVE_SERVICE_RESOURCE_RESOLVER", returnValueResourceResolver()); plan.registerAuditResourceResolver("AUTHENTICATION_EVENT_RESOURCE_RESOLVER", nullableReturnValueResourceResolver()); plan.registerAuditResourceResolver("SERVICE_ACCESS_ENFORCEMENT_RESOURCE_RESOLVER", serviceAccessEnforcementAuditResourceResolver()); /* Add custom resolvers here. */ plan.registerAuditActionResolvers(customAuditActionResolverMap()); plan.registerAuditResourceResolvers(customAuditResourceResolverMap()); }}

DeleteServiceActionResolver.java

package org.apereo.cas.audit.spi.config;import org.apereo.inspektr.audit.annotation.Audit;import org.apereo.inspektr.audit.spi.support.AbstractSuffixAwareAuditActionResolver;import org.aspectj.lang.JoinPoint;/** * @author: wangsaichao * @date: 2018/8/10 * @description: */public class DeleteServiceActionResolver extends AbstractSuffixAwareAuditActionResolver {
/** * Constructs the resolver with empty values for the two suffixes. */ public DeleteServiceActionResolver() { this("",""); } /** * Constructs the {@link DeleteServiceActionResolver} with a success suffix and failure * suffix. CANNOT be NULL. * @param successSuffix the suffix to use in the event of a success. * @param failureSuffix the suffix to use in the event of a failure. */ public DeleteServiceActionResolver(final String successSuffix, final String failureSuffix) { super(successSuffix, failureSuffix); } @Override public String resolveFrom(final JoinPoint auditableTarget, final Object retval, final Audit audit) { return audit.action() + getSuccessSuffix(); } @Override public String resolveFrom(final JoinPoint auditableTarget, final Exception exception, final Audit audit) { return audit.action() + getFailureSuffix(); }}

DeleteServiceResourceResolver.java

package org.apereo.cas.audit.spi.config;import org.apereo.inspektr.audit.spi.AuditResourceResolver;import org.aspectj.lang.JoinPoint;/** * @author: wangsaichao * @date: 2018/8/10 * @description: */public class DeleteServiceResourceResolver implements AuditResourceResolver {
@Override public String[] resolveFrom(JoinPoint target, Object returnValue) { return new String[0]; } @Override public String[] resolveFrom(JoinPoint target, Exception exception) { return new String[0]; }}

最后在resource/META-INFO/spring.factories文件中添加如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.apereo.cas.audit.spi.config.CasCoreAuditConfiguration

测试

因为我们配置的是app1.cas.com.启动cas服务端,启动两个客户端,这时访问app1.cas.com是可以登录成功的,使用app2.cas.com登录时未授权的服务.动态添加service之后,就可以了,也可以删除。删除之后,已登录的服务不会强制退出,退出后重新登录,就不能登录了,演示结果如下:

这里写图片描述

你可能感兴趣的文章
SpringCloud Sleuth 分布式请求链路
查看>>
SpringCloud Alibaba Nacos 服务注册和配置中心
查看>>
poi读写Excel
查看>>
使用Security安全框架实现权限登录
查看>>
JDBC工具类 使用Durid连接池链接MySQL数据库
查看>>
ANSYS——模态提取方法简介
查看>>
ANSYS——初学路径之路径的定义、作用以及ansys路径模块GUI的操作解释
查看>>
ANSYS——网格划分的不同方法以及GUI模块的操作(自由网格、映射网格、扫掠、拖拉)
查看>>
ANSYS——命令流学习(材料属性设置、建模的命令流)
查看>>
ANSYS——杆单元简介与示例(含新版本2019版本杆实常数设置、ANSYS help的使用、单元列表使用的举例)
查看>>
ANSYS——后处理中单元表(ELEMENT table)的作用、创建、使用
查看>>
在VScode上配置golang的开发环境
查看>>
leetcode每日一题---680. 验证回文字符串 Ⅱ
查看>>
leetcode每日一题---15. 三数之和
查看>>
leetcode每日一题---面试题 16.18. 模式匹配
查看>>
地主的钱袋
查看>>
招新成绩统计
查看>>
webpack
查看>>
go部署
查看>>
配置swagger--go语言
查看>>