相关文章推荐
买醉的香蕉  ·  Android中Surface+MediaP ...·  12 月前    · 
道上混的豌豆  ·  在C++/Python/Java/Objec ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have successfully create a web-service using the spring-boot framework. Now I want to secure my web-service with OAuth2 (using spring) and have a few questions regarding that:

According to my research, spring provides some kind of default-url to request an access token ( baseURL/oauth/token ). I have tested the URL using postman, and a valid access token was returned (using client_credentials grant type), but no refresh token. However this method does not work with grant_type=password and results in the following error response:

{"error":"invalid_grant","error_description":"Bad credentials"}

My spring application logs InvalidGrantException .

The curl I used to test grant_type=password is the following:

curl -v -X POST -H "Content-Type: application/json" -H "Authorization: Basic base64encodedclientidandsecret" 'http://localhost:8888/oauth/token?grant_type=password&username=user&password=1234'

I did not test using postman because it does not support grant_type=password.

How can I get spring to return both accessToken and refreshToken using grant_type=password?

Is there anything wrong with my configuration?

My spring application (configuration) looks as follows:

@Configuration
@ComponentScan
@EnableAutoConfiguration(exclude = { MongoAutoConfiguration.class, MongoDataAutoConfiguration.class })
@SpringBootApplication
public class CsWebServerApplication {
    public static final String RESOURCE_ID = "myresource";
    public static final String CLIENT_ID = "myapplication";
    public static final String CLIENT_SECRET = "application_secret";
    public static void main(String[] args) {
        SpringApplication.run(MyWebServerApplication.class, args);
    @Configuration
    @EnableAuthorizationServer
    protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
        @Inject
        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(CLIENT_ID)
            .authorizedGrantTypes("client_credentials", "password", "refresh_token")
            .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
            .scopes("read", "write", "trust")
            .secret(CLIENT_SECRET);
        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
            super.configure(oauthServer);
    @Configuration
    @EnableResourceServer
    protected static class ResourceConfig extends ResourceServerConfigurerAdapter {
        @Override 
        public void configure(HttpSecurity http) throws Exception {
            http.requestMatchers().antMatchers("/*", "/admin/beans").and().authorizeRequests().anyRequest()
                .access("#oauth2.hasScope('read')"); 
        @Override
        public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
            resources.resourceId(RESOURCE_ID);
    @Configuration
    @EnableWebSecurity
    protected static class WebConfigurer extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            super.configure(http);
        @Override
        public void configure(WebSecurity webSecurity) throws Exception {
            webSecurity.ignoring()
                    // All of Spring Security will ignore the requests
                    .antMatchers("/accessibleservices/**")

"4.3.2. Access Token Request" in RFC 6749 (The OAuth 2.0 Authorization Framework) says as follows.

The client makes a request to the token endpoint by adding the following parameters using the "application/x-www-form-urlencoded" format per Appendix B with a character encoding of UTF-8 in the HTTP request entity-body:

So, -H "Content-Type: application/json" is wrong. In addition, your curl command line is wrong. Use -d option to specify a form parameter for POST.

About supporting of refresh tokens. By default spring oauth using DefaultTokenServices class and support of refresh tokens disabled by default. You should override its initialization in your OAuth2Config.class.

Example:

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setSupportRefreshToken(true);
        return tokenServices;

not set TokenStore

OAuth2RefreshToken refreshToken = tokenStore.readRefreshToken(refreshTokenValue);
    if (refreshToken == null) {
        throw new InvalidGrantException("Invalid refresh token: " + refreshTokenValue);
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

add config

@Configuration
public class RedisTokenStoreConfig {
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;
    @Bean
    public TokenStore redisTokenStore (){
        return new RedisTokenStore(redisConnectionFactory);

in your OAuth2Config

@Autowired
@Qualifier("redisTokenStore")
private TokenStore tokenStore;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
    endpoints.authenticationManager(authenticationManager)
            .userDetailsService(userService)
            .tokenStore(tokenStore);//set tokenStore
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.