프로메테우스에 role 이 ADMIN 인 경우만 작동할 수 있게 하려고 설정을 했다.
# my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: "prometheus"
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ["localhost:9090"]
- job_name: "sample"
metrics_path: '/actuator/prometheus'
scrape_interval: 1s
static_configs:
- targets: ['localhost:8080']
bearer_token: token
다음은 Security Config 이다
@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
.accessDeniedHandler(jwtAccessDeniedHandler)
.and()
.headers()
.frameOptions()
.sameOrigin()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/actuator/**")
.hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.apply(new JwtConfig(tokenProvider, redisTemplate));
return http.build();
}
그리고 당연히 정상적으로 작동할 것이라 생각했는데 서버에서 403을 return 한다고 문구가 떴다.
뭐가 문제인가보니... 커스텀으로 지정했던 UserRole이 문제였다.
hasRole에 실제로 내가 값을 쓰면 prefix가 생략되어 있는 형태였다!
즉 hasRole("ADMIN")을 썼지만 실제로는 유저의 role이 prefix+"ADMIN"이여야 정상적으로 인식이 되는 문제였다.
실제로 hasRole 옵션을 따라가보니
public ExpressionUrlAuthorizationConfigurer(ApplicationContext context) {
String[] grantedAuthorityDefaultsBeanNames = context.getBeanNamesForType(GrantedAuthorityDefaults.class);
if (grantedAuthorityDefaultsBeanNames.length == 1) {
GrantedAuthorityDefaults grantedAuthorityDefaults = context.getBean(grantedAuthorityDefaultsBeanNames[0],
GrantedAuthorityDefaults.class);
this.rolePrefix = grantedAuthorityDefaults.getRolePrefix();
}
else {
this.rolePrefix = "ROLE_";
}
this.REGISTRY = new ExpressionInterceptUrlRegistry(context);
}
private static String hasRole(String rolePrefix, String role) {
Assert.notNull(role, "role cannot be null");
Assert.isTrue(rolePrefix.isEmpty() || !role.startsWith(rolePrefix), () -> "role should not start with '"
+ rolePrefix + "' since it is automatically inserted. Got '" + role + "'");
return "hasRole('" + rolePrefix + role + "')";
}
이렇게 되어있다. 즉 prefix까지 붙은 형태로 enum 에서 정의해야 정상적으로 인식을 하는것이다.
그래서 UserRole enum을 다음과 같이 변경하였고
public enum UserRole {
ROLE_NORMAL, ROLE_ADMIN
}
그후 다시 토큰을 발급받아 프로메테우스를 실행하니 정상적으로 연결할 수 있었다.
사실 이 방법 말고도 aws에서 특정 포트를 프로메테우스 서버에서만 연결을 허용해준다던가 해서 해결을 할 수 있지만 꼭 해결하고 싶어서 도전을 하게 되었다..