简体   繁体   中英

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/

I need to set a few arbitrary cookies after a successful login to simplify things in my frontend browser application.

Currently I have a working setup that authenticates a user with a Google account utilizing OAuth2.

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.

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.

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

I've done some further digging in the OAuth2ClientAuthenticationProcessingFilter implementation and found the following possible solution.

It's possible to plug in a custom SessionAuthenticationStrategy which by default is not implemented. The interface documentation states the following:

Allows pluggable support for HttpSession-related behaviour when an authentication occurs.

I've changed the ssoFilter() to the following:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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