2

I have two REST endpoints:

  1. /noAuth/rest/sayHi
  2. /rest/auth/getMsg

I want to give login for only /rest/auth/getMsg and direct access to /noAuth/rest/sayHi.

When I am using below pattern in WebSecurityConfigurerAdapter.configure(HttpSecurity http)

@EnableWebSecurity
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("Java Techie")
                .password("Password")
                .roles("ADMIN");
        auth
            .inMemoryAuthentication()
                .withUser("Basant")
                .password("Password2")
                .roles("USER");
    }

    @Override 
    protected void configure(HttpSecurity http) throws Exception {
       http
           .authorizeRequests()
               .antMatchers("/rest/**").authenticated()
               .anyRequest().permitAll()
               .and()
           .httpBasic();}
    }
}

I only get login prompt in /rest/auth/getMsg but not in /noAuth/rest/sayHi, which is as expected.

But when I use below pattern, I get login prompt in both /rest/auth/getMsg and /noAuth/rest/sayHi which is quite unexpected for me.

http
    .authorizeRequests()
        .anyRequest().authenticated()
        .antMatchers("/rest/**").permitAll()
        .and()
    .httpBasic();`

I know for IInd time I am doing something wrong, so I want to understand why I am not getting login for only /rest/auth/getMsg and direct access to /noAuth/rest/sayHi.

Update

@nully It makes some sense but breaks my understanding for other case. Lets say if I use this pattern:

http
    .authorizeRequests()
        .anyRequest().authenticated()
        .anyRequest().hasRole("ADMIN")
        .and()
    .httpBasic();`

allows only user = "Java Techie " to login since it is an ADMIN and throws 403 Forbidden for user = "Basant".

But when I use

http
    .authorizeRequests()
        .anyRequest().authenticated()
        .antMatchers("/rest/**").hasRole("ADMIN")
        .and()
    .httpBasic();

from your explanation it should not allow user = "Basant" to access /rest/auth/getMsg since it has role = "USER". But actually it is allowing me to access /rest/auth/getMsg when I use user = "Basant".

ASharma7
  • 726
  • 3
  • 8
  • 27
  • So stack overflow is asking me to Mark for your answer "That solved my problem" ! wud that give give you any reps ?? You can post your ans here otherwise & I can accept the answer over here – ASharma7 Apr 30 '19 at 22:57
  • Don't worry about accepting an answer. The possible duplicate link will redirect people or maybe your question will be deleted later. – Anthony Apr 30 '19 at 23:26
  • 1
    @ASharma7 No, you can't accept my answer in the other question. You could only accept answers in your own question. But you could upvote my answer (I think you already did it). Yes, I would get additional rep, if I write another answer in your question that you accept. But that is not the way SO like it. Some users are downvoting duplicate answers of the same user. – dur May 01 '19 at 09:16
  • 1
    Ordering of the filter/security rules is important. You first request that everything needs to be authenticated, then do an exclusion. You should switch the order, first do all specific matches then the more global ones. Rules are consulted in the order they are defined in and the first match is the match that will be picked. In this case always authenticate. – M. Deinum May 07 '19 at 06:11

2 Answers2

1

The default is to require authentication if no other rule is in place. You should add something like antMatchers("/noAuth/**").permitAll().

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
  • I added for "/noAuth/** but still i am getting login for /noAuth/rest/sayHi --"http.authorizeRequests().anyRequest().authenticated().antMatchers("/rest/**").permitAll().antMatchers("/noAuth/**").permitAll().and().httpBasic(); – ASharma7 Apr 29 '19 at 05:15
0

Execution is going from left to right. In the first case : .antMatchers("/rest/").authenticated(), so authenticate anything matching rest/

in the 2 case: .anyRequest().authenticated(), so any request will get authentication required before moving forward.

nully
  • 43
  • 1
  • 10
  • 1
    I would try to keep stuff simple: http.authorizeRequests().antMatchers("/rest/**").access("hasRole('ADMIN')"); should work. I'm unfortunate no springboot expert, so I try to keep it short and clear. – nully Apr 28 '19 at 21:11
  • This one I have idea that it works fine.Just wanted to understand why second one doesn't works.Thank you for your time. I appreciate you help. – ASharma7 Apr 28 '19 at 21:21