Spring启动OAuth成功登录监听器未触发
Spring boot OAuth successful login listener not triggering
使用 Spring 引导 - 使用 GitHub OAuth 成功验证后,未触发审计侦听器。
public class AuthenticationListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent> {
@Override
public void onApplicationEvent(final InteractiveAuthenticationSuccessEvent event) {
System.out.println("+++++++ ================ ------------");
}
}
我需要在其他地方注册吗?我已经按照其他建议尝试在 Whosebug 上创建一个@Bean,但这没有任何区别。
完整代码https://github.com/DashboardHub/PipelineDashboard/tree/feature/178-login-github
更新
安全配置class
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
OAuth2ClientContext oauth2ClientContext;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**", "/webjars/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")//.failureUrl("/login?error")
.permitAll()
.and().logout().logoutSuccessUrl("/").permitAll()
.and().addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class)
;
}
@Bean
@ConfigurationProperties("security.oauth2")
ClientResourcesConfig github() {
return new ClientResourcesConfig();
}
private Filter ssoFilter() {
CompositeFilter filter = new CompositeFilter();
List<Filter> filters = new ArrayList<>();
filters.add(ssoFilter(this.github(), "/login/github"));
filter.setFilters(filters);
return filter;
}
private Filter ssoFilter(ClientResourcesConfig client, String path) {
OAuth2ClientAuthenticationProcessingFilter githubFilter = new OAuth2ClientAuthenticationProcessingFilter(
path);
OAuth2RestTemplate githubTemplate = new OAuth2RestTemplate(client.getClient(),
oauth2ClientContext);
githubFilter.setRestTemplate(githubTemplate);
githubFilter.setTokenServices(new UserInfoTokenServices(
client.getResource().getUserInfoUri(), client.getClient().getClientId()));
return githubFilter;
}
}
在 AuthenticationListener class 上使用 @Configuration 批注将其注册到您的应用程序上下文中。
编辑
由于我无法弄清楚事件未被触发的原因,因此我提出了该问题的替代解决方案。您必须创建实现 AuthenticationSuccessHanddler
的 class 并实现其 onAuthenticationSuccess
方法:
@Component(value="customAuthenticationSuccessHandler")
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler{
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
//implementation
}
}
然后将其添加到您的配置中:
@Resource
private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
...
.loginPage("/login").and()
.successHandler(getCustomAuthenticationSuccessHandler())
.permitAll()
...
}
public CustomAuthenticationSuccessHandler getCustomAuthenticationSuccessHandler() {
return customAuthenticationSuccessHandler;
}
这不是您想要的,但应该可以解决您的问题。
我通过将默认的 ApplicationEventPublisher 注入您的安全配置 bean 来实现这一点。然后将其设置为处理过滤器上的应用程序事件发布者:
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
...
githubFilter.setApplicationEventPublisher(applicationEventPublisher);
由于某些原因,过滤器上的应用程序事件发布者默认为 NullEventPublisher。
监听 AuthenticationSuccessEvent 而不是 InteractiveAuthenticationSuccessEvent 对我有用。
但是,侦听器被调用了两次:第一个事件的身份验证是 UsernamePasswordAuthenticationToken,而第二个是 OAuth2Authentication
使用 Spring 引导 - 使用 GitHub OAuth 成功验证后,未触发审计侦听器。
public class AuthenticationListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent> {
@Override
public void onApplicationEvent(final InteractiveAuthenticationSuccessEvent event) {
System.out.println("+++++++ ================ ------------");
}
}
我需要在其他地方注册吗?我已经按照其他建议尝试在 Whosebug 上创建一个@Bean,但这没有任何区别。
完整代码https://github.com/DashboardHub/PipelineDashboard/tree/feature/178-login-github
更新
安全配置class
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
OAuth2ClientContext oauth2ClientContext;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**", "/webjars/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")//.failureUrl("/login?error")
.permitAll()
.and().logout().logoutSuccessUrl("/").permitAll()
.and().addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class)
;
}
@Bean
@ConfigurationProperties("security.oauth2")
ClientResourcesConfig github() {
return new ClientResourcesConfig();
}
private Filter ssoFilter() {
CompositeFilter filter = new CompositeFilter();
List<Filter> filters = new ArrayList<>();
filters.add(ssoFilter(this.github(), "/login/github"));
filter.setFilters(filters);
return filter;
}
private Filter ssoFilter(ClientResourcesConfig client, String path) {
OAuth2ClientAuthenticationProcessingFilter githubFilter = new OAuth2ClientAuthenticationProcessingFilter(
path);
OAuth2RestTemplate githubTemplate = new OAuth2RestTemplate(client.getClient(),
oauth2ClientContext);
githubFilter.setRestTemplate(githubTemplate);
githubFilter.setTokenServices(new UserInfoTokenServices(
client.getResource().getUserInfoUri(), client.getClient().getClientId()));
return githubFilter;
}
}
在 AuthenticationListener class 上使用 @Configuration 批注将其注册到您的应用程序上下文中。
编辑
由于我无法弄清楚事件未被触发的原因,因此我提出了该问题的替代解决方案。您必须创建实现 AuthenticationSuccessHanddler
的 class 并实现其 onAuthenticationSuccess
方法:
@Component(value="customAuthenticationSuccessHandler")
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler{
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
//implementation
}
}
然后将其添加到您的配置中:
@Resource
private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
...
.loginPage("/login").and()
.successHandler(getCustomAuthenticationSuccessHandler())
.permitAll()
...
}
public CustomAuthenticationSuccessHandler getCustomAuthenticationSuccessHandler() {
return customAuthenticationSuccessHandler;
}
这不是您想要的,但应该可以解决您的问题。
我通过将默认的 ApplicationEventPublisher 注入您的安全配置 bean 来实现这一点。然后将其设置为处理过滤器上的应用程序事件发布者:
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
...
githubFilter.setApplicationEventPublisher(applicationEventPublisher);
由于某些原因,过滤器上的应用程序事件发布者默认为 NullEventPublisher。
监听 AuthenticationSuccessEvent 而不是 InteractiveAuthenticationSuccessEvent 对我有用。 但是,侦听器被调用了两次:第一个事件的身份验证是 UsernamePasswordAuthenticationToken,而第二个是 OAuth2Authentication