Spring Boot KeyCloak 未调用成功处理程序
Spring Boot KeyCloak not invoking success handler
我在我的应用程序中使用 Spring Boot KeyCloak 来连接 KeyCloak。但是我有一个未被调用的自定义成功处理程序。我不确定为什么。这是我的代码:
SecurityConfiguration.java
:
@KeycloakConfiguration
public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Bean
@Primary
@Override
protected KeycloakAuthenticationProcessingFilter keycloakAuthenticationProcessingFilter() throws Exception {
KeycloakAuthenticationProcessingFilter filter = new KeycloakAuthenticationProcessingFilter(authenticationManagerBean());
filter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy());
filter.setAuthenticationSuccessHandler(successHandler());
filter.setAuthenticationFailureHandler(failureHandler());
return filter;
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.csrf().disable().authorizeRequests()
.antMatchers("/**").authenticated();
}
@NotNull
@Bean
public KeyCloakAuthSuccessHandler successHandler() {
return new KeyCloakAuthSuccessHandler(new SavedRequestAwareAuthenticationSuccessHandler());
}
@NotNull
@Bean
public KeyCloakAuthFailureHandler failureHandler() {
return new KeyCloakAuthFailureHandler();
}
}
在我的 KeyCloakAuthSuccessHandler.java
中,我有:
@Slf4j
public class KeyCloakAuthSuccessHandler extends KeycloakAuthenticationSuccessHandler {
@Autowired
ObjectMapper mapper;
public KeyCloakAuthSuccessHandler(AuthenticationSuccessHandler fallback) {
super(fallback);
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
log.error("inside success handler");
if (authentication.getPrincipal() instanceof KeycloakPrincipal) {
AccessToken token = ((KeycloakPrincipal<?>) authentication.getPrincipal()).getKeycloakSecurityContext().getToken();
// do other stuff
}
}
}
上面的代码没有调用成功处理程序,但是一个类似的失败处理程序正在运行并被调用。
我认为您必须使用您的 KeyCloakAuthSuccessHandler 编写您自己的 KeycloakAuthenticationProcessingFilter。
您无法注入您的 KeyCloakAuthSuccessHandler。
如评论所述,这是因为在 non-interactive(non-human 方式 - bearer/basic)登录 Keycloak 期间未调用成功处理程序。如果您想每次都调用成功处理程序,而不管登录方式如何,请通过扩展自定义 KeycloakAuthencticationProcessingFilter
并通过 over-riding 将原始的 this line 更改为 this line 。
一个粗略的例子如下:
public class CustomKeycloakAuthenticationProcessingFilter extends KeycloakAuthenticationProcessingFilter {
public CustomKeycloakAuthenticationProcessingFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
}
public CustomKeycloakAuthenticationProcessingFilter(AuthenticationManager authenticationManager, RequestMatcher requiresAuthenticationRequestMatcher) {
super(authenticationManager, requiresAuthenticationRequestMatcher);
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
// Line of importance down here
if (authResult instanceof KeycloakAuthenticationToken) {
super.successfulAuthentication(request, response, chain, authResult);
return;
}
// whatever spring-boot-keycloak does copy paste here
}
}
我在我的应用程序中使用 Spring Boot KeyCloak 来连接 KeyCloak。但是我有一个未被调用的自定义成功处理程序。我不确定为什么。这是我的代码:
SecurityConfiguration.java
:
@KeycloakConfiguration
public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Bean
@Primary
@Override
protected KeycloakAuthenticationProcessingFilter keycloakAuthenticationProcessingFilter() throws Exception {
KeycloakAuthenticationProcessingFilter filter = new KeycloakAuthenticationProcessingFilter(authenticationManagerBean());
filter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy());
filter.setAuthenticationSuccessHandler(successHandler());
filter.setAuthenticationFailureHandler(failureHandler());
return filter;
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.csrf().disable().authorizeRequests()
.antMatchers("/**").authenticated();
}
@NotNull
@Bean
public KeyCloakAuthSuccessHandler successHandler() {
return new KeyCloakAuthSuccessHandler(new SavedRequestAwareAuthenticationSuccessHandler());
}
@NotNull
@Bean
public KeyCloakAuthFailureHandler failureHandler() {
return new KeyCloakAuthFailureHandler();
}
}
在我的 KeyCloakAuthSuccessHandler.java
中,我有:
@Slf4j
public class KeyCloakAuthSuccessHandler extends KeycloakAuthenticationSuccessHandler {
@Autowired
ObjectMapper mapper;
public KeyCloakAuthSuccessHandler(AuthenticationSuccessHandler fallback) {
super(fallback);
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
log.error("inside success handler");
if (authentication.getPrincipal() instanceof KeycloakPrincipal) {
AccessToken token = ((KeycloakPrincipal<?>) authentication.getPrincipal()).getKeycloakSecurityContext().getToken();
// do other stuff
}
}
}
上面的代码没有调用成功处理程序,但是一个类似的失败处理程序正在运行并被调用。
我认为您必须使用您的 KeyCloakAuthSuccessHandler 编写您自己的 KeycloakAuthenticationProcessingFilter。
您无法注入您的 KeyCloakAuthSuccessHandler。
如评论所述,这是因为在 non-interactive(non-human 方式 - bearer/basic)登录 Keycloak 期间未调用成功处理程序。如果您想每次都调用成功处理程序,而不管登录方式如何,请通过扩展自定义 KeycloakAuthencticationProcessingFilter
并通过 over-riding 将原始的 this line 更改为 this line 。
一个粗略的例子如下:
public class CustomKeycloakAuthenticationProcessingFilter extends KeycloakAuthenticationProcessingFilter {
public CustomKeycloakAuthenticationProcessingFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
}
public CustomKeycloakAuthenticationProcessingFilter(AuthenticationManager authenticationManager, RequestMatcher requiresAuthenticationRequestMatcher) {
super(authenticationManager, requiresAuthenticationRequestMatcher);
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
// Line of importance down here
if (authResult instanceof KeycloakAuthenticationToken) {
super.successfulAuthentication(request, response, chain, authResult);
return;
}
// whatever spring-boot-keycloak does copy paste here
}
}