广告
返回顶部
首页 > 资讯 > 后端开发 > JAVA >Ruo-Yi 前后端分离如何不登录直接访问以及一种基于配置文件实现的方式
  • 888
分享到

Ruo-Yi 前后端分离如何不登录直接访问以及一种基于配置文件实现的方式

java 2023-09-07 13:09:50 888人浏览 薄情痞子
摘要

Ruo-Yi 前后端分离如何不登录直接访问 问题 ​ 我们从若依项目的简介中可以知道,若依前后端分离系统采用了spring Security作为权限校验框架,那么,如果我们想要不登录就可以访问某些页面

Ruo-Yi 前后端分离如何不登录直接访问

问题

​ 我们从若依项目的简介中可以知道,若依前后端分离系统采用了spring Security作为权限校验框架,那么,如果我们想要不登录就可以访问某些页面应该怎么办?

分析

​ 若依官网的解释:若依官网解释

​ 有关spring security配置的东西若依框架都在SecurityConfig类里面有写。找到configure()方法,一般这个类里面会写。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eQGlma5G-1666317952035)(Ruo-Yi 前后端分离如何不登录直接访问.assets/image-20221021092551886.png)]

这里的意思就是 permitAllUrl.getUrls()集合 里面的路径因为后面设置了permitAll()用户可以任意访问。所以我们要想某些路径不登陆就可以访问,其实只需要我们的不登陆像访问的路径在 permitAllUrl.getUrls()集合里面即可。

# 若依原作者的注释* anyRequest          |   匹配所有请求路径* access              |   SpringEl表达式结果为true时可以访问* anonymous           |   匿名可以访问* denyAll             |   用户不能访问* fullyAuthenticated  |   用户完全认证可以访问(非remember-me下自动登录)* hasAnyAuthority     |   如果有参数,参数表示权限,则其中任何一个权限可以访问* hasAnyRole          |   如果有参数,参数表示角色,则其中任何一个角色可以访问* hasAuthority        |   如果有参数,参数表示权限,则其权限可以访问* hasIpAddress        |   如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问* hasRole             |   如果有参数,参数表示角色,则其角色可以访问* permitAll           |   用户可以任意访问* rememberMe          |   允许通过remember-me登录的用户访问* authenticated       |   用户登录后可访问

SecurityConfig 类里面有如下代码:

@Autowiredprivate PermitAllUrlProperties permitAllUrl;

permitAllUrl 是从这里注入进来的,想要知道怎么不登陆就可以访问,就必须分析类PermitAllUrlProperties

PermitAllUrlProperties 类

这个类有@Configuration注解,代表这个类是已启动就被注册到 spring 容器里面。

package com.ruoyi.framework.config.properties;import com.ruoyi.common.annotation.Anonymous;import org.apache.commons.lang3.RegExUtils;import org.springframework.beans.BeansException;import org.springframework.beans.factory.InitializingBean;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.context.annotation.Configuration;import org.springframework.core.annotation.AnnotationUtils;import org.springframework.WEB.method.HandlerMethod;import org.springframework.web.servlet.mvc.method.RequestMappingInfo;import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.Optional;import java.util.regex.Pattern;@Configurationpublic class PermitAllUrlProperties implements InitializingBean, ApplicationContextAware{    private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");    private ApplicationContext applicationContext;    private List<String> urls = new ArrayList<>();    public String ASTERISK = "*";    @Override    public void afterPropertiesSet()    {                RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);        // HandlerMethod 类用于封装控制器方法信息,包含类信息、方法Method对象、参数、注解等信息,具体的接口请求是可以根据封装的信息调用具体的方法来执行业务逻辑;        // RequestMappingInfo其实就是将我们熟悉的@RequestMapping注解的信息数据封装到了RequestMappingInfo POJO对象之中,然后和HandlerMethod做映射关系存入缓存之中;        // 可以参考博客:https://blog.csdn.net/yaomingyang/article/details/107026595        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();        map.keySet().forEach(info -> {            HandlerMethod handlerMethod = map.get(info);            // 获取方法上边的注解 替代path variable 为 *            // 从类或方法中查找某个 Anonymous 注解            Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class);            Optional.ofNullable(method).ifPresent(anonymous -> info.getPatternsCondition().getPatterns()                    .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));            // 获取类上边的注解, 替代path variable 为 *            Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class);            Optional.ofNullable(controller).ifPresent(anonymous -> info.getPatternsCondition().getPatterns()                    .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));        });    }    @Override    public void setApplicationContext(ApplicationContext context) throws BeansException    {        this.applicationContext = context;    }    public List<String> getUrls()    {        return urls;    }    public void setUrls(List<String> urls)    {        this.urls = urls;    }}

从上面的代码我们知道,只要我们给类上加 @Anonymous注解,就可以将不登陆就可以访问的路径加入urls集合里面。

@Target({ ElementType.METHOD, ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Anonymous{}

测试

有了以上的分析,我们接下来测试一波。我们测试缓存监控页面,请求为

Http://localhost/dev-api/monitor/cache

不加@Anonymous注解之前:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nOqAddEE-1666317952035)(Ruo-Yi 前后端分离如何不登录直接访问.assets/image-20221021094638260.png)]

测试结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wURyqbFA-1666317952035)(Ruo-Yi 前后端分离如何不登录直接访问.assets/image-20221021094603553.png)]

