6

I'm using Spring MVC to expose RESTful services. I already enabled authentication via HTTPBasicAuthentication, and using <security:http> i can control which roles can access urls.

Now I want to use @Secured annotation. I tried to add it to Controller methods but it doesn't work. It simply does nothing.

Here is my Controller class:

@Controller
@RequestMapping("/*")
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

private static final String USERS = "/users";
private static final String USER = USERS+"/{userId:.*}";

    @RequestMapping(value=USER, method=RequestMethod.GET)
    @Secured(value = {"ROLE_ADMIN"})
    public @ResponseBody User signin(@PathVariable String userId) {
        logger.info("GET users/"+userId+" received");
        User user= service.getUser(userId);
        if(user==null)
                throw new ResourceNotFoundException();
        return user;
    }
}

This is my security-context.xml:

<http auto-config='true'>
    <intercept-url pattern="/**" access="ROLE_USER"/>
</http>

<global-method-security secured-annotations="enabled" />

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="admin@somedomain.com" password="admin"
                authorities="ROLE_USER, ROLE_ADMIN" />
            <user name="user@somedomain.com" password="pswd"
                authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>

And my root-context.xml:

<context:component-scan base-package="org.mypackage" />

<import resource="database/DataSource.xml"/> 

<import resource="database/Hibernate.xml"/>

<import resource="beans-context.xml"/> 

<import resource="security-context.xml"/> 

All works fine, but If I add @Secured, it simply does nothing: I can access secured method with user@somedomain.com also, which hasn't ROLE_ADMIN privileges. I already tried to move <security:global-method-security> to root-context.xml, it doesn't work. I also tried to secure the same method via <security:http> tag, it works fine, but I want to use @Secured annotation.

Thank you.

EDIT: I've also a servlet-context.xml and a controllers.xml config file in the appServlet subdirectory.

Here is servlet-context.xml:

<mvc:resources mapping="/resources/**" location="/resources/" />

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean>

<beans:import resource="controllers.xml" />

And controllers.xml:

<context:component-scan base-package="org.mose.emergencyalert.controllers" />

<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />     

<beans:bean id="homeController" class="org.mose.emergencyalert.controllers.HomeController"/> 
tereško
  • 58,060
  • 25
  • 98
  • 150
user1781028
  • 1,478
  • 4
  • 22
  • 45
  • why do you have `security:` prefix for `global-method-security` where `authentication-manager` does not have? – Arun P Johny Jan 21 '13 at 10:50
  • cut/paste mistake, while moving the tag from root-context, sorry. However still not working. – user1781028 Jan 21 '13 at 10:56
  • Just to be clear - is your entire configuration in the root application context or is some in the child DispatcherServlet context as well? Also, is your Controller implementing any interface? – Eugen Jan 21 '13 at 10:58
  • try forcing cglib proxies: – Eugen Jan 21 '13 at 11:04
  • I added Controller class definition, no interface implementation. In the appServlet subdirectory I have `servlet-context.xml` and `controllers.xml`. Maybe I've to specify `` in `serlvet-context.xml`? – user1781028 Jan 21 '13 at 11:08
  • 1
    Yes, you have. http://stackoverflow.com/questions/6651119/secured-does-not-work-in-controller-but-intercept-url-seems-to-be-working-fine – axtavt Jan 21 '13 at 11:22

2 Answers2

9

Solved, I added <global-method-security> tag in servlet-context.xml, instead of security-context.xml.

Here is the new security-context.xml:

<annotation-driven />

<security:global-method-security secured-annotations="enabled"/>

<resources mapping="/resources/**" location="/resources/" />

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean>

NB: now Eclipse warns me at the <security:global-method-security> line: "advises org.mypackage.HomeController.signin(String, Principal)", proving that @Secured is now working.

user1781028
  • 1,478
  • 4
  • 22
  • 45
3

SOLVED

Add this tag to your config file that contain ViewResolve config : dispatcher's xml NOT on your application's xml <security:global-method-security pre-post-annotations="enabled" secured annotations="enabled">

tuto

becher henchiri
  • 618
  • 4
  • 10