Spring OAuth2 server cannot refresh token with Resource owner credentials (password) grant flow












1














I have configured an OAuth2 authorisation server with spring security oauth, using jwt tokens:



@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

...
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
}

@Bean
public ApprovalStore approvalStore() {
return new JdbcApprovalStore(dataSource);
}

@Bean
public TokenStore tokenStore() {
var jwtTokenStore = new JwtTokenStore(tokenConverter());
jwtTokenStore.setApprovalStore(approvalStore());
return jwtTokenStore;
}

@Bean
public JwtAccessTokenConverter tokenConverter() {
var converter = new JwtAccessTokenConverter();
var keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource(jwtKeyStore), jwtKeyPass.toCharArray());
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwtkey"));
return converter;
}

}


There is a client that has password and refresh_token grants. I can get access and refresh tokens with the following request:



curl --request POST 
--url 'http://localhost:8080/oauth/token?grant_type=password&scope=read'
--header 'authorization: Basic <xxxxxxx>'
--header 'content-type: application/x-www-form-urlencoded'
--data 'username=xxxxxxx&password=xxxxxxx'


Response:



{
"access_token": "<long access token>",
"token_type": "bearer",
"refresh_token": "<long refresh token>",
"expires_in": 599,
"scope": "read",
"subject": "xxx",
"jti": "xxx"
}


However, when I try to refresh the token, I get an error Invalid refresh token. Further debugging into Spring codes I see that on the first request, it doesn't insert a row into oauth_approvals table. And on the second request (refreshing the token) it thinks that the user has not approved the scope (although I have autoapprove=true).



This is not the case with implicit or authorization_code grant flow: in those cases it does insert a row into oauth_approvals table, and the token is refreshed successfully.



Is this a bug in Spring OAuth or is there any workaround?










