当前位置: 首页 > 知识库问答 >
问题:

Spring引导执行器:使用JWT访问敏感管理endpoint

赵征
2023-03-14

我已经通过浏览器中的令牌读取访问敏感的Spring引导执行器endpoint,因为它接近我需要的,但我不一定需要浏览器,这个问题没有答案。

与教程相反,我在pom.xml中包含了spring-boot-starter-actuator作为依赖项。

我的application.properties如下所示:

logging.level=DEBUG
server.port=9191
endpoints.health.enabled=true
endpoints.health.sensitive=false
endpoints.shutdown.enabled=true
endpoints.shutdown.sensitive=true
management.contextPath: /manage
management.security.enabled=true

我的AccountUserDetailsService如下所示:

package com.divstar.particle.authservice.rest;
import java.text.MessageFormat;

import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class AccountUserDetailsService implements UserDetailsService {

    private final IAccountRepository accountRepository;

    public AccountUserDetailsService(final IAccountRepository accountRepository) {
        this.accountRepository = accountRepository;
    }

    @Override
    public UserDetails loadUserByUsername(final String username) {
        return accountRepository.findByUsername(username)
                                .map(account -> new User(account.getUsername(), account.getPassword(), account.isEnabled(),
                                        account.isNonExpired(), account.isCredentialsNonExpired(), account.isNonLocked(),
                                        AuthorityUtils.createAuthorityList("ROLE_ADMIN", "ROLE_USER", "ROLE_ACTUATOR")))
                                .orElseThrow(() -> new UsernameNotFoundException(
                                        MessageFormat.format("Could not find the user {0}!", username)));
    }
}

我包含了角色“role_actuator”,因为这似乎是actuator访问管理服务endpoint所需要的。

主应用程序类看起来相当简单:

package com.divstar.particle.authservice;

import java.util.stream.Stream;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import com.divstar.particle.authservice.rest.Account;
import com.divstar.particle.authservice.rest.IAccountRepository;

@SpringBootApplication
public class Application {
    @Bean
    CommandLineRunner initUsers(final IAccountRepository userRepository) {
        return args -> Stream.of("test,long", "blame,short", "pass,secure")
                             .map(tpl -> tpl.split(","))
                             .forEach(tpl -> userRepository.save(new Account(tpl[0], tpl[1], "sample@mail.com", true, true, true, true)));
    }

    public static void main(final String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

IAccountRepository扩展了JpaRepository并定义了“FindByUserName”,它返回可选的。

我的AuthorizationServerConfigurationAdapter如下所示:

package com.divstar.particle.authservice;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;

@Configuration
@EnableAuthorizationServer
public class AuthServiceConfiguration extends AuthorizationServerConfigurerAdapter {
    private final AuthenticationManager authenticationManager;

    public AuthServiceConfiguration(final AuthenticationManager authenticationManager) {
        super();
        this.authenticationManager = authenticationManager;
    }

    @Override
    public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
        clients
               .inMemory()
               .withClient("html5")
               .secret("clientsecret")
               .authorizedGrantTypes("password")
               .scopes("openid");
    }

    @Override
    public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }
}

启动身份验证服务器后,我使用以下cURL-command获取令牌:

 curl html5:clientsecret@localhost:9191/oauth/token -d grant_type=password -d username=test -d password=long

它在JSON应答中返回access_token以及进一步的信息。

但是,如果我尝试访问敏感endpoint(例如/manage/shutdown),如下所示:

curl -X POST -H"Authorization: bearer b8412762-af80-4b7d-9eb9-3fa472dd37c9" localhost:9191/manage/shutdown

我收到以下错误消息:

{“时间戳”:1508029184236,“状态”:401,“错误”:“未经授权”,“消息”:“访问此资源需要完全身份验证”,“路径”:“/manage/shutdown”}

我漏掉了什么/做错了什么?如果令牌有效(给定适当的权限/角色),我如何让spring-boot actuator识别JWTs并执行给定的敏感endpoint?

共有1个答案

仉高昂
2023-03-14

根据您共享的信息,看起来您实际上并没有告诉Spring使用您自定义的UserDetailsService。为此,必须有一个扩展WebSecurityConfigurerAdapter的类,然后重写configure(AuthenticationManagerBuilder auth)方法,如下所示:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  auth.userDetailsService(customUserDetailsService);
}

有关OAuth2和自定义UserDetailsService的更多信息,请参见此处:https://stackoverflow.com/a/43245998/1320627

确保正确配置用户详细信息服务的最简单方法是添加一个RESTendpoint,使用身份验证进行保护,然后尝试使用它。

 类似资料:
  • 一、本功能说明 对网站内容进行过滤屏蔽,以免违反互联网相关政策而导致网站被关闭 二、子功能导航 1.添加敏感词 2.修改敏感词 2.删除敏感词 三、功能详解 1.添加敏感词 1).如何进入本功能 导航栏 选择扩展 -> 菜单栏 选择 敏感词管理-> 顶部添加敏感词或者批量导入 2).界面解释 a.)点击添加敏感词后显示如下界面 界面详述 1). 敏感词: 请填写您要屏蔽的任何词语 2). 替换词:

  • 我一直在阅读Spring引导执行器,我很难区分两个应用程序。属性设置 我想自定义执行器endpoint的访问规则。我可以使用属性控制所有执行器endpoint灵敏度。我的理解是,敏感endpoint将需要授权。我还可以通过属性更改endpoint的可访问性。 敏感度控制和安全启动之间有什么区别?

  • 详情: 我要访问的是“执行器”endpoint,而不是spring boot Acture(localhost:8080/acture)提供的其他endpoint 是,我已尝试在属性文件中手动启用该终结点(endpoints.enabled=true或endpoints.actuator.enabled=true) 是,我已尝试启用/禁用endpoint。敏感属性 是的,执行器的其他endpoin

  • 我在将Spring Boot从1.1.12升级到1.2.5时遇到了麻烦,但在1.2.x的所有版本中都存在同样的问题。执行器提供的endpoint现在将401未经授权返回到以前工作的集成测试。升级依赖项时未更改任何代码。 下面是测试用例: 我怎样才能让考试通过呢? 更新: 中定义的唯一相关设置是。 根据Spring Boot问题2120,使用自定义安全性时会忽略属性。我发现文件中没有提到这一点。

  • Spring Boot执行器的两个版本(1.2.5和1.3.0)在HealthMvcEndpoint,isUnrestricted()方法(&&and)中的实现存在差异。我明白这是为了保留这些限制 http://docs.spring.io/spring-boot/docs/current-snapshot/reference/htmlsingle/#production-ready-health