Summary
Based on that docs it's possible to configure two authentication methods at the same Spring Instance, but for some reason I can't not achieve this. I'm trying to use basic and form login.
Actual Behavior
One of the two auth methods will be ignored
curl -I localhost:8080/website && curl -I localhost:8080/api
HTTP/1.1 404
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 27 Jul 2018 03:01:00 GMT
HTTP/1.1 401
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Set-Cookie: JSESSIONID=99E8D742F1E96361D9430B4BC09D55A5;path=/;HttpOnly
WWW-Authenticate: Basic realm="Realm"
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 27 Jul 2018 03:01:00 GMT
Expected Behavior
/api/**protected by basic auth/website/**protected by form login
Configuration / Version / Sample
I have a running sample right here
Comment From: mageddo
Okay, I got it.
- You have run the more specific configurations first
- You have to use
antMatcherand notantMatchers
It works
@EnableWebSecurity
public class SecurityConfig {
@Bean
public UserDetailsService userDetailsService(final PasswordEncoder encoder) {
final InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(
User
.withUsername("admin")
.password(encoder.encode("admin"))
.roles("ADMIN")
.build()
);
return manager;
}
@Bean PasswordEncoder encoder(){
return new BCryptPasswordEncoder();
}
@Configuration
@Order(1)
public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest().hasRole("API_USER")
.and();
}
}
@Configuration
@Order(2)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/website/**").hasRole("ADMIN")
.and()
.formLogin()
.and()
.logout().permitAll()
;
}
}
}
It doesn't
@EnableWebSecurity
public class SecurityConfig {
@Bean
public UserDetailsService userDetailsService(final PasswordEncoder encoder) {
final InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(
User
.withUsername("admin")
.password(encoder.encode("admin"))
.roles("ADMIN")
.build()
);
return manager;
}
@Bean PasswordEncoder encoder(){
return new BCryptPasswordEncoder();
}
@Configuration
@Order(2)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/website/**").hasRole("ADMIN")
.and()
.formLogin()
.and()
.logout().permitAll()
;
}
}
@Configuration
@Order(1)
public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/**").hasRole("API_USER")
.and()
.httpBasic();
}
}
}
Jeez, I lost 3 days working on that thing.
Comment From: chiragsoni2401
I am using above multiple configurations but at the place of form login I am redirecting to an okta idp it is working fine but at the place of httpBasic() if I you something else like fomLogin or if I not use anything means I directly make post request to /api/** then I am getting 403 forbidden error.
So basically I want to know that in case of multiple http elements it is necessary to have formLogin(), and httpBasics() or we can replace these as per our need.
Comment From: mageddo
I have this running example for form and basic http if it would help you
Comment From: pradeepkl
- Any specific reason why we need to add the
antMatcherinstead ofantMatchers? - Is the antMatcher only required for the
Configurationmarked withOrder(1)?