Search code examples
javaspringspring-securityuser-roles

Securing URL using User Roles and Spring Security


I have multiple User Roles in my Java application. Here is my code:

private String userAccess[] = new String[]{"/dashboard/**"};
private String dataAccess[] = new String[]{"/dashboard/**", "/data/**"};
private String adminAccess[] = new String[]{"/dashboard/**", "/data/**", "/admin/**"};

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
        .authorizeRequests()
        .antMatchers(publicResources).permitAll()
            .antMatchers(userAccess).hasRole("USER").anyRequest().authenticated()
            .antMatchers(dataAccess).hasRole("DATA").anyRequest().authenticated()
            .antMatchers(adminAccess).hasRole("ADMIN").anyRequest().authenticated()

Error:

2019-12-18T12:00:34.059+0000 DEBUG Secure object: FilterInvocation: URL: /dashboard; Attributes: hasAnyRole('ROLE_ADMIN') 2019-12-18T12:00:34.059+0000 DEBUG Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@62aad9e7: Principal: userdetails.CustomUserDetails@2228ff0d; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_DATA 2019-12-18T12:00:34.059+0000 DEBUG Voter: org.springframework.security.web.access.expression.WebExpressionVoter@6925373, returned: -1 2019-12-18T12:00:34.062+0000 DEBUG Access is denied (user is not anonymous); delegating to AccessDeniedHandler org.springframework.security.access.AccessDeniedException: Access is denied

Sorry, cannot seem to get the Exception showing in the "code" tag here :(

The problem now is when I logon with ADMIN all works 100%. But when I logon with USER or DATA, then I get an exception saying that I tried to access and unauthorised page.

So what is happening is that it loads the URL access for user DATA, but when the last line executes, it changes the /dashboard URL to have ADMIN access. My Role is still DATA role and thus don't have access to the /dashboard URL.

So it seems like the last line is overwriting the others. Looking at the URL privileges again, if I remove "/dashboard", then I will get the same issue when it comes to the "/data" URL.

Is there a better way of doing this or maybe a way for me to resolve this?

Thanks


Solution

  • What if not repeat an endpoint for role

    private String userAccess[] = new String[]{"/dashboard/**"};
        private String dataAccess[] = new String[]{"/data/**"};
        private String adminAccess[] = new String[]{"/admin/**"};
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable()
                    .authorizeRequests()
                    .antMatchers(publicResources).permitAll()
                    .antMatchers(userAccess).hasAnyRole("USER", "DATA", "ADMIN").anyRequest().authenticated()
                    .antMatchers(dataAccess).hasAnyRole("DATA", "ADMIN").anyRequest().authenticated()
                    .antMatchers(adminAccess).hasRole("ADMIN").anyRequest().authenticated();
        }