java - 使用 Spring Boot 1.3.2(没有 spring-cloud-security)和 @EnableOAuth2Sso 配置 AuthenticationSuccessHandler

标签 java spring-boot spring-security-oauth2

我们有一个 Spring Boot 1.3.2/Webflow 网络应用程序,我们正在将其转换为使用 SSO。我已按照“将 OAuth2 应用程序从 Spring Boot 1.2 迁移到 1.3”博客中的步骤进行操作,并将应用程序移交给我们的 Auth 服务器进行身份验证,并让 Web 应用程序使用 token 正确填充其安全上下文。

唯一不起作用的部分是我们拥有的自定义身份验证成功处理程序,它在用户继续访问其登录页面之前在用户 session 中配置了一些位。

目前在我们的安全配置中配置如下,它扩展了 WebSecurityConfigurerAdapter

@Override
protected void configure(HttpSecurity http) throws Exception {
    // These are all the unprotected endpoints.
    http.authorizeRequests()
            .antMatchers(new String[] { "/", "/login", "/error",
                    "/loginFailed", "/static/**" })
            .permitAll();

    // Protect all the other endpoints with a login page.
    http.authorizeRequests().anyRequest()
            .hasAnyAuthority("USER", "ADMIN").and().formLogin().loginPage("/login").failureUrl("/loginFailed")
            .successHandler(customAuthenticationSuccessHandler()).and().logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
    http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {

        @Override
        public void handle(HttpServletRequest request, HttpServletResponse response,
                AccessDeniedException accessDeniedException) throws IOException, ServletException {
            if (accessDeniedException instanceof CsrfException) {
                response.sendRedirect(request.getContextPath() + "/logout");
            }
        }
    });
}

我可以看到在启动期间正在配置的处理程序,但是一旦用户成功登录就永远不会调用它。 我在该主题上发现的所有问题都涉及使用 OAuth2SsoConfigurerAdapter,但是由于我们不再使用 spring-cloud-security,因此此类不可用。

更新:我发现使用 BeanPostProcessor 是可能的:

public static class DefaultRolesPrefixPostProcessor implements BeanPostProcessor, PriorityOrdered {

        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof FilterChainProxy) {

                FilterChainProxy chains = (FilterChainProxy) bean;

                for (SecurityFilterChain chain : chains.getFilterChains()) {
                    for (Filter filter : chain.getFilters()) {
                        if (filter instanceof OAuth2ClientAuthenticationProcessingFilter) {
                            OAuth2ClientAuthenticationProcessingFilter oAuth2ClientAuthenticationProcessingFilter = (OAuth2ClientAuthenticationProcessingFilter) filter;
                            oAuth2ClientAuthenticationProcessingFilter
                                    .setAuthenticationSuccessHandler(customAuthenticationSuccessHandler());
                        }
                    }
                }
            }
            return bean;
        }
    }

有没有更好的方法来配置它?

最佳答案

如果你关注 Dave Syers 优秀 Spring boot oauth2 tutorial ,你最终会得到一个返回你的 ssoFilter 的方法

我向这个过滤器添加了一个 setAuthenticationSuccessHandler

@Autowired
private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;


private Filter ssoFilter() {
    OAuth2ClientAuthenticationProcessingFilter facebookFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/facebook");
    OAuth2RestTemplate facebookTemplate = new OAuth2RestTemplate(facebook(), oauth2ClientContext);
    facebookFilter.setRestTemplate(facebookTemplate);
    facebookFilter.setTokenServices(new UserInfoTokenServices(facebookResource().getUserInfoUri(), facebook().getClientId()));
    facebookFilter.setAuthenticationSuccessHandler(customAuthenticationSuccessHandler);
    return facebookFilter;
} 

而我的 CustomAuthenticationSuccessHandler 只是一个扩展 AuthenticationSuccessHandler 的组件

@Component
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                    Authentication authentication) throws IOException, ServletException {
    //implementation
}

关于java - 使用 Spring Boot 1.3.2(没有 spring-cloud-security)和 @EnableOAuth2Sso 配置 AuthenticationSuccessHandler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35622563/

相关文章:

Java 8 无法在 FIPS 中加载其 cacerts。异常 "no such provider: SunEC"

java - 编码 - 在 java 中查找一系列数字的按位异或

java - Parcelable 类中的 Parcelable 列表未使用 Parcel.readTypedList 回读

java - @ManyToMany java spring boot

java - 我如何分析 Java 中的线程?

java - 文件可用后立即运行 Spring Batch 作业

java - 如何在 Spring Security 中撤销授权 token ?

spring-boot - Spring Oauth2 - 自定义TokenEndpoint从@RequestParam到@RequestBody

firebase - 如何使用 Java 中的 FCM 将带有自定义图像的推送通知发送到 Web 应用程序

java - 使用 QuerydslJpaPredicateExecutor 替换已弃用的 QuerydslJpaRepository 失败