简体   繁体   English

使用用户角色和 Spring Security 保护 URL

[英]Securing URL using User Roles and Spring Security

I have multiple User Roles in my Java application.我的 Java 应用程序中有多个用户角色。 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; 2019-12-18T12:00:34.059+0000 DEBUG 安全对象: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;属性:hasAnyRole('ROLE_ADMIN') 2019-12-18T12:00:34.059+0000 DEBUG 先前认证:org.springframework.security.authentication.UsernamePasswordAuthenticationToken@62aad9e7: Principal: userdetails@20d2UserDetails. Credentials: [PROTECTED];凭据:[受保护]; Authenticated: true;已认证:真实; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1;详细信息:org.springframework.security.web.authentication.WebAuthenticationDetails@b364:RemoteIpAddress:0:0:0:0:0:0:0:1; SessionId: null;会话 ID:空; 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);授予权限:ROLE_DATA 2019-12-18T12:00:34.059+0000 DEBUG 投票者:org.springframework.security.web.access.expression.WebExpressionVoter@6925373,返回:-1 2019-12-18T12.00000000000000000000000000000000000003访问被拒绝(用户不是匿名的); delegating to AccessDeniedHandler org.springframework.security.access.AccessDeniedException: Access is denied委托给 AccessDeniedHandler org.springframework.security.access.AccessDeniedException:访问被拒绝

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%.现在的问题是,当我使用 ADMIN 登录时,所有工作 100%。 But when I logon with USER or DATA, then I get an exception saying that I tried to access and unauthorised page.但是当我使用 USER 或 DATA 登录时,我收到一个异常,说我试图访问和未经授权的页面。

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.所以发生的事情是它加载了用户 DATA 的 URL 访问权限,但是当最后一行执行时,它更改 /dashboard URL 以具有 ADMIN 访问权限。 My Role is still DATA role and thus don't have access to the /dashboard URL.我的角色仍然是 DATA 角色,因此无权访问 /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.再次查看 URL 权限,如果我删除“/dashboard”,那么当涉及到“/data”URL 时,我会遇到同样的问题。

Is there a better way of doing this or maybe a way for me to resolve this?有没有更好的方法来做到这一点,或者我有办法解决这个问题?

Thanks谢谢

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

The order of antMatchers is important. antMatchers 的顺序很重要。

More specific ones should go first.更具体的应该先行。 Least specific one should be last.最不具体的应该放在最后。

Reorder the antMatchers to be as follows:将 antMatchers 重新排序如下:

.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.我假设用户比数据更具体。

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)在您的配置中写着: publicResources permitAll AND matcher userAccess具有角色 USER AND 任何请求已通过身份验证 AND matcher dataAccess具有角色 DATA AND 任何请求已通过身份验证 AND ...(anyRequest 的多个定义)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM