首先,项目springboot使用了2.6.8版本,集成security的过程中,使用了比较严格的自定义策略,任何请求都需要认证和授权,判断用户是否有查询改接口的权限。并且提供了配置或者注解两种方式提供匿名访问的接口。

 第一种通过配置

 第二种使用自定义注解

 自己实现

AccessDecisionManager

FilterInvocationSecurityMetadataSource

 引起需要收集@Anonymous注解标注的controller。

于是就像参照spring启动扫描注解的方式实现,然后自定义了

 参照spring scan

/**

* 参照spring scan

* @author: Barry.Yu

* @date: 2022/9/30

* @desc: 自定义匿名访问扫描类

**/

@Slf4j

public class AnonymousScanRegistrar implements EnvironmentCapable, ImportBeanDefinitionRegistrar {

private static final String anonymousBeanName = "anonymousUrlServiceImpl";

private Set anonymousUrls = new HashSet<>();

static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";

private String resourcePattern = DEFAULT_RESOURCE_PATTERN;

@Nullable

private Environment environment;

@Nullable

private ResourcePatternResolver resourcePatternResolver;

@Nullable

private MetadataReaderFactory metadataReaderFactory;

private final Map> functionMap = new HashMap<>();

{

functionMap.put("org.springframework.web.bind.annotation.PostMapping",this::postFunction);

functionMap.put("org.springframework.web.bind.annotation.PutMapping",this::putFunction);

functionMap.put("org.springframework.web.bind.annotation.GetMapping",this::getFunction);

functionMap.put("org.springframework.web.bind.annotation.DeleteMapping",this::delFunction);

functionMap.put("org.springframework.web.bind.annotation.RequestMapping",this::requestFunction);

}

@Override

public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry){

AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(annotationMetadata.getAnnotationAttributes(AnonymousScan.class.getName()));

String[] basePackages = annoAttrs.getStringArray("basePackage");

for (String basePackage : basePackages) {

String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +

resolveBasePackage(basePackage) + '/' + this.resourcePattern;

try {

Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);

for (Resource resource : resources) {

MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);

createUrls(metadataReader.getClassMetadata().getClassName());

}

BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();

AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();

//beanDefinition的beanClass

beanDefinition.setBeanClass(AnonymousUrlServiceImpl.class);

ConstructorArgumentValues constructorArgumentValues = beanDefinition.getConstructorArgumentValues();

constructorArgumentValues.addIndexedArgumentValue(0, anonymousUrls);

registry.registerBeanDefinition(anonymousBeanName, beanDefinition);

} catch (IOException e) {

e.printStackTrace();

}

}

}

/**

* 构建所需要的匿名路径

* @param beanClassName

*/

private void createUrls(String beanClassName){

try {

Class aClass = Class.forName(beanClassName);

RequestMapping requestMapping = (RequestMapping) aClass.getAnnotation(RequestMapping.class);

if(requestMapping!=null){

String[] pathParents = requestMapping.value();

String[] paths = null;

Method[] methods = aClass.getMethods();

for (Method method : methods) {

Anonymous anonymous = method.getAnnotation(Anonymous.class);

if(anonymous!=null){

Annotation[] annotations = method.getAnnotations();

for (Annotation annotation : annotations) {

Function methodFunction = functionMap.get(annotation.annotationType().getName());

if(methodFunction!=null){

paths = methodFunction.apply(method);

break;

}

}

if(paths!=null && paths.length>0){

for (String pathParent : pathParents) {

for (String path : paths) {

anonymousUrls.add( pathParent + path);

}

}

}

paths = null;

}

}

}

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

private String[] postFunction(Method method){

return method.getAnnotation(PostMapping.class).value();

}

private String[] getFunction(Method method){

return method.getAnnotation(GetMapping.class).value();

}

private String[] putFunction(Method method){

return method.getAnnotation(PutMapping.class).value();

}

private String[] delFunction(Method method){

return method.getAnnotation(DeleteMapping.class).value();

}

private String[] requestFunction(Method method){

return method.getAnnotation(RequestMapping.class).value();

}

public final MetadataReaderFactory getMetadataReaderFactory() {

if (this.metadataReaderFactory == null) {

this.metadataReaderFactory = new CachingMetadataReaderFactory();

}

return this.metadataReaderFactory;

}

private ResourcePatternResolver getResourcePatternResolver() {

if (this.resourcePatternResolver == null) {

this.resourcePatternResolver = new PathMatchingResourcePatternResolver();

}

return this.resourcePatternResolver;

}

protected String resolveBasePackage(String basePackage) {

return ClassUtils.convertClassNameToResourcePath(getEnvironment().resolveRequiredPlaceholders(basePackage));

}

@Override

public Environment getEnvironment() {

if (this.environment == null) {

this.environment = new StandardEnvironment();

}

return this.environment;

}

public Set getAnonymousUrls(){

return anonymousUrls;

}

}

启动类上加上

 

参考阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。