Spring Security, Method Security annotation (@Secured ) is not working (java config)












13















I am trying to set up a method security annotation using @Secured("ADMIN") (without any XML, only java config, Spring Boot). But access via roles does not work.



Security Config:



@Configuration
@EnableWebSecurity
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{

.....

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/**").fullyAuthenticated().and()
.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}

.....

}


I want restrict access to the method of the controller:



@RestController
@RequestMapping("/api/groups")
public class GroupController {

@Autowired
private GroupService groupService;

@Secured("ADMIN")
@RequestMapping
public List<Group> list() {
return groupService.findAll();
}

}


Restrict access by the url is working, with:



.antMatchers("/api/**").hasAuthority("ADMIN")


Maybe I forgot to specify that I want restrict by roles?



UPD:
By the rules, At what layer must be @PreAuthorize("hasRole('ADMIN')") in Controller layer or in Service layer?










share|improve this question

























  • What does not work ? Is the browsers not trying to authenticate you ? Does it ignore the credentials you provide ? By the way: you should also post where you map your user to the admin group, perhaps this is the problematic area.

    – Marged
    Jul 2 '15 at 14:10






  • 1





    The authentication working correctly, but any user with any role have access to "/api/groups"

    – silverhawk
    Jul 2 '15 at 14:13






  • 1





    Where are you setting the ROLE 'ADMIN', can you show me that??

    – We are Borg
    Jul 2 '15 at 14:16











  • Despite the fact that role is defined correctly: org.springframework.security.authentication.UsernamePasswordAuthenticationToken: Principal: SecurityUser; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ADMIN

    – silverhawk
    Jul 2 '15 at 14:17








  • 1





    here you see that authority was actually ADMIN and not ROLE_ADMIN. Because RoleVoter checks authorities with starting with ROLE_ it can't find your authority (which is ADMIN) and thus abstains

    – pls
    Jul 2 '18 at 11:53
















13















I am trying to set up a method security annotation using @Secured("ADMIN") (without any XML, only java config, Spring Boot). But access via roles does not work.



Security Config:



@Configuration
@EnableWebSecurity
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{

.....

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/**").fullyAuthenticated().and()
.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}

.....

}


I want restrict access to the method of the controller:



@RestController
@RequestMapping("/api/groups")
public class GroupController {

@Autowired
private GroupService groupService;

@Secured("ADMIN")
@RequestMapping
public List<Group> list() {
return groupService.findAll();
}

}


Restrict access by the url is working, with:



.antMatchers("/api/**").hasAuthority("ADMIN")


Maybe I forgot to specify that I want restrict by roles?



UPD:
By the rules, At what layer must be @PreAuthorize("hasRole('ADMIN')") in Controller layer or in Service layer?










share|improve this question

























  • What does not work ? Is the browsers not trying to authenticate you ? Does it ignore the credentials you provide ? By the way: you should also post where you map your user to the admin group, perhaps this is the problematic area.

    – Marged
    Jul 2 '15 at 14:10






  • 1





    The authentication working correctly, but any user with any role have access to "/api/groups"

    – silverhawk
    Jul 2 '15 at 14:13






  • 1





    Where are you setting the ROLE 'ADMIN', can you show me that??

    – We are Borg
    Jul 2 '15 at 14:16











  • Despite the fact that role is defined correctly: org.springframework.security.authentication.UsernamePasswordAuthenticationToken: Principal: SecurityUser; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ADMIN

    – silverhawk
    Jul 2 '15 at 14:17








  • 1





    here you see that authority was actually ADMIN and not ROLE_ADMIN. Because RoleVoter checks authorities with starting with ROLE_ it can't find your authority (which is ADMIN) and thus abstains

    – pls
    Jul 2 '18 at 11:53














13












13








13


5






I am trying to set up a method security annotation using @Secured("ADMIN") (without any XML, only java config, Spring Boot). But access via roles does not work.



Security Config:



@Configuration
@EnableWebSecurity
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{

.....

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/**").fullyAuthenticated().and()
.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}

.....

}


I want restrict access to the method of the controller:



@RestController
@RequestMapping("/api/groups")
public class GroupController {

@Autowired
private GroupService groupService;

@Secured("ADMIN")
@RequestMapping
public List<Group> list() {
return groupService.findAll();
}

}


Restrict access by the url is working, with:



.antMatchers("/api/**").hasAuthority("ADMIN")


Maybe I forgot to specify that I want restrict by roles?



UPD:
By the rules, At what layer must be @PreAuthorize("hasRole('ADMIN')") in Controller layer or in Service layer?










share|improve this question
















I am trying to set up a method security annotation using @Secured("ADMIN") (without any XML, only java config, Spring Boot). But access via roles does not work.



Security Config:



@Configuration
@EnableWebSecurity
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{

.....

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/**").fullyAuthenticated().and()
.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}

.....

}


I want restrict access to the method of the controller:



@RestController
@RequestMapping("/api/groups")
public class GroupController {

@Autowired
private GroupService groupService;

@Secured("ADMIN")
@RequestMapping
public List<Group> list() {
return groupService.findAll();
}

}


Restrict access by the url is working, with:



.antMatchers("/api/**").hasAuthority("ADMIN")


Maybe I forgot to specify that I want restrict by roles?



UPD:
By the rules, At what layer must be @PreAuthorize("hasRole('ADMIN')") in Controller layer or in Service layer?







java spring security spring-security spring-boot






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jul 7 '15 at 9:40







silverhawk

















asked Jul 2 '15 at 14:06









silverhawksilverhawk

1091111




1091111













  • What does not work ? Is the browsers not trying to authenticate you ? Does it ignore the credentials you provide ? By the way: you should also post where you map your user to the admin group, perhaps this is the problematic area.

    – Marged
    Jul 2 '15 at 14:10






  • 1





    The authentication working correctly, but any user with any role have access to "/api/groups"

    – silverhawk
    Jul 2 '15 at 14:13






  • 1





    Where are you setting the ROLE 'ADMIN', can you show me that??

    – We are Borg
    Jul 2 '15 at 14:16











  • Despite the fact that role is defined correctly: org.springframework.security.authentication.UsernamePasswordAuthenticationToken: Principal: SecurityUser; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ADMIN

    – silverhawk
    Jul 2 '15 at 14:17








  • 1





    here you see that authority was actually ADMIN and not ROLE_ADMIN. Because RoleVoter checks authorities with starting with ROLE_ it can't find your authority (which is ADMIN) and thus abstains

    – pls
    Jul 2 '18 at 11:53



















  • What does not work ? Is the browsers not trying to authenticate you ? Does it ignore the credentials you provide ? By the way: you should also post where you map your user to the admin group, perhaps this is the problematic area.

    – Marged
    Jul 2 '15 at 14:10






  • 1





    The authentication working correctly, but any user with any role have access to "/api/groups"

    – silverhawk
    Jul 2 '15 at 14:13






  • 1





    Where are you setting the ROLE 'ADMIN', can you show me that??

    – We are Borg
    Jul 2 '15 at 14:16











  • Despite the fact that role is defined correctly: org.springframework.security.authentication.UsernamePasswordAuthenticationToken: Principal: SecurityUser; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ADMIN

    – silverhawk
    Jul 2 '15 at 14:17








  • 1





    here you see that authority was actually ADMIN and not ROLE_ADMIN. Because RoleVoter checks authorities with starting with ROLE_ it can't find your authority (which is ADMIN) and thus abstains

    – pls
    Jul 2 '18 at 11:53

















What does not work ? Is the browsers not trying to authenticate you ? Does it ignore the credentials you provide ? By the way: you should also post where you map your user to the admin group, perhaps this is the problematic area.

– Marged
Jul 2 '15 at 14:10





What does not work ? Is the browsers not trying to authenticate you ? Does it ignore the credentials you provide ? By the way: you should also post where you map your user to the admin group, perhaps this is the problematic area.

– Marged
Jul 2 '15 at 14:10




1




1





The authentication working correctly, but any user with any role have access to "/api/groups"

– silverhawk
Jul 2 '15 at 14:13





The authentication working correctly, but any user with any role have access to "/api/groups"

– silverhawk
Jul 2 '15 at 14:13




1




1





Where are you setting the ROLE 'ADMIN', can you show me that??

– We are Borg
Jul 2 '15 at 14:16





Where are you setting the ROLE 'ADMIN', can you show me that??

– We are Borg
Jul 2 '15 at 14:16













Despite the fact that role is defined correctly: org.springframework.security.authentication.UsernamePasswordAuthenticationToken: Principal: SecurityUser; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ADMIN

– silverhawk
Jul 2 '15 at 14:17







Despite the fact that role is defined correctly: org.springframework.security.authentication.UsernamePasswordAuthenticationToken: Principal: SecurityUser; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ADMIN

– silverhawk
Jul 2 '15 at 14:17






1




1





here you see that authority was actually ADMIN and not ROLE_ADMIN. Because RoleVoter checks authorities with starting with ROLE_ it can't find your authority (which is ADMIN) and thus abstains

– pls
Jul 2 '18 at 11:53





here you see that authority was actually ADMIN and not ROLE_ADMIN. Because RoleVoter checks authorities with starting with ROLE_ it can't find your authority (which is ADMIN) and thus abstains

– pls
Jul 2 '18 at 11:53












7 Answers
7






active

oldest

votes


















26














Kindly add this



@EnableGlobalMethodSecurity(securedEnabled = true)


This element is used to enable annotation-based security in your application (by setting the appropriate attributes on the element), and also to group together security pointcut declarations which will be applied across your entire application context specifically for @Secured.
Hence your code should look like this



@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{..





share|improve this answer


























  • made the edit for specifically securedEnabled = true

    – Mudassar
    Jul 2 '15 at 14:37











  • i am try this, but this does not work correctly, ie spring response "Access denied"

    – silverhawk
    Jul 2 '15 at 15:25











  • Let's do some analysis, any surviving reason of adding @RequestMapping below Secured("ADMIN")

    – Mudassar
    Jul 2 '15 at 15:37











  • Any progress? Did you try removing that @RequestMapping below @Secured("ADMIN")

    – Mudassar
    Jul 2 '15 at 16:54











  • Kindly let me know if you made any progress or if the solution is fixed with the help of the proposed solution then kindly close the question by accepting the answer

    – Mudassar
    Jul 3 '15 at 14:35



















12














There may be many reasons for which method security on a controller does not work.



First because it is never cited as example in Spring Security manual ... joking but it may be tricky to take Spring tools where they do not want to go.



More seriously, you should enable method security as already said by @Mudassar. The manual says :



We can enable annotation-based security using the @EnableGlobalMethodSecurity annotation on any @Configuration instance. For example, the following would enable Spring Security’s @Secured annotation.



@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig {
// ...
}


Note that Mudassar's answer is correct till here.



But method security is based on AOP, which by default uses JDK proxying on interfaces. That's the reason why all examples applies method security on the service layer, because the service classes are normally injected in controllers as interfaces.



You can of course use it on controller layer, but :




  • either all your controllers implement interfaces for you all @Secured annotated methods

  • or you must switch to class proxying


The rule that I try to follow is :




  • if I want to secure an URL, I stick to HTTPSecurity

  • if I need to allow finer grained access, I add security at service layer






share|improve this answer































    8














    I know this thread is quite old and my answer alludes to portions of the answers by various people in this thread; but here is a list combined list of pitfalls and answers:




    1. When using @Secured, and the role name is (e.g.) ADMIN; this means an annotation of @Secured("ROLE_ADMIN").

    2. WebSecurityConfigurerAdapter must have @EnableGlobalMethodSecurity(securedEnabled = true)

    3. As with most Spring related proxies, make sure that the class and the secured methods are not in any way final. For Kotlin this means "open" every method as well as the class.

    4. When the class and its methods are virtual ("open"), then there is no implied need for an interface.


    Here is part of a working Kotlin example:



    @RestController
    @RequestMapping("api/v1")

    open class DiagnosticsController {
    @Autowired
    lateinit var systemDao : SystemDao

    @RequestMapping("ping", method = arrayOf(RequestMethod.GET))
    @Secured("ROLE_ADMIN")
    open fun ping(request : HttpServletRequest, response: HttpServletResponse) : String { ...
    }


    and



    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(securedEnabled = true)
    open class WebSecurityConfig : WebSecurityConfigurerAdapter() {


    Regards






    share|improve this answer

































      1














      This issue was solved.



      I add @EnableGlobalMethodSecurity(prePostEnabled = true)



      @Configuration
      @EnableWebSecurity
      @EnableGlobalMethodSecurity(prePostEnabled = true)
      public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{
      }


      And in controller i changed @Secured("ADMIN") to @PreAuthorize("hasRole('ADMIN')")






      share|improve this answer































        1














        You need to use @secured(ROLE_ADMIN) instead of @secured(ADMIN). You are required to write "ROLE_" infront of your role name. Please find the example mentioned below which is making sure only a user with Admin role can access list() method.



        @RestController
        @RequestMapping("/api/groups")
        public class GroupController {

        @Autowired
        private GroupService groupService;

        @Secured("ROLE_ADMIN")
        @RequestMapping
        public List<Group> list() {
        return groupService.findAll();
        }

        }





        share|improve this answer































          0














          Maybe you should register your AppSecurityConfiguration to same context as WebMvcConfig (that extends WebMvcConfigurerAdapter).



          AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();      
          mvcContext.register(WebMvcConfig.class, SecurityConfig.class);





          share|improve this answer































            0














            I want to share my decision, may be it will be helpful.



            Used spring mvc + spring security, version 4.2.9.RELEASE



            For example, i have a Service with method annotated @Secured



            @Secured("ACTION_USER_LIST_VIEW")
            List<User> getUsersList();


            But, it didn't work, because GlobalMethodSecurityConfiguration has inside method.



            protected AccessDecisionManager accessDecisionManager()


            in which initialized the new RoleVoter() with default rolePrefix = "ROLE_"; (this makes it impossible to use beans to set your rolePrefix) that give to us not working annotations, because RoleVoter expects annotation value which starts with 'ROLE_'



            For resolving this problem i override GlobalMethodSecurityConfiguration like this



            @Configuration
            @EnableGlobalMethodSecurity(securedEnabled = true)
            public class AppMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
            @Override
            protected AccessDecisionManager accessDecisionManager() {
            List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList<>();
            ExpressionBasedPreInvocationAdvice expressionAdvice = new ExpressionBasedPreInvocationAdvice();
            expressionAdvice.setExpressionHandler(getExpressionHandler());
            decisionVoters.add(getRoleVoter());
            decisionVoters.add(new AuthenticatedVoter());
            return new AffirmativeBased(decisionVoters);
            }

            private RoleVoter getRoleVoter() {
            RoleVoter e = new RoleVoter();
            e.setRolePrefix("");
            return e;
            }
            }





            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%2f31186826%2fspring-security-method-security-annotation-secured-is-not-working-java-con%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              7 Answers
              7






              active

              oldest

              votes








              7 Answers
              7






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              26














              Kindly add this



              @EnableGlobalMethodSecurity(securedEnabled = true)


              This element is used to enable annotation-based security in your application (by setting the appropriate attributes on the element), and also to group together security pointcut declarations which will be applied across your entire application context specifically for @Secured.
              Hence your code should look like this



              @Configuration
              @EnableWebSecurity
              @EnableGlobalMethodSecurity(securedEnabled = true)
              public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{..





              share|improve this answer


























              • made the edit for specifically securedEnabled = true

                – Mudassar
                Jul 2 '15 at 14:37











              • i am try this, but this does not work correctly, ie spring response "Access denied"

                – silverhawk
                Jul 2 '15 at 15:25











              • Let's do some analysis, any surviving reason of adding @RequestMapping below Secured("ADMIN")

                – Mudassar
                Jul 2 '15 at 15:37











              • Any progress? Did you try removing that @RequestMapping below @Secured("ADMIN")

                – Mudassar
                Jul 2 '15 at 16:54











              • Kindly let me know if you made any progress or if the solution is fixed with the help of the proposed solution then kindly close the question by accepting the answer

                – Mudassar
                Jul 3 '15 at 14:35
















              26














              Kindly add this



              @EnableGlobalMethodSecurity(securedEnabled = true)


              This element is used to enable annotation-based security in your application (by setting the appropriate attributes on the element), and also to group together security pointcut declarations which will be applied across your entire application context specifically for @Secured.
              Hence your code should look like this



              @Configuration
              @EnableWebSecurity
              @EnableGlobalMethodSecurity(securedEnabled = true)
              public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{..





              share|improve this answer


























              • made the edit for specifically securedEnabled = true

                – Mudassar
                Jul 2 '15 at 14:37











              • i am try this, but this does not work correctly, ie spring response "Access denied"

                – silverhawk
                Jul 2 '15 at 15:25











              • Let's do some analysis, any surviving reason of adding @RequestMapping below Secured("ADMIN")

                – Mudassar
                Jul 2 '15 at 15:37











              • Any progress? Did you try removing that @RequestMapping below @Secured("ADMIN")

                – Mudassar
                Jul 2 '15 at 16:54











              • Kindly let me know if you made any progress or if the solution is fixed with the help of the proposed solution then kindly close the question by accepting the answer

                – Mudassar
                Jul 3 '15 at 14:35














              26












              26








              26







              Kindly add this



              @EnableGlobalMethodSecurity(securedEnabled = true)


              This element is used to enable annotation-based security in your application (by setting the appropriate attributes on the element), and also to group together security pointcut declarations which will be applied across your entire application context specifically for @Secured.
              Hence your code should look like this



              @Configuration
              @EnableWebSecurity
              @EnableGlobalMethodSecurity(securedEnabled = true)
              public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{..





              share|improve this answer















              Kindly add this



              @EnableGlobalMethodSecurity(securedEnabled = true)


              This element is used to enable annotation-based security in your application (by setting the appropriate attributes on the element), and also to group together security pointcut declarations which will be applied across your entire application context specifically for @Secured.
              Hence your code should look like this



              @Configuration
              @EnableWebSecurity
              @EnableGlobalMethodSecurity(securedEnabled = true)
              public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{..






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Oct 19 '17 at 4:12

























              answered Jul 2 '15 at 14:31









              MudassarMudassar

              1,967917




              1,967917













              • made the edit for specifically securedEnabled = true

                – Mudassar
                Jul 2 '15 at 14:37











              • i am try this, but this does not work correctly, ie spring response "Access denied"

                – silverhawk
                Jul 2 '15 at 15:25











              • Let's do some analysis, any surviving reason of adding @RequestMapping below Secured("ADMIN")

                – Mudassar
                Jul 2 '15 at 15:37











              • Any progress? Did you try removing that @RequestMapping below @Secured("ADMIN")

                – Mudassar
                Jul 2 '15 at 16:54











              • Kindly let me know if you made any progress or if the solution is fixed with the help of the proposed solution then kindly close the question by accepting the answer

                – Mudassar
                Jul 3 '15 at 14:35



















              • made the edit for specifically securedEnabled = true

                – Mudassar
                Jul 2 '15 at 14:37











              • i am try this, but this does not work correctly, ie spring response "Access denied"

                – silverhawk
                Jul 2 '15 at 15:25











              • Let's do some analysis, any surviving reason of adding @RequestMapping below Secured("ADMIN")

                – Mudassar
                Jul 2 '15 at 15:37











              • Any progress? Did you try removing that @RequestMapping below @Secured("ADMIN")

                – Mudassar
                Jul 2 '15 at 16:54











              • Kindly let me know if you made any progress or if the solution is fixed with the help of the proposed solution then kindly close the question by accepting the answer

                – Mudassar
                Jul 3 '15 at 14:35

















              made the edit for specifically securedEnabled = true

              – Mudassar
              Jul 2 '15 at 14:37





              made the edit for specifically securedEnabled = true

              – Mudassar
              Jul 2 '15 at 14:37













              i am try this, but this does not work correctly, ie spring response "Access denied"

              – silverhawk
              Jul 2 '15 at 15:25





              i am try this, but this does not work correctly, ie spring response "Access denied"

              – silverhawk
              Jul 2 '15 at 15:25













              Let's do some analysis, any surviving reason of adding @RequestMapping below Secured("ADMIN")

              – Mudassar
              Jul 2 '15 at 15:37





              Let's do some analysis, any surviving reason of adding @RequestMapping below Secured("ADMIN")

              – Mudassar
              Jul 2 '15 at 15:37













              Any progress? Did you try removing that @RequestMapping below @Secured("ADMIN")

              – Mudassar
              Jul 2 '15 at 16:54





              Any progress? Did you try removing that @RequestMapping below @Secured("ADMIN")

              – Mudassar
              Jul 2 '15 at 16:54













              Kindly let me know if you made any progress or if the solution is fixed with the help of the proposed solution then kindly close the question by accepting the answer

              – Mudassar
              Jul 3 '15 at 14:35





              Kindly let me know if you made any progress or if the solution is fixed with the help of the proposed solution then kindly close the question by accepting the answer

              – Mudassar
              Jul 3 '15 at 14:35













              12














              There may be many reasons for which method security on a controller does not work.



              First because it is never cited as example in Spring Security manual ... joking but it may be tricky to take Spring tools where they do not want to go.



              More seriously, you should enable method security as already said by @Mudassar. The manual says :



              We can enable annotation-based security using the @EnableGlobalMethodSecurity annotation on any @Configuration instance. For example, the following would enable Spring Security’s @Secured annotation.



              @Configuration
              @EnableGlobalMethodSecurity(securedEnabled = true)
              public class MethodSecurityConfig {
              // ...
              }


              Note that Mudassar's answer is correct till here.



              But method security is based on AOP, which by default uses JDK proxying on interfaces. That's the reason why all examples applies method security on the service layer, because the service classes are normally injected in controllers as interfaces.



              You can of course use it on controller layer, but :




              • either all your controllers implement interfaces for you all @Secured annotated methods

              • or you must switch to class proxying


              The rule that I try to follow is :




              • if I want to secure an URL, I stick to HTTPSecurity

              • if I need to allow finer grained access, I add security at service layer






              share|improve this answer




























                12














                There may be many reasons for which method security on a controller does not work.



                First because it is never cited as example in Spring Security manual ... joking but it may be tricky to take Spring tools where they do not want to go.



                More seriously, you should enable method security as already said by @Mudassar. The manual says :



                We can enable annotation-based security using the @EnableGlobalMethodSecurity annotation on any @Configuration instance. For example, the following would enable Spring Security’s @Secured annotation.



                @Configuration
                @EnableGlobalMethodSecurity(securedEnabled = true)
                public class MethodSecurityConfig {
                // ...
                }


                Note that Mudassar's answer is correct till here.



                But method security is based on AOP, which by default uses JDK proxying on interfaces. That's the reason why all examples applies method security on the service layer, because the service classes are normally injected in controllers as interfaces.



                You can of course use it on controller layer, but :




                • either all your controllers implement interfaces for you all @Secured annotated methods

                • or you must switch to class proxying


                The rule that I try to follow is :




                • if I want to secure an URL, I stick to HTTPSecurity

                • if I need to allow finer grained access, I add security at service layer






                share|improve this answer


























                  12












                  12








                  12







                  There may be many reasons for which method security on a controller does not work.



                  First because it is never cited as example in Spring Security manual ... joking but it may be tricky to take Spring tools where they do not want to go.



                  More seriously, you should enable method security as already said by @Mudassar. The manual says :



                  We can enable annotation-based security using the @EnableGlobalMethodSecurity annotation on any @Configuration instance. For example, the following would enable Spring Security’s @Secured annotation.



                  @Configuration
                  @EnableGlobalMethodSecurity(securedEnabled = true)
                  public class MethodSecurityConfig {
                  // ...
                  }


                  Note that Mudassar's answer is correct till here.



                  But method security is based on AOP, which by default uses JDK proxying on interfaces. That's the reason why all examples applies method security on the service layer, because the service classes are normally injected in controllers as interfaces.



                  You can of course use it on controller layer, but :




                  • either all your controllers implement interfaces for you all @Secured annotated methods

                  • or you must switch to class proxying


                  The rule that I try to follow is :




                  • if I want to secure an URL, I stick to HTTPSecurity

                  • if I need to allow finer grained access, I add security at service layer






                  share|improve this answer













                  There may be many reasons for which method security on a controller does not work.



                  First because it is never cited as example in Spring Security manual ... joking but it may be tricky to take Spring tools where they do not want to go.



                  More seriously, you should enable method security as already said by @Mudassar. The manual says :



                  We can enable annotation-based security using the @EnableGlobalMethodSecurity annotation on any @Configuration instance. For example, the following would enable Spring Security’s @Secured annotation.



                  @Configuration
                  @EnableGlobalMethodSecurity(securedEnabled = true)
                  public class MethodSecurityConfig {
                  // ...
                  }


                  Note that Mudassar's answer is correct till here.



                  But method security is based on AOP, which by default uses JDK proxying on interfaces. That's the reason why all examples applies method security on the service layer, because the service classes are normally injected in controllers as interfaces.



                  You can of course use it on controller layer, but :




                  • either all your controllers implement interfaces for you all @Secured annotated methods

                  • or you must switch to class proxying


                  The rule that I try to follow is :




                  • if I want to secure an URL, I stick to HTTPSecurity

                  • if I need to allow finer grained access, I add security at service layer







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jul 2 '15 at 14:49









                  Serge BallestaSerge Ballesta

                  80.8k961133




                  80.8k961133























                      8














                      I know this thread is quite old and my answer alludes to portions of the answers by various people in this thread; but here is a list combined list of pitfalls and answers:




                      1. When using @Secured, and the role name is (e.g.) ADMIN; this means an annotation of @Secured("ROLE_ADMIN").

                      2. WebSecurityConfigurerAdapter must have @EnableGlobalMethodSecurity(securedEnabled = true)

                      3. As with most Spring related proxies, make sure that the class and the secured methods are not in any way final. For Kotlin this means "open" every method as well as the class.

                      4. When the class and its methods are virtual ("open"), then there is no implied need for an interface.


                      Here is part of a working Kotlin example:



                      @RestController
                      @RequestMapping("api/v1")

                      open class DiagnosticsController {
                      @Autowired
                      lateinit var systemDao : SystemDao

                      @RequestMapping("ping", method = arrayOf(RequestMethod.GET))
                      @Secured("ROLE_ADMIN")
                      open fun ping(request : HttpServletRequest, response: HttpServletResponse) : String { ...
                      }


                      and



                      @Configuration
                      @EnableWebSecurity
                      @EnableGlobalMethodSecurity(securedEnabled = true)
                      open class WebSecurityConfig : WebSecurityConfigurerAdapter() {


                      Regards






                      share|improve this answer






























                        8














                        I know this thread is quite old and my answer alludes to portions of the answers by various people in this thread; but here is a list combined list of pitfalls and answers:




                        1. When using @Secured, and the role name is (e.g.) ADMIN; this means an annotation of @Secured("ROLE_ADMIN").

                        2. WebSecurityConfigurerAdapter must have @EnableGlobalMethodSecurity(securedEnabled = true)

                        3. As with most Spring related proxies, make sure that the class and the secured methods are not in any way final. For Kotlin this means "open" every method as well as the class.

                        4. When the class and its methods are virtual ("open"), then there is no implied need for an interface.


                        Here is part of a working Kotlin example:



                        @RestController
                        @RequestMapping("api/v1")

                        open class DiagnosticsController {
                        @Autowired
                        lateinit var systemDao : SystemDao

                        @RequestMapping("ping", method = arrayOf(RequestMethod.GET))
                        @Secured("ROLE_ADMIN")
                        open fun ping(request : HttpServletRequest, response: HttpServletResponse) : String { ...
                        }


                        and



                        @Configuration
                        @EnableWebSecurity
                        @EnableGlobalMethodSecurity(securedEnabled = true)
                        open class WebSecurityConfig : WebSecurityConfigurerAdapter() {


                        Regards






                        share|improve this answer




























                          8












                          8








                          8







                          I know this thread is quite old and my answer alludes to portions of the answers by various people in this thread; but here is a list combined list of pitfalls and answers:




                          1. When using @Secured, and the role name is (e.g.) ADMIN; this means an annotation of @Secured("ROLE_ADMIN").

                          2. WebSecurityConfigurerAdapter must have @EnableGlobalMethodSecurity(securedEnabled = true)

                          3. As with most Spring related proxies, make sure that the class and the secured methods are not in any way final. For Kotlin this means "open" every method as well as the class.

                          4. When the class and its methods are virtual ("open"), then there is no implied need for an interface.


                          Here is part of a working Kotlin example:



                          @RestController
                          @RequestMapping("api/v1")

                          open class DiagnosticsController {
                          @Autowired
                          lateinit var systemDao : SystemDao

                          @RequestMapping("ping", method = arrayOf(RequestMethod.GET))
                          @Secured("ROLE_ADMIN")
                          open fun ping(request : HttpServletRequest, response: HttpServletResponse) : String { ...
                          }


                          and



                          @Configuration
                          @EnableWebSecurity
                          @EnableGlobalMethodSecurity(securedEnabled = true)
                          open class WebSecurityConfig : WebSecurityConfigurerAdapter() {


                          Regards






                          share|improve this answer















                          I know this thread is quite old and my answer alludes to portions of the answers by various people in this thread; but here is a list combined list of pitfalls and answers:




                          1. When using @Secured, and the role name is (e.g.) ADMIN; this means an annotation of @Secured("ROLE_ADMIN").

                          2. WebSecurityConfigurerAdapter must have @EnableGlobalMethodSecurity(securedEnabled = true)

                          3. As with most Spring related proxies, make sure that the class and the secured methods are not in any way final. For Kotlin this means "open" every method as well as the class.

                          4. When the class and its methods are virtual ("open"), then there is no implied need for an interface.


                          Here is part of a working Kotlin example:



                          @RestController
                          @RequestMapping("api/v1")

                          open class DiagnosticsController {
                          @Autowired
                          lateinit var systemDao : SystemDao

                          @RequestMapping("ping", method = arrayOf(RequestMethod.GET))
                          @Secured("ROLE_ADMIN")
                          open fun ping(request : HttpServletRequest, response: HttpServletResponse) : String { ...
                          }


                          and



                          @Configuration
                          @EnableWebSecurity
                          @EnableGlobalMethodSecurity(securedEnabled = true)
                          open class WebSecurityConfig : WebSecurityConfigurerAdapter() {


                          Regards







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Oct 10 '16 at 16:54

























                          answered Oct 10 '16 at 16:48









                          user1210708user1210708

                          34838




                          34838























                              1














                              This issue was solved.



                              I add @EnableGlobalMethodSecurity(prePostEnabled = true)



                              @Configuration
                              @EnableWebSecurity
                              @EnableGlobalMethodSecurity(prePostEnabled = true)
                              public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{
                              }


                              And in controller i changed @Secured("ADMIN") to @PreAuthorize("hasRole('ADMIN')")






                              share|improve this answer




























                                1














                                This issue was solved.



                                I add @EnableGlobalMethodSecurity(prePostEnabled = true)



                                @Configuration
                                @EnableWebSecurity
                                @EnableGlobalMethodSecurity(prePostEnabled = true)
                                public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{
                                }


                                And in controller i changed @Secured("ADMIN") to @PreAuthorize("hasRole('ADMIN')")






                                share|improve this answer


























                                  1












                                  1








                                  1







                                  This issue was solved.



                                  I add @EnableGlobalMethodSecurity(prePostEnabled = true)



                                  @Configuration
                                  @EnableWebSecurity
                                  @EnableGlobalMethodSecurity(prePostEnabled = true)
                                  public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{
                                  }


                                  And in controller i changed @Secured("ADMIN") to @PreAuthorize("hasRole('ADMIN')")






                                  share|improve this answer













                                  This issue was solved.



                                  I add @EnableGlobalMethodSecurity(prePostEnabled = true)



                                  @Configuration
                                  @EnableWebSecurity
                                  @EnableGlobalMethodSecurity(prePostEnabled = true)
                                  public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{
                                  }


                                  And in controller i changed @Secured("ADMIN") to @PreAuthorize("hasRole('ADMIN')")







                                  share|improve this answer












                                  share|improve this answer



                                  share|improve this answer










                                  answered Jul 7 '15 at 9:40









                                  silverhawksilverhawk

                                  1091111




                                  1091111























                                      1














                                      You need to use @secured(ROLE_ADMIN) instead of @secured(ADMIN). You are required to write "ROLE_" infront of your role name. Please find the example mentioned below which is making sure only a user with Admin role can access list() method.



                                      @RestController
                                      @RequestMapping("/api/groups")
                                      public class GroupController {

                                      @Autowired
                                      private GroupService groupService;

                                      @Secured("ROLE_ADMIN")
                                      @RequestMapping
                                      public List<Group> list() {
                                      return groupService.findAll();
                                      }

                                      }





                                      share|improve this answer




























                                        1














                                        You need to use @secured(ROLE_ADMIN) instead of @secured(ADMIN). You are required to write "ROLE_" infront of your role name. Please find the example mentioned below which is making sure only a user with Admin role can access list() method.



                                        @RestController
                                        @RequestMapping("/api/groups")
                                        public class GroupController {

                                        @Autowired
                                        private GroupService groupService;

                                        @Secured("ROLE_ADMIN")
                                        @RequestMapping
                                        public List<Group> list() {
                                        return groupService.findAll();
                                        }

                                        }





                                        share|improve this answer


























                                          1












                                          1








                                          1







                                          You need to use @secured(ROLE_ADMIN) instead of @secured(ADMIN). You are required to write "ROLE_" infront of your role name. Please find the example mentioned below which is making sure only a user with Admin role can access list() method.



                                          @RestController
                                          @RequestMapping("/api/groups")
                                          public class GroupController {

                                          @Autowired
                                          private GroupService groupService;

                                          @Secured("ROLE_ADMIN")
                                          @RequestMapping
                                          public List<Group> list() {
                                          return groupService.findAll();
                                          }

                                          }





                                          share|improve this answer













                                          You need to use @secured(ROLE_ADMIN) instead of @secured(ADMIN). You are required to write "ROLE_" infront of your role name. Please find the example mentioned below which is making sure only a user with Admin role can access list() method.



                                          @RestController
                                          @RequestMapping("/api/groups")
                                          public class GroupController {

                                          @Autowired
                                          private GroupService groupService;

                                          @Secured("ROLE_ADMIN")
                                          @RequestMapping
                                          public List<Group> list() {
                                          return groupService.findAll();
                                          }

                                          }






                                          share|improve this answer












                                          share|improve this answer



                                          share|improve this answer










                                          answered Mar 10 '17 at 5:55









                                          Sadiq AliSadiq Ali

                                          7121617




                                          7121617























                                              0














                                              Maybe you should register your AppSecurityConfiguration to same context as WebMvcConfig (that extends WebMvcConfigurerAdapter).



                                              AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();      
                                              mvcContext.register(WebMvcConfig.class, SecurityConfig.class);





                                              share|improve this answer




























                                                0














                                                Maybe you should register your AppSecurityConfiguration to same context as WebMvcConfig (that extends WebMvcConfigurerAdapter).



                                                AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();      
                                                mvcContext.register(WebMvcConfig.class, SecurityConfig.class);





                                                share|improve this answer


























                                                  0












                                                  0








                                                  0







                                                  Maybe you should register your AppSecurityConfiguration to same context as WebMvcConfig (that extends WebMvcConfigurerAdapter).



                                                  AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();      
                                                  mvcContext.register(WebMvcConfig.class, SecurityConfig.class);





                                                  share|improve this answer













                                                  Maybe you should register your AppSecurityConfiguration to same context as WebMvcConfig (that extends WebMvcConfigurerAdapter).



                                                  AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();      
                                                  mvcContext.register(WebMvcConfig.class, SecurityConfig.class);






                                                  share|improve this answer












                                                  share|improve this answer



                                                  share|improve this answer










                                                  answered May 3 '16 at 8:16









                                                  digz6666digz6666

                                                  1,4792232




                                                  1,4792232























                                                      0














                                                      I want to share my decision, may be it will be helpful.



                                                      Used spring mvc + spring security, version 4.2.9.RELEASE



                                                      For example, i have a Service with method annotated @Secured



                                                      @Secured("ACTION_USER_LIST_VIEW")
                                                      List<User> getUsersList();


                                                      But, it didn't work, because GlobalMethodSecurityConfiguration has inside method.



                                                      protected AccessDecisionManager accessDecisionManager()


                                                      in which initialized the new RoleVoter() with default rolePrefix = "ROLE_"; (this makes it impossible to use beans to set your rolePrefix) that give to us not working annotations, because RoleVoter expects annotation value which starts with 'ROLE_'



                                                      For resolving this problem i override GlobalMethodSecurityConfiguration like this



                                                      @Configuration
                                                      @EnableGlobalMethodSecurity(securedEnabled = true)
                                                      public class AppMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
                                                      @Override
                                                      protected AccessDecisionManager accessDecisionManager() {
                                                      List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList<>();
                                                      ExpressionBasedPreInvocationAdvice expressionAdvice = new ExpressionBasedPreInvocationAdvice();
                                                      expressionAdvice.setExpressionHandler(getExpressionHandler());
                                                      decisionVoters.add(getRoleVoter());
                                                      decisionVoters.add(new AuthenticatedVoter());
                                                      return new AffirmativeBased(decisionVoters);
                                                      }

                                                      private RoleVoter getRoleVoter() {
                                                      RoleVoter e = new RoleVoter();
                                                      e.setRolePrefix("");
                                                      return e;
                                                      }
                                                      }





                                                      share|improve this answer






























                                                        0














                                                        I want to share my decision, may be it will be helpful.



                                                        Used spring mvc + spring security, version 4.2.9.RELEASE



                                                        For example, i have a Service with method annotated @Secured



                                                        @Secured("ACTION_USER_LIST_VIEW")
                                                        List<User> getUsersList();


                                                        But, it didn't work, because GlobalMethodSecurityConfiguration has inside method.



                                                        protected AccessDecisionManager accessDecisionManager()


                                                        in which initialized the new RoleVoter() with default rolePrefix = "ROLE_"; (this makes it impossible to use beans to set your rolePrefix) that give to us not working annotations, because RoleVoter expects annotation value which starts with 'ROLE_'



                                                        For resolving this problem i override GlobalMethodSecurityConfiguration like this



                                                        @Configuration
                                                        @EnableGlobalMethodSecurity(securedEnabled = true)
                                                        public class AppMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
                                                        @Override
                                                        protected AccessDecisionManager accessDecisionManager() {
                                                        List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList<>();
                                                        ExpressionBasedPreInvocationAdvice expressionAdvice = new ExpressionBasedPreInvocationAdvice();
                                                        expressionAdvice.setExpressionHandler(getExpressionHandler());
                                                        decisionVoters.add(getRoleVoter());
                                                        decisionVoters.add(new AuthenticatedVoter());
                                                        return new AffirmativeBased(decisionVoters);
                                                        }

                                                        private RoleVoter getRoleVoter() {
                                                        RoleVoter e = new RoleVoter();
                                                        e.setRolePrefix("");
                                                        return e;
                                                        }
                                                        }





                                                        share|improve this answer




























                                                          0












                                                          0








                                                          0







                                                          I want to share my decision, may be it will be helpful.



                                                          Used spring mvc + spring security, version 4.2.9.RELEASE



                                                          For example, i have a Service with method annotated @Secured



                                                          @Secured("ACTION_USER_LIST_VIEW")
                                                          List<User> getUsersList();


                                                          But, it didn't work, because GlobalMethodSecurityConfiguration has inside method.



                                                          protected AccessDecisionManager accessDecisionManager()


                                                          in which initialized the new RoleVoter() with default rolePrefix = "ROLE_"; (this makes it impossible to use beans to set your rolePrefix) that give to us not working annotations, because RoleVoter expects annotation value which starts with 'ROLE_'



                                                          For resolving this problem i override GlobalMethodSecurityConfiguration like this



                                                          @Configuration
                                                          @EnableGlobalMethodSecurity(securedEnabled = true)
                                                          public class AppMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
                                                          @Override
                                                          protected AccessDecisionManager accessDecisionManager() {
                                                          List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList<>();
                                                          ExpressionBasedPreInvocationAdvice expressionAdvice = new ExpressionBasedPreInvocationAdvice();
                                                          expressionAdvice.setExpressionHandler(getExpressionHandler());
                                                          decisionVoters.add(getRoleVoter());
                                                          decisionVoters.add(new AuthenticatedVoter());
                                                          return new AffirmativeBased(decisionVoters);
                                                          }

                                                          private RoleVoter getRoleVoter() {
                                                          RoleVoter e = new RoleVoter();
                                                          e.setRolePrefix("");
                                                          return e;
                                                          }
                                                          }





                                                          share|improve this answer















                                                          I want to share my decision, may be it will be helpful.



                                                          Used spring mvc + spring security, version 4.2.9.RELEASE



                                                          For example, i have a Service with method annotated @Secured



                                                          @Secured("ACTION_USER_LIST_VIEW")
                                                          List<User> getUsersList();


                                                          But, it didn't work, because GlobalMethodSecurityConfiguration has inside method.



                                                          protected AccessDecisionManager accessDecisionManager()


                                                          in which initialized the new RoleVoter() with default rolePrefix = "ROLE_"; (this makes it impossible to use beans to set your rolePrefix) that give to us not working annotations, because RoleVoter expects annotation value which starts with 'ROLE_'



                                                          For resolving this problem i override GlobalMethodSecurityConfiguration like this



                                                          @Configuration
                                                          @EnableGlobalMethodSecurity(securedEnabled = true)
                                                          public class AppMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
                                                          @Override
                                                          protected AccessDecisionManager accessDecisionManager() {
                                                          List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList<>();
                                                          ExpressionBasedPreInvocationAdvice expressionAdvice = new ExpressionBasedPreInvocationAdvice();
                                                          expressionAdvice.setExpressionHandler(getExpressionHandler());
                                                          decisionVoters.add(getRoleVoter());
                                                          decisionVoters.add(new AuthenticatedVoter());
                                                          return new AffirmativeBased(decisionVoters);
                                                          }

                                                          private RoleVoter getRoleVoter() {
                                                          RoleVoter e = new RoleVoter();
                                                          e.setRolePrefix("");
                                                          return e;
                                                          }
                                                          }






                                                          share|improve this answer














                                                          share|improve this answer



                                                          share|improve this answer








                                                          edited Nov 16 '18 at 22:43

























                                                          answered Nov 16 '18 at 0:20









                                                          IgorIgor

                                                          13117




                                                          13117






























                                                              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%2f31186826%2fspring-security-method-security-annotation-secured-is-not-working-java-con%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

                                                              Florida Star v. B. J. F.

                                                              Error while running script in elastic search , gateway timeout

                                                              Adding quotations to stringified JSON object values