使用用户角色和 Spring 安全保护 URL

Securing URL using User Roles and Spring Security

我的 Java 应用程序中有多个用户角色。 这是我的代码:

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()

错误:

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

抱歉,似乎无法在此处的 "code" 标记中显示异常 :(

现在的问题是当我使用 ADMIN 登录时一切正常 100%。但是,当我使用 USER 或 DATA 登录时,出现异常,提示我尝试访问未经授权的页面。

所以发生的事情是它加载了用户数据的 URL 访问权限,但是当最后一行执行时,它将 /dashboard URL 更改为具有 ADMIN 访问权限。我的角色仍然是 DATA 角色,因此无法访问 /dashboard URL.

所以最后一行似乎覆盖了其他行。再次查看 URL 权限,如果我删除“/dashboard”,那么当涉及到“/data”时我会遇到同样的问题 URL.

是否有更好的方法或者我可以解决这个问题?

谢谢

antMatchers 的顺序很重要。

更具体的应该放在第一位。最不具体的应该放在最后。

将 antMatchers 重新排序如下:

.antMatchers(userAccess).hasRole("USER").anyRequest().authenticated()
            .antMatchers(dataAccess).hasRole("DATA").anyRequest().authenticated()
            .antMatchers(adminAccess).hasRole("ADMIN").anyRequest().authenticated()
            .antMatchers(publicResources).permitAll()

我假设用户比数据更具体。

奇怪的授权...您需要更改逻辑。 在您的配置中写入:publicResources permitAll AND matcher userAccess 具有角色 USER AND any requests authenticated AND matcher dataAccess has role DATA AND any requests authenticated AND ...(anyRequest 的多个定义)

如果不为角色重复端点会怎样

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();
    }