问题
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
回答1:
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();
}
回答2:
The order of antMatchers is important.
More specific ones should go first. Least specific one should be last.
Reorder the antMatchers to be as follows:
.antMatchers(userAccess).hasRole("USER").anyRequest().authenticated()
.antMatchers(dataAccess).hasRole("DATA").anyRequest().authenticated()
.antMatchers(adminAccess).hasRole("ADMIN").anyRequest().authenticated()
.antMatchers(publicResources).permitAll()
I am assuming user is more specific than data.
回答3:
Strange authorization ... You need to change the logic.
In your config is written: publicResources
permitAll AND matcher userAccess
has role USER AND any requests authenticated AND matcher dataAccess
has role DATA AND any requests authenticated AND ... (multiple definitions of anyRequest)
来源:https://stackoverflow.com/questions/59392255/securing-url-using-user-roles-and-spring-security