簡體   English   中英

Spring Boot webflux中的線程本地remove()

[英]Thread Local remove() in Spring Boot webflux

我有一個 Web 過濾器,它在 ThreadLocal 屬性中設置一個對象,並且我試圖了解應該如何/何時清除此本地線程 (ThreadLocal.remove()) 以避免出現異常“用戶上下文已經啟動”。 發生這種情況是因為它是從 Spring Boot 線程池中使用先前設置的值進行檢索的。

我正在使用 Spring Webflux。

我在哪里可以掛鈎這個 SecurityAuthorizationContext.clean() 調用?

public class SecurityAuthorizationContext
{
    private static final ThreadLocal<PrivilegeHolder> userContext = new ThreadLocal<>();

    private final List<String> roles;

    private SecurityAuthorizationContext(List<String> roles)
    {
        this.roles = roles;
    }

    public static void create(List<String> roles)
    {
        if (nonNull(userContext.get()))
        {
            log.error("User context already initiated.");
            throw new AuthorizationException("User context already initiated.");
        }

        PrivilegeHolder privilegeHolder = new PrivilegeHolder();
        userContext.set(privilegeHolder);

        // example of privileges retrieved from database by the user roles
        privilegeHolder.add(INSERT);
        privilegeHolder.add(DELETE);
    }

    public static void clean()
    {
        userContext.remove();
    }

    public static boolean hasInsertPrivilege()
    {
        return userContext.get().hasPrivilege(INSERT);
    }

    public static boolean hasDeletePrivilege()
    {
        return userContext.get().hasPrivilege(DELETE);
    } 
}

public class AuthorizationFilter implements OrderedWebFilter
{
    private static final String USER_ROLES = "user-roles";

    @Override
    public int getOrder()
    {
        return SecurityWebFiltersOrder.AUTHORIZATION.getOrder();
    }

    @Override
    public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain)
    {
        ServerHttpRequest request = serverWebExchange.getRequest();
        HttpHeaders headers = request.getHeaders();

        List<String> roles = headers.get(USER_ROLES);

        SecurityAuthorizationContext.create(roles);

        return webFilterChain.filter(serverWebExchange);
    }        
}

@Configuration
@EnableWebFluxSecurity
@EnableTransactionManagement
public class ApplicationConfiguration
{    
    @Autowired
    private AuthorizationFilter authorizationFilter;

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http)
    {
        return http
            .csrf().disable()
            .authorizeExchange()
            .pathMatchers("/**").permitAll()
            .and()
            .addFilterAt(authorizationFilter, AUTHORIZATION)
            .build();
    }    
}

更新:長話短說......我只想從請求標頭中提取一些內容,並使其可用於所有堆棧而不將其作為參數傳遞。

因此,最好使用 reactor 上下文而不是 ThreadLocal,您可以在這里閱讀: https : //projectreactor.io/docs/core/release/reference/#context

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM