我的解决方法:
1. 创建一个自定义过滤器并将其添加到(Spring)安全链的早期位置。
2.在application.yml中创建flag(securityEnabled)
3. 查询自定义过滤器中的标志。如果为“真”,只需调用chain.doFilter() 继续下一个过滤器。如果为“假”,则创建一个虚拟 Keycloak-Account 设置您需要的角色并将其设置为上下文。
4.顺便把角色也外包给了application.yml
5. 跳过安全链中的其余过滤器(因此不执行 keycloak-stuff 并且发生相应的授权)
详细:
1.自定义过滤器类
public class CustomFilter extends OncePerRequestFilter {
@Value("${securityEnabled}")
private boolean securityEnabled;
@Value("${grantedRoles}")
private String[] grantedRoles;
@Override
public void doFilterInternal(HttpServletRequest req, HttpServletResponse res,
FilterChain chain) throws IOException, ServletException {
if (!securityEnabled){
// Read roles from application.yml
Set<String> roles = Arrays.stream(grantedRoles)
.collect(Collectors.toCollection(HashSet::new));
// Dummy Keycloak-Account
RefreshableKeycloakSecurityContext session = new RefreshableKeycloakSecurityContext(null, null, null, null, null, null, null);
final KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal = new KeycloakPrincipal<>("Dummy_Principal", session);
final KeycloakAccount account = new SimpleKeycloakAccount(principal, roles, principal.getKeycloakSecurityContext());
// Dummy Security Context
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(new KeycloakAuthenticationToken(account, false));
SecurityContextHolder.setContext(context);
// Skip the rest of the filters
req.getRequestDispatcher(req.getServletPath()).forward(req, res);
}
chain.doFilter(req, res);
}
}
2. 在 Spring-Security 的 http-Configuration 中插入 Custom-Filter
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.cors()
.and()
.csrf()
.disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.sessionAuthenticationStrategy(sessionAuthenticationStrategy())
.and()
.addFilterAfter(CustomFilter(), CsrfFilter.class)
.authorizeRequests()
.anyRequest().permitAll();
}
配置Keycloak后看看默认的Filter-Chain:
Filter-Chain
所以很明显在位置 5 插入自定义过滤器以避免整个 Keycloak-Magic。
我已使用此解决方法来破坏方法安全性,它是@Secured-Annotation。