Skip authorization in Spring service for internal service to service calls












0















I am using Spring layered architecture, performing authorization of the requests in the service classes. One service could look like this:



@Service
public class SomeService {

public void findOne(Long id) {
assertPrivilege("READ");
// ...
}
}


Now, assertPrivilege() uses the SecurityContextHolder to obtain a list of GratedAuthority objects. Putting the authorization logic into services, the controllers don´t have to worry about that - also when calling multiple services from one controller.



The problem is that all other services cannot access that method now, unless authorized. However, there are some threads (schedulers for example) which exactly call that method at some point without having an Authentication object ready. In some cases, if it is the same thread, the SecurityContext will also return the current authentication.



Now, how to refactor this logic to achieve the other internal threads to call the method without authorization. Is a design change needed, possible a second wrapper class like SomeService (no authorization) and SomeClientService (with authorization)? Another possibility would be to access the repositories directly.










share|improve this question























  • would it be possible to create auth context from service where you want to call another service which requires authorization? I do this in my project as well!

    – Yogen Rai
    Nov 25 '18 at 23:23
















0















I am using Spring layered architecture, performing authorization of the requests in the service classes. One service could look like this:



@Service
public class SomeService {

public void findOne(Long id) {
assertPrivilege("READ");
// ...
}
}


Now, assertPrivilege() uses the SecurityContextHolder to obtain a list of GratedAuthority objects. Putting the authorization logic into services, the controllers don´t have to worry about that - also when calling multiple services from one controller.



The problem is that all other services cannot access that method now, unless authorized. However, there are some threads (schedulers for example) which exactly call that method at some point without having an Authentication object ready. In some cases, if it is the same thread, the SecurityContext will also return the current authentication.



Now, how to refactor this logic to achieve the other internal threads to call the method without authorization. Is a design change needed, possible a second wrapper class like SomeService (no authorization) and SomeClientService (with authorization)? Another possibility would be to access the repositories directly.










share|improve this question























  • would it be possible to create auth context from service where you want to call another service which requires authorization? I do this in my project as well!

    – Yogen Rai
    Nov 25 '18 at 23:23














0












0








0








I am using Spring layered architecture, performing authorization of the requests in the service classes. One service could look like this:



@Service
public class SomeService {

public void findOne(Long id) {
assertPrivilege("READ");
// ...
}
}


Now, assertPrivilege() uses the SecurityContextHolder to obtain a list of GratedAuthority objects. Putting the authorization logic into services, the controllers don´t have to worry about that - also when calling multiple services from one controller.



The problem is that all other services cannot access that method now, unless authorized. However, there are some threads (schedulers for example) which exactly call that method at some point without having an Authentication object ready. In some cases, if it is the same thread, the SecurityContext will also return the current authentication.



Now, how to refactor this logic to achieve the other internal threads to call the method without authorization. Is a design change needed, possible a second wrapper class like SomeService (no authorization) and SomeClientService (with authorization)? Another possibility would be to access the repositories directly.










share|improve this question














I am using Spring layered architecture, performing authorization of the requests in the service classes. One service could look like this:



@Service
public class SomeService {

public void findOne(Long id) {
assertPrivilege("READ");
// ...
}
}


Now, assertPrivilege() uses the SecurityContextHolder to obtain a list of GratedAuthority objects. Putting the authorization logic into services, the controllers don´t have to worry about that - also when calling multiple services from one controller.



The problem is that all other services cannot access that method now, unless authorized. However, there are some threads (schedulers for example) which exactly call that method at some point without having an Authentication object ready. In some cases, if it is the same thread, the SecurityContext will also return the current authentication.



Now, how to refactor this logic to achieve the other internal threads to call the method without authorization. Is a design change needed, possible a second wrapper class like SomeService (no authorization) and SomeClientService (with authorization)? Another possibility would be to access the repositories directly.







java spring spring-security






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 25 '18 at 23:14









GlainsGlains

985719




985719













  • would it be possible to create auth context from service where you want to call another service which requires authorization? I do this in my project as well!

    – Yogen Rai
    Nov 25 '18 at 23:23



















  • would it be possible to create auth context from service where you want to call another service which requires authorization? I do this in my project as well!

    – Yogen Rai
    Nov 25 '18 at 23:23

















would it be possible to create auth context from service where you want to call another service which requires authorization? I do this in my project as well!

– Yogen Rai
Nov 25 '18 at 23:23





would it be possible to create auth context from service where you want to call another service which requires authorization? I do this in my project as well!

– Yogen Rai
Nov 25 '18 at 23:23












2 Answers
2






active

oldest

votes


















1














It's better use @PreAuthorize("hasRole('ROLE_VIEWER') or hasRole('ROLE_EDITOR') or #id == authentication.principal.username") instead of method, see tutorial, there are many of them.



