Spring boot OAuth成功登录侦听器未触发

Posted

技术标签:

【中文标题】Spring boot OAuth成功登录侦听器未触发【英文标题】:Spring boot OAuth successful login listener not triggering 【发布时间】:2016-04-19 14:39:37 【问题描述】:

使用 Spring boot - 成功通过 GitHub OAuth 进行身份验证后,不会触发 Audit 侦听器。

public class AuthenticationListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent> 

@Override
public void onApplicationEvent(final InteractiveAuthenticationSuccessEvent event) 
       System.out.println("+++++++ ================ ------------");
   


我需要在其他地方注册吗?我已按照建议在 *** 上的其他位置尝试创建 @Bean,但这没有任何区别。

完整代码https://github.com/DashboardHub/PipelineDashboard/tree/feature/178-login-github

更新

SecurityConfig 类

@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;


【问题讨论】:

【参考方案1】:

侦听 AuthenticationSuccessEvent 而不是 InteractiveAuthenticationSuccessEvent,这对我有用。 但是,监听器被调用了两次:第一个事件的 Authentication 是 UsernamePasswordAuthenticationToken,而第二个是 OAuth2Authentication

【讨论】:

【参考方案2】:

我通过将默认的 ApplicationEventPublisher 注入您的安全配置 bean 来实现此功能。然后将其设置为 processingfilter 上的应用程序事件发布者:

@Autowired
private ApplicationEventPublisher applicationEventPublisher;    

...        

githubFilter.setApplicationEventPublisher(applicationEventPublisher);

由于某种原因,过滤器上的应用程序事件发布者默认为 NullEventPublisher。

【讨论】:

这是提交给需要它的任何其他人的更改github.com/DashboardHub/PipelineDashboard/commit/… 与问题没有直接关系,但有时可能希望手动触发事件,这是使用注入的 ApplicationEventPublisher 的 publishEvent() 方法完成的【参考方案3】:

在 AuthenticationListener 类上使用 @Configuration 注解将其注册到您的应用程序上下文中。

编辑

由于我无法弄清楚为什么没有触发事件,因此我提出了针对此问题的替代解决方案。您必须创建实现AuthenticationSuccessHanddler 的类并实现其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;

这不是您想要的,但应该可以解决您的问题。

【讨论】:

您确定您在 Spring Security Context 中获得授权吗?您可以检查您的一个视图 (doanduyhai.wordpress.com/2012/02/26/…) 或 Authentication 对象(您可以从 SecurityContextHolder.getContext().getAuthentication() 访问它) 感谢您的链接。是的,绝对通过 OAuth2 (GitHub) 授权。 OAuth 有影响吗? 我不知道我是否理解正确 - 您是否在 Spring Security 上下文中获得授权? SecurityContextHolder.getContext().getAuthentication().isAuthenticated() 返回真?请在记录过程后调试并检查。 我刚刚又检查了一遍,肯定返回true。 尝试收听AbstractAuthenticationEvent 并记录您收到的每个事件类名称。我认为因为您使用的是 OAuth,所以应用程序发布 AuthenticationSuccessEvent 而不是 InteractiveAuthenticationSuccessEvent

以上是关于Spring boot OAuth成功登录侦听器未触发的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot OAuth 2:登录后匿名用户

Spring Boot + Oauth 2单点登录ridirect uri错误行为

成功登录后 Spring Boot Security 重定向 - 未定义

Spring Boot 2 OIDC(OAuth2)客户端/资源服务器未在 WebClient 中传播访问令牌

Spring Boot 和 OAuth2 社交登录,无法获取 refreshToken

如何在 Spring Boot 2 oauth2 中获取令牌?