在 AADAppRoleStatelessAuthenticationFilter 中添加自定义逻辑,以便我可以决定过滤哪些请求

Posted

技术标签:

【中文标题】在 AADAppRoleStatelessAuthenticationFilter 中添加自定义逻辑,以便我可以决定过滤哪些请求【英文标题】:Add custom logic in the AADAppRoleStatelessAuthenticationFilter so I can decide which requests to be filtered 【发布时间】:2022-01-17 08:53:02 【问题描述】:

我正在使用来自 azure 的以下过滤器 AADAppRoleStatelessAuthenticationFilter,在我的 WebConfiguration 中我有以下内容:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Profile("dev", "test", "prod")
protected static class AADWebSecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    private AADAppRoleStatelessAuthenticationFilter aadAuthFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.csrf().disable();

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.authorizeRequests()
                .antMatchers("/actuator/health/**").permitAll()
                .anyRequest().authenticated();

        http.addFilterBefore(aadAuthFilter, UsernamePasswordAuthenticationFilter.class);
        log.info("Security enabled.");
    

我有两种情况:

在第一个中,用户使用 FE 发送请求 -> 在这种方法中,他使用他的帐户登录,我可以进行角色验证以查看它是否具有正确的角色。我进行角色验证的方式是使用端点上方的注释:

@PreAuthorize("hasRole('ROLE_tools-reader')")
public ResponseEntity<Resource> downloadFileForVariable(String processInstanceId, String 
variableName) 

在第二个中,另一个微服务正在从另一个微服务调用端点。为了能够调用端点,我还需要发送一个 jwt 令牌,并且有一种方法可以获取令牌但没有任何角色。在这种情况下,我使用以下逻辑保护这些端点:

@PreAuthorize("isAuthenticated()")
public ResponseEntity<RentalCaseDTO> createRentalCase(CreateRentalCaseDTO createRentalCaseDTO) 

但如果 FE 需要此端点,我将无法验证它是读取器还是写入器,并且任何人都可以访问具有任何角色的此端点。

我尝试使用角色从 azure 获取令牌,但没有成功。我这样做的逻辑如下:

public String getTokenFromAzure() 
    String token = null;
    ConfidentialClientApplication application = getApplication();
    if (application == null) 
        log.error("application is not instantiated");
     else 
        ClientCredentialParameters parameters = ClientCredentialParameters.builder(Collections.singleton(clientId + "/.default")).build();
        IAuthenticationResult auth = application.acquireToken(parameters).join();

        if (auth == null) 
            log.info("auth still == null");
         else 
            log.info("idToken: " + auth.idToken());
            log.info("accessToken: " + auth.accessToken());
            token = isEmpty(auth.idToken()) ? auth.accessToken() : auth.idToken();
        
    
    return token;

我目前想要实现的是在标头中设置一些技术用户并覆盖 AADAppRoleStatelessAuthenticationFilter,这样来自其他微服务的标头中包含该技术用户的所有请求都不会被过滤,即使它们受角色保护。我不确定这是否是正确的方法,但是当我尝试以编程方式从 azure 获取具有特定角色的令牌时,我陷入了死胡同。

【问题讨论】:

【参考方案1】:

当您实现 2 个不同的用例时,我建议您从不同的 URL 为每个用例提供服务。这样您就可以将过滤器连接到一个而不是另一个。

【讨论】:

我这样做了,但我想避免相同的端点两次调用相同的服务逻辑。

以上是关于在 AADAppRoleStatelessAuthenticationFilter 中添加自定义逻辑,以便我可以决定过滤哪些请求的主要内容,如果未能解决你的问题,请参考以下文章

秋的潇洒在啥?在啥在啥?

上传的数据在云端的怎么查看,保存在啥位置?

在 React 应用程序中在哪里转换数据 - 在 Express 中还是在前端使用 React?

存储在 plist 中的数据在模拟器中有效,但在设备中无效

如何在保存在 Mongoose (ExpressJS) 之前在模型中格式化数据

如何在保存在 Mongoose (ExpressJS) 之前在模型中格式化数据