这是解决方案:
- 创建 CustomPrincipal 来存储角色
- 创建用于验证凭证并返回 CustomPrincipal 的 IdentityStore
- 创建 ThreadLocal RolesHolder 来存储角色
- 为每个请求生命周期管理 RolesHolder
- 在其他线程中使用 RolesHolder
创建 CustomPrincipal 来存储角色:
public class CustomPrincipal extends CallerPrincipal {
final Set<String> roles;
public CustomPrincipal(String name, Set<String> roles) {
this.roles = Collections.unmodifiableSet(new HashSet<>(roles));
}
public Set<String> getRoles() {
return roles;
}
}
创建您的 IdentityStore 以验证凭据并返回 CustomPrincipal
@ApplicationScoped
public class YourIdentityStore implements IdentityStore {
@Override
public CredentialValidationResult validate(Credential credential) {
// TODO: Your verification of credential
// Assume verification successful
// You have roles/groups
Set<String> roles = computed_roles
return new CredentialValidationResult(
new CustomPrincipal(userNameFromCredential, roles), roles);
}
}
使用 ThreadLocal 存储角色
public class RolesHolder {
// Must be InheritableThreadLocal, NOT new ThreadLocal<>()
final ThreadLocal<Set<String>> holder = new InheritableThreadLocal<>();
public static Set<String> get() {
return this.holder.get();
}
public static void set(Set<String> value) {
if (value == null) {
this.holder.remove();
} else {
this.holder.set(value);
}
}
}
为每个请求生命周期管理 RolesHolder
@WebFilter(urlPatterns = "your_mappings")
public class RolesFilter extends HttpFilter {
private static final long serialVersionUID = 1L;
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
if (request.getUserPrincipal() != null) {
CustomPrincipal customPrincipal = (CustomPrincipal)request.getUserPrincipal();
// Store Roles in thread local
RolesHolder.set(customPrincipal.getRoles());
}
chain.doFilter(request, response);
} finally {
RolesHolder.set(null);
}
}
}
在其他线程中使用 RolesHolder
if(RolesHolder.get()!=null&&RolesHolder.get().contains("CheckingRole")){
// Do authorized roles things
}