Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AwsCognitoJwtAuthenticationFilter bean is registered twice when placed in Spring Security Filter Chain #13

Open
ddewaele opened this issue Jul 27, 2018 · 9 comments

Comments

@ddewaele
Copy link
Contributor

Spring automatically registers all filter beans and puts it in the top level filter chain.
This means that when adding the AwsCognitoJwtAuthenticationFilter to the spring security filter chain (using addFilterBefore or addFilterAfter) it will be registered twice. Once in the top-level chain and once in the spring security filter chain.

Adding this will avoid spring registering it in the top level filter.

    @Bean
    public FilterRegistrationBean registration(AwsCognitoJwtAuthenticationFilter awsCognitoJwtAuthenticationFilter) {
        FilterRegistrationBean registration = new FilterRegistrationBean(awsCognitoJwtAuthenticationFilter);
        registration.setEnabled(false);
        return registration;
    }
@xanscale
Copy link
Contributor

in this way i need to register manually with addFilterBefore? only with your bean i receive:

2018-07-27 14:23:42.834  INFO 18245 --- [ost-startStop-1] o.s.boot.web.servlet.RegistrationBean    : Filter awsCognitoJwtAuthenticationFilter was not registered (disabled)
2018-07-27 14:23:42.839  INFO 18245 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-07-27 14:23:42.840  INFO 18245 --- [ost-startStop-1] o.s.boot.web.servlet.RegistrationBean    : Filter myHlJwtAuthenticationFilter was not registered (disabled)
2018-07-27 14:23:42.840  INFO 18245 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-07-27 14:23:42.840  INFO 18245 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-07-27 14:23:42.840  INFO 18245 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2018-07-27 14:23:42.841  INFO 18245 --- [ost-startStop-1] .s.DelegatingFilterProxyRegistrationBean : Mapping filter: 'springSecurityFilterChain' to: [/*]
2018-07-27 14:23:42.841  INFO 18245 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpTraceFilter' to: [/*]
2018-07-27 14:23:42.841  INFO 18245 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'webMvcMetricsFilter' to: [/*]
2018-07-27 14:23:42.841  INFO 18245 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestLoggingFilter' to: [/*]

@ddewaele
Copy link
Contributor Author

What you're seeing here is the top level filter chain that the spring context is building. (All filters that are either registered via a FilterRegistrationBean, or GenericFilterBeans).

If you want to make use of Spring Security features, I think it's best to make sure your filter is hooked into the springSecurityFilterChain. To do that you make sure Spring doesn't register it automatically, and you create a new security config (via a WebSecurityConfigurer) to hook your filter in the spring security filter before or after an existing filter.

It is also mentioned here : https://spring.io/guides/topicals/spring-security-architecture/

The fact that all filters internal to Spring Security are unknown to the container is important, especially in a Spring Boot application, where all @beans of type Filter are registered automatically with the container by default. So if you want to add a custom filter to the security chain, you need to either not make it a @bean or wrap it in a FilterRegistrationBean that explicitly disables the container registration.

@xanscale
Copy link
Contributor

with this configuration all works fine but i don't know if this is a correct way

@Configuration
public class HcaWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
	@Autowired
	private AwsCognitoJwtAuthenticationFilter awsCognitoJwtAuthenticationFilter;

	@Autowired
	private HcaAuthenticationEntryPoint hcaAuthenticationEntryPoint;

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.cors().and().authorizeRequests().anyRequest().authenticated().and()
				.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
				.exceptionHandling().authenticationEntryPoint(hcaAuthenticationEntryPoint).and()
				.addFilterBefore(awsCognitoJwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
				.addFilterBefore(new MyHlJwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
		;
	}

	@Bean
	public FilterRegistrationBean unregister(AwsCognitoJwtAuthenticationFilter awsCognitoJwtAuthenticationFilter) {
		FilterRegistrationBean registration = new FilterRegistrationBean<>(awsCognitoJwtAuthenticationFilter);
		registration.setEnabled(false);
		return registration;
	}
}

@ddewaele
Copy link
Contributor Author

Looks ok to me .. I'm probably going to disable the filter registration by default in the auto config of this library so you don't have to do it in code anymore. That will solve this ticket and if the config above works for you we can also close issue #12

@xanscale
Copy link
Contributor

"disable the filter registration by default" i think is the correct coice

i have a question about:

.addFilterBefore(awsCognitoJwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new MyHlJwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)

i put aws and custom filter beforce UsernamePasswordAuthenticationFilter, but is not clear the order, actually works correctly but i fear that is a coincidence.

i need my custom fitler chained after Cognito, this is the correct way? i don't want that in a future version of spring change somethings internal and my code stop works.
i tried somethings like that but spring not start

.addFilterBefore(awsCognitoJwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new MyHlJwtAuthenticationFilter(), AwsCognitoJwtAuthenticationFilter.class)

@ddewaele
Copy link
Contributor Author

Yes, misread your original config .... that indeed didn't make the order explicit.
Your last snippet should work ... what is the error you are getting ?

@xanscale
Copy link
Contributor

sorry seams something wrong before, now works

just i receive 2 invocation per fiter:

@Configuration
public class HcaWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
	@Autowired
	private AwsCognitoJwtAuthenticationFilter awsCognitoJwtAuthenticationFilter;
	@Autowired
	private MyHlJwtAuthenticationFilter myHlJwtAuthenticationFilter;
	@Autowired
	private HcaAuthenticationEntryPoint hcaAuthenticationEntryPoint;

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.cors();
		http.authorizeRequests().anyRequest().authenticated();
		http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
		http.exceptionHandling().authenticationEntryPoint(hcaAuthenticationEntryPoint);
		http.addFilterBefore(myHlJwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
		http.addFilterBefore(awsCognitoJwtAuthenticationFilter, MyHlJwtAuthenticationFilter.class);
	}

	@Bean
	public FilterRegistrationBean awsBean(AwsCognitoJwtAuthenticationFilter awsCognitoJwtAuthenticationFilter) {
		FilterRegistrationBean registration = new FilterRegistrationBean<>(awsCognitoJwtAuthenticationFilter);
		registration.setEnabled(false);
		return registration;
	}

	@Bean
	public FilterRegistrationBean myhlBean(MyHlJwtAuthenticationFilter myHlJwtAuthenticationFilter) {
		FilterRegistrationBean registration = new FilterRegistrationBean<>(myHlJwtAuthenticationFilter);
		registration.setEnabled(false);
		return registration;
	}
}
@Component
public class MyHlJwtAuthenticationFilter extends GenericFilterBean {}

@xanscale
Copy link
Contributor

xanscale commented Aug 3, 2018

@ddewaele also with only your filter using FilterRegistrationBean (enabled false) and addFilterBefore i receive 2 invocation.

another question are you sure to extends GenericFilterBean and not AbstractAuthenticationProcessingFilter ?

@xanscale
Copy link
Contributor

xanscale commented Aug 6, 2018

@ddewaele can you make version without autoregistration and read my pull request about a little fix ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants