Springboot集成security,自定义@Anonymous标签实现免登录,免鉴权

这篇具有很好参考价值的文章主要介绍了Springboot集成security,自定义@Anonymous标签实现免登录,免鉴权。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

springsecurity绕过登录,spring boot,后端,java

 第一种通过配置springsecurity绕过登录,spring boot,后端,java

 第二种使用自定义注解

springsecurity绕过登录,spring boot,后端,java

 自己实现

AccessDecisionManager

FilterInvocationSecurityMetadataSource

springsecurity绕过登录,spring boot,后端,java

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

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

springsecurity绕过登录,spring boot,后端,java

 参照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<String> 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<String, Function<Method,String[]>> 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<Method, String[]> 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<String> getAnonymousUrls(){
        return anonymousUrls;
    }
}

启动类上加上

springsecurity绕过登录,spring boot,后端,java

 文章来源地址https://www.toymoban.com/news/detail-742338.html

到了这里,关于Springboot集成security,自定义@Anonymous标签实现免登录,免鉴权的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【SpringBoot】集成SpringSecurity+JWT实现多服务单点登录,原来这么easy

    Spring Boot+Spring Security+JWT实现单点登录 介绍: 单点登录(SingleSignOn,SSO) ,当用户在身份 认证服务器 上登录一次以后,即可 获得访问单点登录系统中其他关联系统和应用软件的权限 ,同时这种实现是不需要管理员对用户的登录状态或其他信息进行修改的,这意味着在多个应用

    2024年02月02日
    浏览(46)
  • 在 Spring Security 中定义多种登录方式,比如邮箱、手机验证码登录

    现在各大网站登录的方式是越来越多。比如:传统的用户名密码登录、快捷的邮箱、手机验证码登录,还有流行的第三方登录。那本篇呢,就给大家带来如何在 Spring Security 中定义使用邮箱验证码登录方式。看完本篇,让你学会自定义认证方式,如果公司还需要使用手机验证

    2024年02月11日
    浏览(43)
  • Spring Security6入门及自定义登录

    Spring Security已经更新到了6.x,很多常见的方法都废弃了,并且将在未来的 Spring Security7 中移除,主要总结几点变化。 本文代码环境jdk版本17、boot版本3.1.2、security6.1.2 准确来说,Spring Security 是在 5.7.0-M2 这个版本中将 WebSecurityConfigurerAdapter 过期的,过期的原因是因为官方想要鼓

    2024年02月14日
    浏览(35)
  • SpringBoot【集成 jasypt】实现配置信息自定义加解密(自定义的属性探测和密码解析器)

    Jasypt是一个Java简易加密库,用于加密配置文件中的敏感信息,如数据库密码。它可以帮助开发人员在应用程序中加密密码、敏感信息和数据通信,还包括高安全性、基于标准的加密技术、可同时单向和双向加密的加密密码、文本、数字和二进制文件。如果您正在使用Spring B

    2024年02月05日
    浏览(52)
  • Java21 + SpringBoot3集成easy-captcha实现验证码显示和登录校验

    近日心血来潮想做一个开源项目,目标是做一款可以适配多端、功能完备的模板工程,包含后台管理系统和前台系统,开发者基于此项目进行裁剪和扩展来完成自己的功能开发。 本项目为前后端分离开发,后端基于 Java21 和 SpringBoot3 开发,后端使用 Spring Security 、 JWT 、 Spr

    2024年01月23日
    浏览(62)
  • 【深入浅出Spring Security(五)】自定义过滤器进行前后端登录认证

    在【深入浅出Spring Security(二)】Spring Security的实现原理 中小编阐述了默认加载的过滤器,里面有些过滤器有时并不能满足开发中的实际需求,这个时候就需要我们自定义过滤器,然后填入或者替换掉原先存在的过滤器。 首先阐述一下添加过滤器的四个方法(都是 HttpSecur

    2024年02月08日
    浏览(45)
  • SpringBoot2.3集成Spring Security(二) JWT认证

    紧接上文,我们已经完成了 SpringBoot中集成Spring Security,并且用户名帐号和密码都是从数据库中获取。但是这种方式还是不能满足现在的开发需求。 使用JWT的好处: 无状态认证:JWT本身包含了认证信息和声明,服务器不需要在会话中保存任何状态。这样使得应用程序可以更加

    2024年02月11日
    浏览(58)
  • 【Java】SpringBoot集成P6spy,实现自定义SQL日志打印

    在项目中对数据库中进行操作调试的时候,最重要的一个功能就是 SQL打印 。 如果使用Mybatis-plus的话,他会自带一个SQL打印的功能。虽然它可以打印,但我觉得还不够优雅,因为包含着很多我们不需要的信息,所以这篇文章实现一下在代码中优雅的打印SQL。 P6Spy 是针对数据库

    2024年02月16日
    浏览(53)
  • Springboot Security 认证鉴权——使用JSON格式参数登录

    在 Spring Security 中,默认的登陆方式是以表单形式进行提交参数的。可以参考前面的几篇文章,但是在前后端分离的项目,前后端都是以 JSON 形式交互的。一般不会使用表单形式提交参数。所以,在 Spring Security 中如果要使用 JSON 格式登录,需要自己来实现。那本文介绍两种方

    2024年02月04日
    浏览(34)
  • 前端Vue自定义验证码密码登录切换tabs选项卡标签栏标题栏 验证码登录模版 密码登录模版

    前端Vue自定义验证码密码登录切换tabs选项卡标签栏标题栏 验证码登录模版 密码登录模版, 请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13221 效果图如下: 实现代码如下: 使用方法 HTML代码实现部分 组件实现代码

    2024年02月11日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包