Spring oauth2 hasRole access denied

I am really new to OAuth2 and trying to create a single server with auth.server roles to authorize users and save a protected resource ...

I have security issues using the ResourceServerConfigurerAdapter. It looks like he is ignoring all his roles, getting the form userInfoUrl ...

so here is the code:

AuthServer

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

__

@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");
    }
}

__

@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");
    }
}

ResourceServer

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

Thus, getting a token from authserver + calls "localhost: 9091 /" and "/ forAdmin" with this token.

But when I do this:

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

I get access denied ....

to make sure the roles reached the resource server, I changed geet () from above to

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

and the console shows

dkauth.Oa2ResourceServerApplication: with roles: [{authority = ROLE_USER}]

, "" , , , resourceerverer.... - ...

....

- ?

+4
4

AuthServer. , , , AuthoritiesExtractor. FixedAuthoritiesExtractor.

FixedAuthoritiesExtractor GrantedAuthority, asAuthorities.

private String asAuthorities(Object object) {
    if (object instanceof Collection) {
        return StringUtils.collectionToCommaDelimitedString((Collection<?>) object);
    }
    if (ObjectUtils.isArray(object)) {
        return StringUtils.arrayToCommaDelimitedString((Object[]) object);
    }
    return object.toString();
}

, , , , . , a List<Map<String,String>>. .

, ROLE_USER AuthServer. toString String {authority=ROLE_USER}. , ROLE_USER, {authority=ROLE_USER}

AuthoritiesExtractor.

public class OAuth2AuthoritiesExtractor implements AuthoritiesExtractor {

    static final String AUTHORITIES = "authorities";

    @Override
    public List<GrantedAuthority> extractAuthorities(Map<String, Object> map) {
        String authorities = "ROLE_USER";
        if (map.containsKey(AUTHORITIES)) {
            authorities = asAuthorities(map.get(AUTHORITIES));
        }
        return AuthorityUtils.commaSeparatedStringToAuthorityList(authorities);
    }

    @SuppressWarnings("unchecked")
    private String asAuthorities(Object object) {
        if (object instanceof Collection) {
            return (String) ((Collection) object).stream().map(o -> {
                if (o instanceof Map) {
                    return ((Map) o).values().stream().collect(Collectors.joining(","));
                }
                return o.toString();
            }).collect(Collectors.joining(","));

        }
        if (ObjectUtils.isArray(object)) {
            return StringUtils.arrayToCommaDelimitedString((Object[]) object);
        }
        return object.toString();
    }

}

, - .

, spring, {authority= String ROLE_USER, , isUserInRole.

+2

, .

Spring 4.x , .

.antMatchers("/forAdmin").hasRole("USER");

:

.antMatchers("/forAdmin").hasRole("ROLE_USER");

RoleVoter , , , , . , "ROLE_ADMIN, IS_AUTHENTICATED_FULLY", , IS_AUTHENTICATED_FULLY - AuthenticatedVoter .

:

, ConfigAttribute.getAttribute() . - ROLE_, . , , . , .

+1

, JWT , .

:

@PreAuthorize("#oauth2.hasScope('openid') and hasRole('ROLE_ADMIN')")

.

+1

The problem is that the token exchange through userInfoUri does not work correctly. You can protect resource servers from unauthorized access, but the access () method in the HttpSecurity configuration always rejects the request.

Adding the JWT token store fixed this.

I described this in detail in a blog article: stytex.de/blog/2016/02/01/spring-cloud-security-with-oauth2/

0
source

Source: https://habr.com/ru/post/1626560/


All Articles