从nacos的权限控制看nacos的配置热加载

最近在使用nacos,部署在k8s集群上,使用的是从源码自己打的镜像。在配置nacos的权限认证功能时, 发现无法生效,而且所谓的配置修改立即生效也无法实现,下面就探讨下这是什么原因导致的?同时也看下nacos所说配置修改立即生效是如何实现的?

基于nacos-1.3.3

nacos的权限控制是什么样的

nacos通过将用户绑定到某个角色上,然后赋予某个角色对某个资源(命名空间)的读写权限,假如当前登录的用户对某个空间没有访问权限,那么其试图访问该资源时,会通过弹框等方式予以拒绝,大致是这样的…
在这里插入图片描述

nacos是如何进行权限控制的

nacos的权限控制在AuthFilter中实现

com.alibaba.nacos.core.auth.AuthFilter#doFilter

// 被加上@Secured注解,并且auth鉴权开关打开了,将进行权限校验
if (method.isAnnotationPresent(Secured.class) && authConfigs.isAuthEnabled()) {
                
    if (Loggers.AUTH.isDebugEnabled()) {
        Loggers.AUTH.debug("auth start, request: {} {}", req.getMethod(), req.getRequestURI());
    }
    
	// 获取需要权限认证的方法, 和请求进行校验
    Secured secured = method.getAnnotation(Secured.class);
    String action = secured.action().toString();
    String resource = secured.resource();
    
    if (StringUtils.isBlank(resource)) {
        ResourceParser parser = secured.parser().newInstance();
        resource = parser.parseName(req);
    }
    
    if (StringUtils.isBlank(resource)) {
        // deny if we don't find any resource:
        throw new AccessException("resource name invalid!");
    }
	// 正真进行权限校验的地方,对当前用户及其角色的进行权限验证
    authManager.auth(new Permission(resource, action), authManager.login(req)); 
}

当方法被加上Secured注解即意味着该方法需要进行权限校验,比如"/nacos/v1/console/namespaces",其实现

@PostMapping
@Secured(action = ActionTypes.WRITE, parser = ConfigResourceParser.class)
public Boolean publishConfig(HttpServletRequest request...)

权限校验的方式并不复杂,具体就是首先获取当前登录用户的所有角色(查询roles表),如果角色具有全局的ROLE_ADMIN角色,则校验通过;
其次校验其访问的命名空间,最后查询当前用于持有的角色在permissions表中被赋予的权限,并和"@Secured"注解赋予的action权限进行对比

开启权限控制的开关

auth开关的读取是通过 ReloadableConfigs实现的,ReloadableConfigs的实现其实就是启动定时任务,不断的读取appliaction.properties的配置并更新至内存

public class ReloadableConfigs {
    
    private static final String FILE_PREFIX = "file:";
    
    private Properties properties;
    
    @Value("${spring.config.location:}")
    private String path;
    
    /**
     * Periodically load configuration file information.
     *
     * @throws IOException IOException
     */
    @Scheduled(fixedRate = 5000)
    public void reload() throws IOException {
        final Properties properties = new Properties();
        InputStream inputStream = null;
        if (StringUtils.isNotBlank(path) && path.contains(FILE_PREFIX)) {
            String[] paths = path.split(",");
            path = paths[paths.length - 1].substring(FILE_PREFIX.length());
        }
        try {
            inputStream = new FileInputStream(new File(path + "application.properties"));
        } catch (Exception ignore) {
        }
        if (inputStream == null) {
            inputStream = getClass().getResourceAsStream("/application.properties");
        }
        properties.load(inputStream);
        inputStream.close();
        this.properties = properties;
    }
    
    public final Properties getProperties() {
        return properties;
    }
}

从"spring.config.location"配置的路径下读取配置,如果文件不存在则试图读取classPath下的文件

为什么权限控制开关失效

为什么在application.properties中将nacos.core.auth.enabled=true打开,为什么当时的auth功能失效了?
在程序启动后,通过arthas读取com.alibaba.nacos.core.env.ReloadableConfigs#getProperties发现配置不变
原因就是没有读取到application.properties
首先,ReloadableConfigs#reloadspring.config.location配置在哪儿? 在程序启动脚本中是这样的

export DEFAULT_SEARCH_LOCATIONS="classpath:/,classpath:/config/,file:./,file:./conf/"
export CUSTOM_SEARCH_LOCATIONS=${BASE_DIR}/init.d/,file:${BASE_DIR}/conf/,${DEFAULT_SEARCH_LOCATIONS}

...
JAVA_OPT="${JAVA_OPT} --spring.config.location=${CUSTOM_SEARCH_LOCATIONS}"

...
$JAVA ${JAVA_OPT} > ${BASE_DIR}/logs/start.out

而reload方法默认读取的路径是最后一个路径下的配置,如果配置不当,那么该路径下没有文件,自然就无法读取到

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Nacos配置中心支持部署配置,即在配置文件被修改后,能够自动更新应用程序中的配置信息,无需重启应用程序。 要实现配置中心的部署,首先需要在应用程序中使用Nacos配置客户端来获取配置信息。然后,在Nacos配置中心修改配置信息时,Nacos会自动通知应用程序更新配置信息。 具体实现步骤如下: 1. 在应用程序中引入Nacos配置客户端依赖,例如在Maven项目中,可以添加以下依赖: ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> ``` 2. 在应用程序的配置文件中配置Nacos配置中心地址和应用程序的配置项,例如: ```yaml spring: application: name: my-application cloud: nacos: config: server-addr: localhost:8848 namespace: your-namespace group: your-group refreshable-dataids: your-config-id ``` 其中,`server-addr`是Nacos配置中心地址,`namespace`是Nacos的命名空间,`group`是配置的分组,`refreshable-dataids`是要部署的配置项的ID。 3. 在应用程序中使用`@Value`注解来获取配置项的值,例如: ```java @RestController public class MyController { @Value("${your-config-id}") private String configValue; @GetMapping("/config") public String getConfig() { return configValue; } } ``` 4. 在Nacos配置中心修改配置信息时,Nacos会自动通知应用程序更新配置信息。应用程序会重新加载最新的配置信息,无需重启应用程序。 需要注意的是,部署的配置项需要在配置文件中加上`@NacosConfigurationProperties`注解,例如: ```java @Configuration @NacosConfigurationProperties(prefix = "your-config-id", dataId = "your-config-id", groupId = "your-group", autoRefreshed = true) public class MyConfig { private String configValue; public String getConfigValue() { return configValue; } public void setConfigValue(String configValue) { this.configValue = configValue; } } ``` 这样,在配置文件中修改配置信息时,应用程序会自动更新`MyConfig`类中的`configValue`属性,无需手动获取配置项的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值