加了 @Anonymous注解之后:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HeCxHhwF-1666317952036)(Ruo-Yi 前后端分离如何不登录直接访问.assets/image-20221021094742483.png)]

测试结果,访问成功:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GHfwbPa1-1666317952036)(Ruo-Yi 前后端分离如何不登录直接访问.assets/image-20221021094804998.png)]

总结

在若依的系统里面,如果我们想要实现某一个接口不登陆就可以访问,只需要在方法上添加 @Anonymous注解即可。

如果我们想要在我们的项目里面实现不登陆就可以访问,我们可以将若依的PermitAllUrlProperties类和Anonymous类拿过来,然后在SecurityConfigspring security的配置类添加如下代码。

@Autowiredprivate PermitAllUrlProperties permitAllUrl;@Overrideprotected void configure(HttpSecurity httpSecurity) throws Exception{    // 注解标记允许匿名访问的url    // 自定义@Anonymous注解添加到方法上可以实现跳过权限验证。    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlReGIStry registry = httpSecurity.authorizeRequests();    permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll());    // ....     }

拓展:另一种方法基于配置文件

​ 经过上面的分析,我们知道,实现不登陆就可以访问某些接口,若依系统采用的是注解的形式,其实我们还可以将不需要登陆的接口放入配置文件里面。

SecurityConfig类改为

//@Autowired//private PermitAllUrlProperties permitAllUrl;@Resourceprivate IgnoreUrlsConfig ignoreUrlsConfig;@Overrideprotected void configure(HttpSecurity httpSecurity) throws Exception{    // 注解标记允许匿名访问的url    // 自定义@Anonymous注解添加到方法上可以实现跳过权限验证。    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();    // permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll());    // 白名单    //不需要保护的资源路径允许访问    for (String url : ignoreUrlsConfig.getUrls()) {        registry.antMatchers(url).permitAll();    }

去掉原有的方式的类的注入,添加IgnoreUrlsConfig

添加类 IgnoreUrlsConfig

@Component@ConfigurationProperties(prefix = "secure.ignore")public class IgnoreUrlsConfig {    private List<String> urls = new ArrayList<>();    public List<String> getUrls() {        return urls;    }    public void setUrls(List<String> urls) {        this.urls = urls;    }}

application.yml添加白名单

secure:  ignore:    urls: #安全路径白名单      - /monitor/cache

测试,还是测试之前的接口

http://localhost/dev-api/monitor/cache

记住,去掉权限的注解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HeZUQ55l-1666317952036)(Ruo-Yi 前后端分离如何不登录直接访问.assets/image-20221021100236661.png)]

测试成功:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bx4XtUqK-1666317952037)(Ruo-Yi 前后端分离如何不登录直接访问.assets/image-20221021100248640.png)]

以上的两种方法,我自己还是比较喜欢第二种,想要添加或者删除不需要登陆就可以访问的路径只需要修改配置文件即可,还不会污染业务代码。

来源地址:https://blog.csdn.net/H_Q_Li/article/details/127440502

--结束END--

本文标题: Ruo-Yi 前后端分离如何不登录直接访问以及一种基于配置文件实现的方式

本文链接: https://www.lsjlt.com/news/398240.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作