2
votes

I am trying to get oauth2 to work with spring-boot and protect my rest method calls, sans much success. I have tried using spring-security-oauth2-javaconfig:1.0.0.CI-SNAPSHOT with rg.springframework.boot:spring-boot-starter-security:1.0.0.RC1.

*gradle: compile("org.springframework.boot:spring-boot-starter-security:1.0.0.RC1")

compile ('org.springframework.security.oauth:spring-security-oauth2-javaconfig:1.0.0.CI-SNAPSHOT'){
    exclude module: 'spring-security-config'
    exclude module: 'spring-security-core'
    exclude module: 'spring-security-web'
}

For now I am just trying to get the authentication and resource server working. I have copied and tried to modify the existing sparklr2 sample from the spring-security-oauth2-javaconfig sample.

The last error I get is :"error":"invalid_client","error_description":"Bad client credentials when I run curl -v --data "grant_type=password&username=marissa&password=koala&client_id=tonr&secret=secret" -X POST localhost:8100/oauth/token.

I understand oauth2 from a beginner's perspective and the paucity of resources with regard to oauth2 with spring-boot and rest make it hard. Any suggestions?

If someone could provide a cookbook like approach to configure oauth2 authentication and authorization to protect a rest api call along with the relevant curl commands, that would be awesome.,

2

2 Answers

3
votes

Java config support for oauth2 is work in progress, but you might have more success with my fork. If I were you I'd stick to XML for the oauth2 bits for now. Here's a bootified sparklr2 with minimal XML. I haven't checked that it works recently but it shouldn't be in bad shape if you update the boot dependencies to 1.0.0.RC2.

Update: the @Configuration stuff has moved to the main OAuth2 repo, so the fork and its parent are basically redundant now (and will probably be removed soon).

Update: the bootified sample is now also using @Configuration.

0
votes

Yes. This is what I have done to get it to work that way. I believe it is the right solution (other than using client_credentials for grant_type, but I am not an expert:-) If there is a better solution that would be awesome. Thank you so much for taking the time to help me out.


import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.config.annotation.authentication.configurers.InMemoryClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.OAuth2ServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.OAuth2ServerConfigurer;
import org.springframework.security.oauth2.provider.token.InMemoryTokenStore;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends OAuth2ServerConfigurerAdapter {

    private final String applicationName = "restservice";

    @Value("${client_id}")
    private String client_id;

    @Value("${client_secret}")
    private String client_secret;

    @Value("${grant_type}")
    private String grant_type;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .requestMatchers()
            .and()
            .authorizeRequests()
                .antMatchers("/").permitAll()
                .anyRequest().authenticated()
                .and()
            .apply(new OAuth2ServerConfigurer())
            .tokenStore(new InMemoryTokenStore())
            .resourceId(applicationName);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .userDetailsService(new InMemoryUserDetailsManager(getUserDetails()))
            .and()
            .apply(new InMemoryClientDetailsServiceConfigurer())
                .withClient(client_id)
                .resourceIds(applicationName)
                .scopes("read", "write")
                .authorities("USER")
                .authorizedGrantTypes(grant_type)
                .secret(client_secret);
    }

    private static final Collection<UserDetails> getUserDetails() {
        List<UserDetails> userDetails = new ArrayList<UserDetails>();
        userDetails.add(new User("user", "password", AuthorityUtils.createAuthorityList(
                        "USER", "read", "write")));
        return userDetails;
    }

}