Home > Back-end >  How to secure some URLS while keeping others without authentication?
How to secure some URLS while keeping others without authentication?

Time:03-17

I have a Spring Boot based application. I want the URL /camunda/app/welcome/default/#!/login to be accessible without any authentication, while the URLs

  • /camunda/app/welcome/default/#!/welcome,
  • /camunda/app/welcome/default/#!/dashboard,
  • /camunda/app/tasklist/**, and
  • /camunda/app/admin/**

must be secured (i. e. only authenticated users should be able to access them).

To achieve this, I wrote the following configuration:

@Configuration
@EnableWebSecurity
public class MyConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .requestMatchers()
            .and()
            .authorizeRequests()
            .antMatchers("/camunda/app/welcome/default/#!/login").permitAll()
            .antMatchers("/camunda/app/welcome/default/#!/welcome",
                "/camunda/app/welcome/default/#!/dashboard",
                "/camunda/app/tasklist/**",
                "/camunda/app/admin/**", 
                "/oauth2/authorization/**",
                "/oauth2/code/myredirecturl")
            .authenticated()
            .and()
            .oauth2Login(...)
            .logout()
                .logoutRequestMatcher(...)
                .logoutSuccessHandler(...);
    }

}

However with this configuration unauthenticated users can access URLs that are supposed to be protected (/camunda/app/welcome/default/#!/welcome, /camunda/app/welcome/default/#!/dashboard, /camunda/app/tasklist/**, /camunda/app/admin/**).

What is wrong with my configuration and how can I fix it?

CodePudding user response:

Make sure you use the URL encoding of #, which is # when calling the endpoints. Otherwise, the characters after the # will not be considered.

Making a request to /camunda/app/welcome/default/#!/welcome without properly encoding will be interpreted as a request to /camunda/app/welcome/default/. Since that endpoint doesn't require authentication then anyone will be allowed to access it.

Since all endpoints except /camunda/app/welcome/default/#!/login require authentication you condense your HttpSecurity configuration. I'll rewrite it below using the lambda style configuration to make it more readable:

http
    // no need to add requestMatchers since you aren't changing the default configuration
    .authorizeRequests(authz -> authz
        .antMatchers("/camunda/app/welcome/default/#!/login").permitAll()
        .anyRequest().authenticated() // any request that does not match the above rule ^ will require an authenticated user
    )
    .oauth2Login(...)
    .logout(...)

CodePudding user response:

Sadly to say, but that will not work, because there is actually only one url:

/camunda/app/welcome/default/

and parts after '#' symbol are called 'anchors':

#!/welcome, #!/dashboard,

Anchors are not processed on backend, because they point to some place in html document that was loaded on client side.

https://www.w3docs.com/snippets/html/how-to-create-an-anchor-link-to-jump-to-a-specific-part-of-a-page.html

So you cant solve it by Spring only, there must be some frontend logic.

Also these two masks:

/camunda/app/tasklist/, and /camunda/app/admin/

could be covered by Spring Boot, because point to different urls, not anchors.

  • Related