I just added token authentication to my spring boot API and it's working well, with only one issue.
I want to use the /login
endpoint (with login and password) to get a token, which be then passed in the header to all services requiring authentication, namely logout
and everything on the /api/**
routes.
My issue is that I have to leave /login
unprotected but not the logout
one however I can't remove the line marked // TODO Why can't I remove this
in the following code or I get a 403 error (Forbidden) when accessing /logout
with or without token
And I don't get why, I think it's related maybe to my RequestMacther :
private static final RequestMatcher PROTECTED_URLS = new OrRequestMatcher(
new AntPathRequestMatcher("/api/**"),
new AntPathRequestMatcher("/logout/**")
);
However the /logout
does indeed requires authentication with token, so maybe it's not that.
TLDR everything is working well with this code but I'd like to remove the line after // TODO Why can't I remove this
but I get a 403 on /logout
if I do remove it
Any help appreciated.
My SecurityConfiguration :
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@AllArgsConstructor
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final RequestMatcher PROTECTED_URLS = new OrRequestMatcher(
new AntPathRequestMatcher("/api/**"),
new AntPathRequestMatcher("/logout/**")
);
AuthenticationProvider provider;
@Override
protected void configure(final AuthenticationManagerBuilder auth) {
auth.authenticationProvider(provider);
}
@Override
public void configure(final WebSecurity webSecurity) {
webSecurity.ignoring().antMatchers("/login/**");
// TODO Why can't I remove this
webSecurity.ignoring().antMatchers("/logout/**");
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.and()
.authenticationProvider(provider)
.addFilterBefore(authenticationFilter(), AnonymousAuthenticationFilter.class)
.authorizeRequests()
.requestMatchers(PROTECTED_URLS)
.authenticated()
.and()
.formLogin().disable()
.httpBasic().disable()
.logout().disable();
}
@Bean
AuthenticationFilter authenticationFilter() throws Exception {
final AuthenticationFilter filter = new AuthenticationFilter(PROTECTED_URLS);
filter.setAuthenticationManager(authenticationManager());
return filter;
}
@Bean
AuthenticationEntryPoint forbiddenEntryPoint() {
return new HttpStatusEntryPoint(HttpStatus.FORBIDDEN);
}
}
CodePudding user response:
You can configure it in the method configure(HttpSecurity http) by simply adding
http.authorizeRequests().antMatchers("/login").permitAll();
http.authorizeRequests().antMatchers("/logout").permitAll();
CodePudding user response:
So I found how to make it work, there seems to have been two/three issues :
- I had removed
.csrf().disable()
because it didn't seem to be good practice but actually this was causing some issues - order of the statements in the
configure(HttpSecurity http)
function is important, putting thelogout()
at the very end was apparently problematic - removed some uneeded code, which might or might have not contributed to the issue.
In the end here is my working SecurityConfiguration
:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@AllArgsConstructor
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final RequestMatcher PROTECTED_URLS = new OrRequestMatcher(
new AntPathRequestMatcher("/api/**"),
new AntPathRequestMatcher("/logout/**")
);
AuthenticationProvider provider;
@Override
protected void configure(final AuthenticationManagerBuilder auth) {
auth.authenticationProvider(provider);
}
@Override
public void configure(final WebSecurity webSecurity) {
webSecurity.ignoring().antMatchers("/login/**");
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable()
.logout().disable()
.exceptionHandling()
.and()
.authenticationProvider(provider)
.addFilterBefore(authenticationFilter(), AnonymousAuthenticationFilter.class)
.authorizeRequests()
.requestMatchers(PROTECTED_URLS)
.authenticated()
.and();
}
@Bean
AuthenticationFilter authenticationFilter() throws Exception {
final AuthenticationFilter filter = new AuthenticationFilter(PROTECTED_URLS);
filter.setAuthenticationManager(authenticationManager());
return filter;
}
}