Spring oauth2 hasRole 访问被拒绝

Dav*_*man 5 spring spring-cloud spring-oauth2

我真的是 OAuth2 的新手,并尝试在角色 auth.server 中构建一台服务器来授权用户,并尝试保留受保护的资源...

我有一些问题需要使用 ResourceServerConfigurerAdapter 来确保安全。似乎他忽略了从 userInfoUrl 中获取的所有角色......

所以这里的代码:

认证服务器

@SpringBootApplication
@EnableAuthorizationServer
@EnableResourceServer
@RestController
public class Oa2AuthServerApplication {

    @RequestMapping("/user")
    public Principal user(Principal user) {
        return user;
    }
    public static void main(String[] args) {
        SpringApplication.run(Oa2AuthServerApplication.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)

__

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("admin")
                .password("admin")
                .roles("ADMIN", "USER")
                .and()
                .withUser("user")
                .password("user")
                .roles("USER");
    }
}
Run Code Online (Sandbox Code Playgroud)

__

@Configuration
public class OA2AuthConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("default")
                .secret("kx")
                .scopes("AUTH", "TRUST")
                .autoApprove(true)
                .authorities("ROLE_GUEST", "ROLE_USER", "ROLE_ADMIN")
                .authorizedGrantTypes("authorization_code", "implicit", "refresh_token");
    }
}
Run Code Online (Sandbox Code Playgroud)

资源服务器

@SpringBootApplication
@RestController
@EnableResourceServer
public class Oa2ResourceServerApplication {
    @RequestMapping("/")
    public String greet() {
        return UUID.randomUUID().toString() + "\r\n";
    }

    @RequestMapping("/forAdmin")
    public String admin() {
        return "hi admin!";
    }


    public static void main(String[] args) {
        SpringApplication.run(Oa2ResourceServerApplication.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,从 authserver 获取令牌 + 调用“localhost:9091/”和“/forAdmin”可使用此令牌。

但是当我这样做时:

public class WebSecurityConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/forAdmin").hasRole("USER");
    }
Run Code Online (Sandbox Code Playgroud)

我被拒绝访问....

可以肯定的是,角色正在到达资源服务器,我已将 geet() 从上面更改为

@RequestMapping("/")
    public String greet(Principal user) {
        if (user instanceof OAuth2Authentication) {
            log.info("having roles: {}", ((OAuth2Authentication) user).getAuthorities());
        }
        return UUID.randomUUID().toString() + "\r\n";
    }
Run Code Online (Sandbox Code Playgroud)

控制台显示

dkauth.Oa2ResourceServerApplication :具有角色:[{authority=ROLE_USER}]

因此,当“主体”是当前经过身份验证的用户时,我认为资源服务器配置器存在错误......或者我正在做一些致命的错误......

或者两者都有......我不知道

有人可以帮助我解决这个问题吗?

Pau*_*nis 2

我认为您缺少角色前缀。

从 Spring Security 4.x 开始,角色必须带有前缀,例如,如果您正在做

.antMatchers("/forAdmin").hasRole("USER");
Run Code Online (Sandbox Code Playgroud)

你必须将其更改为:

.antMatchers("/forAdmin").hasRole("ROLE_USER");
Run Code Online (Sandbox Code Playgroud)

角色由 RoleVoter 处理,并且具有前缀让投票者知道哪些标记是角色名称,以便它可以忽略无法处理的标记。例如,您可以指定“ROLE_ADMIN,IS_AUTHENTICATED_FULLY”,但您不希望该投票者处理 IS_AUTHENTICATED_FULLY - AuthenticatedVoter 应该处理该问题。

来自官方文档

如果任何 ConfigAttribute.getAttribute() 以表明它是角色的前缀开头,则进行投票。默认前缀字符串是 ROLE_,但这可以被覆盖为任何值。它也可以设置为空,这意味着基本上任何属性都将被投票。如下文进一步描述的,空前缀的效果可能不太理想。