在Spring Security OAuth2实现中成功完成OAuth2身份验证时设置Cookie

时间:2019-07-30 08:35:47

标签: java spring spring-boot cookies spring-security-oauth2

根据https://spring.io/guides/tutorials/spring-boot-oauth2/提供的指南,我正在实现一个稍微简单的OAuth2安全的Web应用程序。

成功登录后,我需要设置一些任意cookie,以简化前端浏览器应用程序中的操作。

当前,我有一个有效的设置,可以使用OAuth2使用Google帐户对用户进行身份验证。

我打算在HttpSecurity oauth2Login().successHandler()函数中使用WebSecurityConfigurerAdapter configure(),但是我没有提供ClientRegistrationRepository,但似乎无法自动接线。

我似乎在任何地方都找不到关于如何向该指南中介绍的实现添加其他登录成功逻辑的标准方法。

这是我的主要应用程序类,在application.yml文件中配置了OAuth2客户端。

@SpringBootApplication
@EnableOAuth2Client
public class RestApplication extends WebSecurityConfigurerAdapter {

    @Autowired
    LogoutSuccessHandler logoutHandler;

    @Autowired
    OAuth2ClientContext oauth2ClientContext;

    public static void main(String[] args) {
        SpringApplication.run(RestApplication.class, args);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
        .antMatcher("/**").authorizeRequests()
        .antMatchers("/", "/login**", "/error**", "/webapp/**").permitAll()
        .anyRequest().authenticated()
        .and().addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class)
        .logout().logoutSuccessUrl("/").invalidateHttpSession(true).clearAuthentication(true).deleteCookies("JSESSIONID").logoutSuccessHandler(logoutHandler)
        // @formatter:on
    }

    private Filter ssoFilter() {
        OAuth2ClientAuthenticationProcessingFilter authFilter = new OAuth2ClientAuthenticationProcessingFilter(
                "/login");

        OAuth2RestTemplate oAuthTemplate = new OAuth2RestTemplate(oAuth2ResourceDetails(), oauth2ClientContext);
        UserInfoTokenServices tokenServices = new UserInfoTokenServices(oAuth2Resource().getUserInfoUri(),
                oAuth2ResourceDetails().getClientId());

        authFilter.setRestTemplate(oAuthTemplate);
        tokenServices.setRestTemplate(oAuthTemplate);
        authFilter.setTokenServices(tokenServices);

        return authFilter;
    }

    @Bean
    @ConfigurationProperties("oauth.client")
    public AuthorizationCodeResourceDetails oAuth2ResourceDetails() {
        return new AuthorizationCodeResourceDetails();
    }

    @Bean
    @ConfigurationProperties("oauth.resource")
    public ResourceServerProperties oAuth2Resource() {
        return new ResourceServerProperties();
    }

    @Bean
    public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(
            OAuth2ClientContextFilter filter) {
        FilterRegistrationBean<OAuth2ClientContextFilter> registration = new FilterRegistrationBean<OAuth2ClientContextFilter>();
        registration.setFilter(filter);
        registration.setOrder(-100);
        return registration;
    }
}

添加逻辑的正确方法是什么,该逻辑将在成功认证期间发生一次,特别是在我可以访问用户Principal对象之后。

1 个答案:

答案 0 :(得分:0)

我在OAuth2ClientAuthenticationProcessingFilter实现中做了进一步的挖掘,发现了以下可能的解决方案。

可以插入默认情况下未实现的自定义SessionAuthenticationStrategy。界面文档指出以下内容:

  

当身份验证发生时,可插入支持HttpSession相关行为。

我将ssoFilter()更改为以下内容:

private Filter ssoFilter() {
        OAuth2ClientAuthenticationProcessingFilter authFilter = new OAuth2ClientAuthenticationProcessingFilter(
                "/login");

        authFilter.setSessionAuthenticationStrategy(new SessionAuthenticationStrategy() {
            @Override
            public void onAuthentication(Authentication authentication, HttpServletRequest request,
                    HttpServletResponse response) throws SessionAuthenticationException {
                LinkedHashMap<String, Object> userDets = (LinkedHashMap<String, Object>) ((OAuth2Authentication) authentication)
                        .getUserAuthentication().getDetails();
                response.addCookie(new Cookie("authenticated", userDets.get("email").toString()));
            }
        });

        OAuth2RestTemplate oAuthTemplate = new OAuth2RestTemplate(oAuth2ResourceDetails(), oauth2ClientContext);
        UserInfoTokenServices tokenServices = new UserInfoTokenServices(oAuth2Resource().getUserInfoUri(),
                oAuth2ResourceDetails().getClientId());

        authFilter.setRestTemplate(oAuthTemplate);
        tokenServices.setRestTemplate(oAuthTemplate);
        authFilter.setTokenServices(tokenServices);

        return authFilter;
    }
相关问题