Spring Security using @Secured Annotation
November 27, 2019
On this page we will learn how to secure a service layer method using @Secured
annotation in our Spring Security application. To enable annotation based security, we need to configure <global-method-security>
namespace. The @Secured
annotation can allow method access for one or more roles. In our application it is our choice which method should be secured and which is not using @Secured
annotation. The method that needs to be secured is annotated with @Secured
and the method is secured.
<global-method-security>
The<global-method-security>
is the namespace which is the first step to configure. It has the attribute secured-annotations
which is enabled to get annotation based security. We configure it as following.
<global-method-security secured-annotations="enabled" />
@Secured
annotation by annotating Java configuration class with @EnableGlobalMethodSecurity
annotation as following.
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled=true) public class SecurityConfig { ------ }
How to use @Secured Annotation
Suppose we have roles like ROLE_USER and ROLE_ADMIN, so we can define a method by annotating@Secured("ROLE_ADMIN") public void deleteUser(String name);
@Secured ({"ROLE_USER", "ROLE_ADMIN"}) public void addUser(String name, String pwd);
IUserService
. There are two methods addUser()
and deleteUser()
. We have secured deleteUser()
method for the ROLE_ADMIN and addUser()
method can be accessed by both roles. Find all the configurations.
IUserService.java
package com.concretepage.service; import org.springframework.security.access.annotation.Secured; public interface IUserService { @Secured ({"ROLE_USER", "ROLE_ADMIN"}) public void addUser(String name, String pwd); @Secured("ROLE_ADMIN") public void deleteUser(String name); }
package com.concretepage.service; public class UserService implements IUserService { @Override public void addUser(String name, String pwd) { System.out.println("user added"); } @Override public void deleteUser(String name) { System.out.println("user deleted"); } }
LoginController.java
package com.concretepage.security.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.concretepage.service.IUserService; @Controller @RequestMapping("/login") public class LoginController { @Autowired public IUserService userService; @RequestMapping(method = RequestMethod.GET) public String success(ModelMap map) { userService.addUser("ABC", "abc"); userService.deleteUser("ABC"); map.addAttribute("msg", "Done Successfully"); return "success"; } }
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> <http auto-config="true"> <intercept-url pattern="/login" access="ROLE_USER,ROLE_ADMIN" /> <logout logout-success-url="/login" /> </http> <authentication-manager> <authentication-provider> <user-service> <user name="ram" password="con1234" authorities="ROLE_ADMIN" /> <user name="rahim" password="con1234" authorities="ROLE_USER" /> </user-service> </authentication-provider> </authentication-manager> <global-method-security secured-annotations="enabled" /> <beans:bean name="userService" class="com.concretepage.service.UserService"/> </beans:beans>
Output UI
Login with user ram and password con1234 and you will see success message.
Login with user rahim with password con1234 and you will see access denied message.
Our observation is that first login with user ram and there is no error because this user is authorized for both role. But when we login with rahim, it denies access for
deleteUser()
method.