접근 권한을 부여 할 때 security-context.xml에 직접선언을 할 수 있지만, @Secured어노테이션을 사용하면 좀 더 편하고 직관적인 권한 부여가 가능하다.
@Secured 어노테이션은 권한이 필요한 부분에 선언 할 수 있는데 Class나 Method 단위까지 지정을 할 수 있다. 예를 들면 ROLE_ADMIN만 접근시킬 메서드가 있다면 해당 메서드위에 @Secured 어노테이션을 선언해주기만 하면 된다.
1.pom.xml에 cglib.jar를 추가해야한다(라이브러리의 정확한 용도는 모르겠다.)
cglib cglib 2.2
2.context:component-scan 이있는 context.xml에서 <security:global-method-security secured-annotations="enabled"/>를 추가한다.
이 부분이 참 애매 했는데, 언뜻보면 시큐리티 관련 어노테이션이기 때문에 security-context.xml에서 지정을 해야 할꺼 같았지만, 여기저기 검색 해본 결과 spring과 spring security설정xml을 따로관리하는 지금의 방식에서는 context별로 proxy(????)가 적용되어 어쩌구 저쩌구... 어려워서 그냥 패스하고
결과적으로 servlet-context.xml에 지정해야 한다는걸 알았다.
하지만 servlet-context.xml에는 security스키마 속성이 없기 때문에 추가를 해주어야 한다. 선언부에
xmlns:security="http://www.springframework.org/schema/security" 와
xsi:schemaLocation="http://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security-3.1.xsd"
를 추가해준 후 <security:global-method-security secured-annotations="enabled"/>를 추가해주면 된다.
ex)적용된 servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:security="http://www.springframework.org/schema/security" xsi:schemaLocation="http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security-3.1.xsd"> <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --> <!-- Enables the Spring MVC @Controller programming model --> <annotation-driven /> <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --> <resources mapping="/resources/**" location="/resources/" /> <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --> <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> <context:component-scan base-package="com.min.study" /> <security:global-method-security secured-annotations="enabled"/> </beans:beans>
3.권한을 적용할 메서드에 @Secured 어노테이션을 추가 한다.
ex1)접근 가능한 권한이 하나 일때
@Secured("ROLE_ADMIN") public String encoding(String str){ return encoder.encodePassword(str,null); }
ex2)접근 가능한 권한이 두개 이상일때
@RequestMapping(value = "/checkAuth", method = RequestMethod.GET) @Secured({"ROLE_ADMIN","ROLE_USER"}) public String checkAuth(Locale locale, Model model, Authentication auth) { UserDetailsVO vo = (UserDetailsVO) auth.getPrincipal(); logger.info("Welcome checkAuth! Authentication is {}.", auth); logger.info("UserDetailsVO == {}.", vo); model.addAttribute("auth", auth ); model.addAttribute("vo", vo ); return "checkAuth"; }
4. 적용 후 해당 메서드에 권한이 없는 사용자로 접근을 하게 되면 권한이 필요하다는 403에러가 뜨게된다.
------------------------------------------------------------------------------------------