简体   繁体   English

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

[英]Set cookies on successful OAuth2 Authentication in Spring Security OAuth2 implementation

I'm implementing a somewhat simple OAuth2 secured web application according to the guide provided at https://spring.io/guides/tutorials/spring-boot-oauth2/ 我正在根据https://spring.io/guides/tutorials/spring-boot-oauth2/提供的指南实现一个稍微简单的OAuth2安全的Web应用程序

I need to set a few arbitrary cookies after a successful login to simplify things in my frontend browser application. 成功登录后,我需要设置一些任意cookie,以简化前端浏览器应用程序中的操作。

Currently I have a working setup that authenticates a user with a Google account utilizing OAuth2. 目前,我有一个有效的设置,可以使用OAuth2使用Google帐户对用户进行身份验证。

I intended to use HttpSecurity oauth2Login().successHandler() in my WebSecurityConfigurerAdapter configure() function however I have no ClientRegistrationRepository provided and I don't seem to be able to autowire it. 我打算在我的WebSecurityConfigurerAdapter configure()函数中使用HttpSecurity oauth2Login().successHandler() ,但是我没有提供ClientRegistrationRepository ,而且似乎无法自动装配它。

I couldn't seem to find any standard approach documented anywhere on how to add additional login success logic to the implementation presented in that guide. 我似乎在任何地方都找不到关于如何向该指南中介绍的实现添加其他登录成功逻辑的标准方法。

This is my main application class, OAuth2 client is configured in the application.yml file. 这是我的主要应用程序类,在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;
    }
}

What would be the correct way to add logic that would happen once during a successful authentication, specifically after I have access to the user Principal object. 添加逻辑的正确方法是什么,该逻辑将在成功认证期间发生一次,特别是在我可以访问用户Principal对象之后。

I've done some further digging in the OAuth2ClientAuthenticationProcessingFilter implementation and found the following possible solution. 我在OAuth2ClientAuthenticationProcessingFilter实现中做了进一步的挖掘,并找到了以下可能的解决方案。

It's possible to plug in a custom SessionAuthenticationStrategy which by default is not implemented. 可以插入默认情况下未实现的自定义SessionAuthenticationStrategy The interface documentation states the following: 接口文档指出以下内容:

Allows pluggable support for HttpSession-related behaviour when an authentication occurs. 进行身份验证时,可插入支持与HttpSession相关的行为。

I've changed the ssoFilter() to the following: 我已将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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM