【问题标题】:Securing URL using User Roles and Spring Security使用用户角色和 Spring Security 保护 URL
【发布时间】:2020-04-11 00:28:28
【问题描述】:

我的 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 调试安全对象:FilterInvocation:URL:/dashboard;属性:hasAnyRole('ROLE_ADMIN') 2019-12-18T12:00:34.059+0000 DEBUG 先前已验证:org.springframework.security.authentication.UsernamePasswordAuthenticationToken@62aad9e7:主体:userdetails.CustomUserDetails@2228ff0d;凭证:[受保护];已认证:真实;详细信息:org.springframework.security.web.authentication.WebAuthenticationDetails@b364:RemoteIpAddress:0:0:0:0:0:0:0:1;会话ID:空;授予权限:ROLE_DATA 2019-12-18T12:00:34.059+0000 调试投票者:org.springframework.security.web.access.expression.WebExpressionVoter@6925373,返回:-1 2019-12-18T12:00:34.062+0000 DEBUG 访问被拒绝(用户不是匿名的);委托给 AccessDeniedHandler org.springframework.security.access.AccessDeniedException:访问被拒绝

抱歉,这里的“代码”标签中似乎无法显示异常:(

现在的问题是当我使用 ADMIN 登录时,所有工作都 100% 正常。但是当我使用 USER 或 DATA 登录时,我得到一个异常,说我试图访问和未经授权的页面。

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

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

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

谢谢

【问题讨论】:

    标签: java spring spring-security user-roles


    【解决方案1】:

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

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

    【讨论】:

    • 应该有一个anyRequest().authenticated(),应该是最后一个。
    【解决方案2】:

    antMatchers 的顺序很重要。

    更具体的应该先写。最不具体的应该是最后一个。

    将 antMatchers 重新排序如下:

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

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

    【讨论】:

    • 是的,因为您还没有完全理解匹配器。排序很重要,第一个匹配的获胜。所以/dashboard/** 总是匹配用户,不会落空。
    【解决方案3】:

    奇怪的授权......你需要改变逻辑。 在你的配置中写着:publicResources permitAll AND matcher userAccess has role USER AND any requests authenticated AND matcher dataAccess has role DATA AND any requests authenticated AND ...(anyRequest 的多个定义)

    【讨论】:

    • 您这里没有提供任何答案或解决方案?
    猜你喜欢
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    • 2014-03-07
    • 2017-12-29
    • 1970-01-01
    • 2011-07-21
    • 2022-08-09
    • 1970-01-01
    相关资源
    最近更新 更多