Generally, your business logic should not be mixed with security framework - it's why there are @PreAuthorize and @PostAuthorize - developer should be able define user access independently from business logic - it's two different requirements.



There are no easy way to disable spring security for one user (inner call, external app etc.), also it's not recommended (bugs etc.), you can create special role for external app or use Concurrency Support to perform inner call in behalf of user.






share|improve this answer































    0














    The proxy service approach seems to be the easiest thing to do, as you don't need to move authorization logic out of this layer. Managing authorization as an aspect would be the key for that solution. Otherwise, you can always manage these checks directly in the controllers, so every endpoint handles it according to the type of client it was designed to be used by.






    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%2f53472971%2fskip-authorization-in-spring-service-for-internal-service-to-service-calls%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      It's better use @PreAuthorize("hasRole('ROLE_VIEWER') or hasRole('ROLE_EDITOR') or #id == authentication.principal.username") instead of method, see tutorial, there are many of them.



      Generally, your business logic should not be mixed with security framework - it's why there are @PreAuthorize and @PostAuthorize - developer should be able define user access independently from business logic - it's two different requirements.



      There are no easy way to disable spring security for one user (inner call, external app etc.), also it's not recommended (bugs etc.), you can create special role for external app or use Concurrency Support to perform inner call in behalf of user.






      share|improve this answer




























        1














        It's better use @PreAuthorize("hasRole('ROLE_VIEWER') or hasRole('ROLE_EDITOR') or #id == authentication.principal.username") instead of method, see tutorial, there are many of them.



        Generally, your business logic should not be mixed with security framework - it's why there are @PreAuthorize and @PostAuthorize - developer should be able define user access independently from business logic - it's two different requirements.



        There are no easy way to disable spring security for one user (inner call, external app etc.), also it's not recommended (bugs etc.), you can create special role for external app or use Concurrency Support to perform inner call in behalf of user.






        share|improve this answer


























          1












          1








          1







          It's better use @PreAuthorize("hasRole('ROLE_VIEWER') or hasRole('ROLE_EDITOR') or #id == authentication.principal.username") instead of method, see tutorial, there are many of them.



          Generally, your business logic should not be mixed with security framework - it's why there are @PreAuthorize and @PostAuthorize - developer should be able define user access independently from business logic - it's two different requirements.



          There are no easy way to disable spring security for one user (inner call, external app etc.), also it's not recommended (bugs etc.), you can create special role for external app or use Concurrency Support to perform inner call in behalf of user.






          share|improve this answer













          It's better use @PreAuthorize("hasRole('ROLE_VIEWER') or hasRole('ROLE_EDITOR') or #id == authentication.principal.username") instead of method, see tutorial, there are many of them.



          Generally, your business logic should not be mixed with security framework - it's why there are @PreAuthorize and @PostAuthorize - developer should be able define user access independently from business logic - it's two different requirements.



          There are no easy way to disable spring security for one user (inner call, external app etc.), also it's not recommended (bugs etc.), you can create special role for external app or use Concurrency Support to perform inner call in behalf of user.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 26 '18 at 9:58









          Andrew SashaAndrew Sasha

          581315




          581315

























              0














              The proxy service approach seems to be the easiest thing to do, as you don't need to move authorization logic out of this layer. Managing authorization as an aspect would be the key for that solution. Otherwise, you can always manage these checks directly in the controllers, so every endpoint handles it according to the type of client it was designed to be used by.






              share|improve this answer




























                0














                The proxy service approach seems to be the easiest thing to do, as you don't need to move authorization logic out of this layer. Managing authorization as an aspect would be the key for that solution. Otherwise, you can always manage these checks directly in the controllers, so every endpoint handles it according to the type of client it was designed to be used by.






                share|improve this answer


























                  0












                  0








                  0







                  The proxy service approach seems to be the easiest thing to do, as you don't need to move authorization logic out of this layer. Managing authorization as an aspect would be the key for that solution. Otherwise, you can always manage these checks directly in the controllers, so every endpoint handles it according to the type of client it was designed to be used by.






                  share|improve this answer













                  The proxy service approach seems to be the easiest thing to do, as you don't need to move authorization logic out of this layer. Managing authorization as an aspect would be the key for that solution. Otherwise, you can always manage these checks directly in the controllers, so every endpoint handles it according to the type of client it was designed to be used by.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 25 '18 at 23:23









                  Ezequiel PalumboEzequiel Palumbo

                  12




                  12






























                      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%2f53472971%2fskip-authorization-in-spring-service-for-internal-service-to-service-calls%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

                      Create new schema in PostgreSQL using DBeaver

                      Deepest pit of an array with Javascript: test on Codility

                      Costa Masnaga