2012-02-22 92 views
1

(首先,我很抱歉,我不能比縮進的一個水平我的代碼獲得更多)春季安全@Preauthorize標籤不工作在單元測試

我試圖寫一個單元測試來測試我的服務層方法。這些服務類的接口都標註有@Preauthorize:

public interface LocationService { 

    void setLocationRepository(LocationRepository locationRepository); 

    /** 
    * Get all Location objects from the backend repository 
    * @return 
    */ 

    @PreAuthorize("has_role('ROLE_ADMIN')") 
    List<Location> getAll(); 

單元測試看起來是這樣的:

@Before 
public void setUp() { 
    admin = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("admin", "admin")); 
    user = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("user", "user")); 
    // create Mock Repository 
    // set up the actual service WITH the repository 
    locationService = new LocationServiceImpl(); 
    locationService.setLocationRepository(locationRepository); 
} 

@Test(expected = AccessDeniedException.class) 
@SuppressWarnings("unused") 
public void testGetAllAsUser() { 
    SecurityContextHolder.getContext().setAuthentication(user); 
    List<Location> resultList = locationService.getAll(); 
} 

最後,這裏是從我的applicationContext.xml安全上下文:

<!-- Temporary security config. This will get moved to a separate context 
    file, but I need it for unit testing right now --> 
<security:http use-expressions="true"> 
    <security:form-login /> 
    <security:session-management 
     invalid-session-url="/timeout.jsp"> 
     <security:concurrency-control 
      max-sessions="1" error-if-maximum-exceeded="true" /> 
    </security:session-management> 
</security:http> 
<security:authentication-manager alias="authenticationManager"> 
    <security:authentication-provider> 
     <security:password-encoder hash="plaintext" /> 
     <security:user-service> 
      <security:user name="admin" password="admin" 
       authorities="ROLE_ADMIN" /> 
      <security:user name="user" password="user" 
       authorities="ROLE_USER" /> 
     </security:user-service> 
    </security:authentication-provider> 
</security:authentication-manager> 

<security:global-method-security 
    pre-post-annotations="enabled" proxy-target-class="true" /> 

不幸的是,@PreAuthorize標記被忽略,允許有ROLE_USER的人運行getAll()。

任何人都可以幫忙嗎?

傑森

回答

1
  • 你運行與彈簧的JUnit運行單元測試?
  • 您是否指向該單元測試的正確的彈簧配置文件?
  • 您是否爲安全性方面配置了加載時織入?

線:

locationService = new LocationServiceImpl(); 

創建一個新的位置的服務,完全繞過彈簧。如果您使用的是spring junit runner,那麼您應該使用@Resource來獲取注入的locationService,以便使用spring bean而不僅僅是pojo。

+0

好點,我會修復它以從上下文獲得LocationService bean。我也會試着弄清楚我是否已經編織好了,但是代碼在工作,所以我不能在早上檢查它。 – Jason 2012-02-22 23:23:34

+0

您不需要啓用LTW以使其工作,但如果不是,那麼您需要確保您在spring代理上調用方法,而不是直接在您的impl上調用該方法,這是後半部分我的答案正在進行中。 – digitaljoel 2012-02-22 23:55:05

+0

好吧,你是對的。我非常愚蠢的錯誤。我轉過身來,讓Spring autowire locationService。 – Jason 2012-02-23 12:57:55