2010-06-21 3 views

답변

63

네, 정상적으로 작동합니다.

<security:global-method-security pre-post-annotations="enabled" />...-servlet.xml입니다. CGLIB proxies이 필요하므로 컨트롤러에 인터페이스가 없어야하거나 proxy-target-class = true을 사용해야합니다.

+1

하지만, @Controller를 사용하는 컨트롤러에서는 Spring이 아무 것도하지 않습니다. 이 일이 당신이 말한 것 이상으로 효과를 발휘하려면 특별한 일을해야합니까? – egervari

+13

에서 "글로벌 메소드 보안"은 "스프링 보안 애플리케이션 컨텍스트"가 아닌 DispatcherServlet 컨텍스트 ('...- servlet.xml')에 있어야한다고 말했습니다. – axtavt

+0

감사! 왜 합병 된 이후에 차이가 나는지 알 수 없기 때문에 나는 그것을 움직이지 않았다. 나는 그렇지 않았다고 생각한다;) 이제 작동한다! – egervari

20

Spring Security FAQ (강조 광산)을 참조하십시오. 봄 웹 응용 프로그램에서

, 디스패처 서블릿의 스프링 MVC 빈을 보유하고있는 애플리케이션 컨텍스트는 종종 기본 응용 프로그램 컨텍스트에서 분리합니다. 이것은 종종 myapp-servlet.xml 파일에 정의됩니다. 여기서 "myapp"는 web.xml의 DispatcherServlet에 할당 된 이름입니다. 응용 프로그램에는 각각 DispatcherServlet이있을 수 있으며 각각 고유 한 격리 된 응용 프로그램 컨텍스트가 있습니다. 이러한 "하위"컨텍스트의 beans는 나머지 응용 프로그램에서 볼 수 없습니다. "부모"응용 프로그램 컨텍스트는 web.xml에 정의한 ContextLoaderListener에 의해로드되고 모든 자식 컨텍스트 에 표시됩니다. 이 상위 컨텍스트는 일반적으로 요소를 포함하여 보안 구성을 정의하는 곳입니다. 결과적으로 콩이 DispatcherServlet 컨텍스트에서 볼 수 없으므로 의 메소드에 적용된 보안 제한이 적용되지 않습니다. 선언을 웹 컨텍스트로 이동하거나 보안을 유지하려는 bean을 기본 응용 프로그램 컨텍스트로 이동해야합니다.

일반적으로 개별 웹 컨트롤러가 아닌 계층의 서비스에서 메소드 보안을 적용하는 것이 좋습니다. 당신이 서비스 계층에 포인트 컷을 적용하면

당신은 앱의 보안 컨텍스트에서 <global-method-security>을 설정해야합니다.

+0

컨트롤러에서 @PreAuthorize를 사용하려고했지만 작동하지 않았습니다. 일단 서비스 레이어로 이동하면 작동했습니다. – MarCrazyness

16

Spring 3.1을 사용한다면, 이것으로 꽤 멋진 것을 할 수 있습니다. https://github.com/mohchi/spring-security-request-mapping을보십시오. 그것은 당신이 뭔가를 할 수 있도록 스프링 MVC의 RequestMappingHandlerMapping와 @PreAuthorize을 통합하는 샘플 프로젝트입니다 :

@RequestMapping("/") 
@PreAuthorize("isAuthenticated()") 
public String authenticatedHomePage() { 
    return "authenticatedHomePage"; 
} 

@RequestMapping("/") 
public String homePage() { 
    return "homePage"; 
} 

사용자가 인증 된 경우 "/"호출 authenticatedHomePage()에 대한 요청. 그렇지 않으면 homePage()를 호출합니다.

9

이 질문이 제기 된 이래로 2 년이 지났지 만 오늘 내가 가진 문제로 인해 , @PreAuthorize 등을 @Controller에 사용하는 것이 좋습니다.

@Controller 
@Secured("ROLE_ADMIN") 
public class AdministrationController { 

// @InitBinder here... 

@RequestMapping(value = "/administration/add-product", method = RequestMethod.POST) 
public String addProductPost(@ModelAttribute("product") @Validated ProductDto product, BindingResult bindingResult) { 
    // ... 
} 

검사기는 단순히 화재 (스프링 MVC 4.1.2, 봄 보안 3.2.5)하지 않는 어떠한 검사가 수행되지 않은 : 나를 위해 작동하지 않았다 무엇

@Validated@Secured 컨트롤러와 결합되었다.

유사한 문제는 스프링에 의해 사용 CGLIB 프록시에 의해 발생된다 (클래스 구현에 인터페이스가없는 경우, 스프링 CGLIB 프록시를 생성, 클래스 다음 JDK 프록시가 생성되는 임의의 인터페이스를 구현하는 경우 - documentation, well explained herehere 참조).

위에서 링크 된 답변에서 언급했듯이, 일반적으로 인터페이스를 구현하는 서비스 레이어에서 스프링 보안 주석을 사용하지 않는 것이 좋습니다 (JDK 프록시가 사용됨). 이러한 문제로 이어지지 않기 때문에.

웹 컨트롤러를 보호하려면 컨트롤러의 메서드가 아닌 특정 URL에 바인딩되어 꽤 잘 작동하는 <http><intercept-url />을 사용하는 것이 가장 좋습니다. 내 경우 :

<http use-expressions="true" disable-url-rewriting="true"> 

    ... 

    <intercept-url pattern="/administration/**" access="hasRole('ROLE_ADMIN')" /> 

</http> 
1

앤디가 제공하는 답을 확장하려면, 당신은 사용할 수 있습니다

@PreAuthorize("hasRole('foo')") 

가 특정 역할을 확인 할 수 있습니다.

2

이미 XML 구성을 변경하여 작동시키는 방법에 대한 답변이 있습니다. 당신은 코드 기반 구성 작업하는 경우 그러나, 당신이 당신의 @Configuration 클래스에 비해 다음과 같은 주석을 배치하여 동일한을 달성 할 수있다 : 내 봄 보안 응용 프로그램 컨텍스트에서 (이미 실제로 있었다) 것을 넣어

@EnableGlobalMethodSecurity(prePostEnabled=true) 
관련 문제