share|improve this question



























    1














    I have configured an OAuth2 authorisation server with spring security oauth, using jwt tokens:



    @Configuration
    @EnableAuthorizationServer
    public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    ...
    @Override
    public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
    clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
    }

    @Bean
    public ApprovalStore approvalStore() {
    return new JdbcApprovalStore(dataSource);
    }

    @Bean
    public TokenStore tokenStore() {
    var jwtTokenStore = new JwtTokenStore(tokenConverter());
    jwtTokenStore.setApprovalStore(approvalStore());
    return jwtTokenStore;
    }

    @Bean
    public JwtAccessTokenConverter tokenConverter() {
    var converter = new JwtAccessTokenConverter();
    var keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource(jwtKeyStore), jwtKeyPass.toCharArray());
    converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwtkey"));
    return converter;
    }

    }


    There is a client that has password and refresh_token grants. I can get access and refresh tokens with the following request:



    curl --request POST 
    --url 'http://localhost:8080/oauth/token?grant_type=password&scope=read'
    --header 'authorization: Basic <xxxxxxx>'
    --header 'content-type: application/x-www-form-urlencoded'
    --data 'username=xxxxxxx&password=xxxxxxx'


    Response:



    {
    "access_token": "<long access token>",
    "token_type": "bearer",
    "refresh_token": "<long refresh token>",
    "expires_in": 599,
    "scope": "read",
    "subject": "xxx",
    "jti": "xxx"
    }


    However, when I try to refresh the token, I get an error Invalid refresh token. Further debugging into Spring codes I see that on the first request, it doesn't insert a row into oauth_approvals table. And on the second request (refreshing the token) it thinks that the user has not approved the scope (although I have autoapprove=true).



    This is not the case with implicit or authorization_code grant flow: in those cases it does insert a row into oauth_approvals table, and the token is refreshed successfully.



    Is this a bug in Spring OAuth or is there any workaround?










    share|improve this question

























      1












      1








      1







      I have configured an OAuth2 authorisation server with spring security oauth, using jwt tokens:



      @Configuration
      @EnableAuthorizationServer
      public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

      ...
      @Override
      public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
      clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
      }

      @Bean
      public ApprovalStore approvalStore() {
      return new JdbcApprovalStore(dataSource);
      }

      @Bean
      public TokenStore tokenStore() {
      var jwtTokenStore = new JwtTokenStore(tokenConverter());
      jwtTokenStore.setApprovalStore(approvalStore());
      return jwtTokenStore;
      }

      @Bean
      public JwtAccessTokenConverter tokenConverter() {
      var converter = new JwtAccessTokenConverter();
      var keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource(jwtKeyStore), jwtKeyPass.toCharArray());
      converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwtkey"));
      return converter;
      }

      }


      There is a client that has password and refresh_token grants. I can get access and refresh tokens with the following request:



      curl --request POST 
      --url 'http://localhost:8080/oauth/token?grant_type=password&scope=read'
      --header 'authorization: Basic <xxxxxxx>'
      --header 'content-type: application/x-www-form-urlencoded'
      --data 'username=xxxxxxx&password=xxxxxxx'


      Response:



      {
      "access_token": "<long access token>",
      "token_type": "bearer",
      "refresh_token": "<long refresh token>",
      "expires_in": 599,
      "scope": "read",
      "subject": "xxx",
      "jti": "xxx"
      }


      However, when I try to refresh the token, I get an error Invalid refresh token. Further debugging into Spring codes I see that on the first request, it doesn't insert a row into oauth_approvals table. And on the second request (refreshing the token) it thinks that the user has not approved the scope (although I have autoapprove=true).



      This is not the case with implicit or authorization_code grant flow: in those cases it does insert a row into oauth_approvals table, and the token is refreshed successfully.



      Is this a bug in Spring OAuth or is there any workaround?










      share|improve this question













      I have configured an OAuth2 authorisation server with spring security oauth, using jwt tokens:



      @Configuration
      @EnableAuthorizationServer
      public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

      ...
      @Override
      public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
      clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
      }

      @Bean
      public ApprovalStore approvalStore() {
      return new JdbcApprovalStore(dataSource);
      }

      @Bean
      public TokenStore tokenStore() {
      var jwtTokenStore = new JwtTokenStore(tokenConverter());
      jwtTokenStore.setApprovalStore(approvalStore());
      return jwtTokenStore;
      }

      @Bean
      public JwtAccessTokenConverter tokenConverter() {
      var converter = new JwtAccessTokenConverter();
      var keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource(jwtKeyStore), jwtKeyPass.toCharArray());
      converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwtkey"));
      return converter;
      }

      }


      There is a client that has password and refresh_token grants. I can get access and refresh tokens with the following request:



      curl --request POST 
      --url 'http://localhost:8080/oauth/token?grant_type=password&scope=read'
      --header 'authorization: Basic <xxxxxxx>'
      --header 'content-type: application/x-www-form-urlencoded'
      --data 'username=xxxxxxx&password=xxxxxxx'


      Response:



      {
      "access_token": "<long access token>",
      "token_type": "bearer",
      "refresh_token": "<long refresh token>",
      "expires_in": 599,
      "scope": "read",
      "subject": "xxx",
      "jti": "xxx"
      }


      However, when I try to refresh the token, I get an error Invalid refresh token. Further debugging into Spring codes I see that on the first request, it doesn't insert a row into oauth_approvals table. And on the second request (refreshing the token) it thinks that the user has not approved the scope (although I have autoapprove=true).



      This is not the case with implicit or authorization_code grant flow: in those cases it does insert a row into oauth_approvals table, and the token is refreshed successfully.



      Is this a bug in Spring OAuth or is there any workaround?







      spring spring-security oauth-2.0 spring-security-oauth2 spring-oauth2






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Dec 28 '18 at 11:13









      ArchieArchie

      399112




      399112
























          1 Answer
          1






          active

          oldest

          votes


















          1














          After digging more into Spring's codes, I came to conclusion that this is indeed a bug there. So I extended JdbcApprovalStore and used that one instead. Here is pseudo-code



          public class JdbcApprovalStoreAutoApprove extends JdbcApprovalStore {
          ...
          @Override
          public List<Approval> getApprovals(String userName, String clientId) {
          if (client has auto approved scopes) {
          return those scopes;
          }
          return super.getApprovals(userName, clientId);
          }





          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53957622%2fspring-oauth2-server-cannot-refresh-token-with-resource-owner-credentials-passw%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            After digging more into Spring's codes, I came to conclusion that this is indeed a bug there. So I extended JdbcApprovalStore and used that one instead. Here is pseudo-code



            public class JdbcApprovalStoreAutoApprove extends JdbcApprovalStore {
            ...
            @Override
            public List<Approval> getApprovals(String userName, String clientId) {
            if (client has auto approved scopes) {
            return those scopes;
            }
            return super.getApprovals(userName, clientId);
            }





            share|improve this answer


























              1














              After digging more into Spring's codes, I came to conclusion that this is indeed a bug there. So I extended JdbcApprovalStore and used that one instead. Here is pseudo-code



              public class JdbcApprovalStoreAutoApprove extends JdbcApprovalStore {
              ...
              @Override
              public List<Approval> getApprovals(String userName, String clientId) {
              if (client has auto approved scopes) {
              return those scopes;
              }
              return super.getApprovals(userName, clientId);
              }





              share|improve this answer
























                1












                1








                1






                After digging more into Spring's codes, I came to conclusion that this is indeed a bug there. So I extended JdbcApprovalStore and used that one instead. Here is pseudo-code



                public class JdbcApprovalStoreAutoApprove extends JdbcApprovalStore {
                ...
                @Override
                public List<Approval> getApprovals(String userName, String clientId) {
                if (client has auto approved scopes) {
                return those scopes;
                }
                return super.getApprovals(userName, clientId);
                }





                share|improve this answer












                After digging more into Spring's codes, I came to conclusion that this is indeed a bug there. So I extended JdbcApprovalStore and used that one instead. Here is pseudo-code



                public class JdbcApprovalStoreAutoApprove extends JdbcApprovalStore {
                ...
                @Override
                public List<Approval> getApprovals(String userName, String clientId) {
                if (client has auto approved scopes) {
                return those scopes;
                }
                return super.getApprovals(userName, clientId);
                }






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 3 at 12:58









                ArchieArchie

                399112




                399112






























                    draft saved

                    draft discarded




















































                    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.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53957622%2fspring-oauth2-server-cannot-refresh-token-with-resource-owner-credentials-passw%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Monofisismo

                    Angular Downloading a file using contenturl with Basic Authentication

                    Olmecas