更新:我改變了這個問題是關於我遇到的具體問題。這是因爲過濾器的單元測試將在Grails 2.0中得到支持,所以希望文檔會更好。使用FiltersUnitTestCase來單元測試Shiro安全過濾器,IllegalStateException
我想爲我設置的過濾器編寫單元測試,在我的grails應用程序中實現Shiro安全。我正在使用Grails 1.3.7,並且無法爲此特定項目使用2.0一段時間(如果有的話)。
我的過濾器背後的想法是我需要匿名訪問數字或控制器/操作組合,但保護對其他人的訪問。我也希望它失敗,即如果您忘記明確允許訪問,則禁止訪問。
過濾器類
class SecurityFilters {
def filters = {
homeAccess(controller: "home", action: "*") {
before = {
// Allow all access
request.accessAllowed = true
}
}
serverAccess(controller: "server", action: "list") {
before = {
// Allow all access
request.accessAllowed = true
}
}
layerAccess(controller: "layer", action: "list|listBaseLayersAsJson|listNonBaseLayerAsJson|showLayerByItsId") {
before = {
// Allow all access
request.accessAllowed = true
}
}
all(uri: "/**") {
before = {
// Check if request has been allowed by another filter
if (request.accessAllowed) return true
// Ignore direct views (e.g. the default main index page).
if (!controllerName) return true
// Access control by convention.
accessControl(auth: false)
}
}
}
}
單元測試
import org.codehaus.groovy.grails.plugins.web.filters.FilterConfig
class SecurityFiltersTests extends FiltersUnitTestCase {
protected void setUp() {
super.setUp()
}
protected void tearDown() {
super.tearDown()
}
void testHomeControllerFilter() {
checkFilter('homeAccess')
}
void testServerControllerFilter() {
checkFilter('serverAccess')
}
void testLayerControllerFilter() {
checkFilter('layerAccess')
}
void testAllFilter() {
assertTrue "Write tests", false
}
void checkFilter(String filterName) {
FilterConfig filter = initFilter(filterName)
assertNotNull filterName + " filter should exist", filter
assertExistsBefore(filterName)
assertEquals "accessAllowed should be null to start with", null, filter.request.accessAllowed
// Run filter
filter.before()
assertEquals "accessAllowed should be true now", true, filter.request.accessAllowed
}
}
例外
的問題是,當這些測試都跑我得到下面的異常:
No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at grails.test.MockUtils$_addCommonWebProperties_closure32.doCall(MockUtils.groovy:316)
at shiro.SecurityFilters$_closure1_closure5_closure12.doCall(SecurityFilters.groovy:40)
at shiro.SecurityFilters$_closure1_closure5_closure12.doCall(SecurityFilters.groovy)
at shiro.SecurityFiltersTests.checkFilter(SecurityFiltersTests.groovy:92)
at shiro.SecurityFiltersTests$checkFilter.callCurrent(Unknown Source)
at shiro.SecurityFiltersTests.testLayerControllerFilter(SecurityFiltersTests.groovy:65)
此外,我已經把在單元測試下面一行:
println "filter.request: " + filter.request
打印出以下幾點:
filter.request: org.code[email protected]2914cca4
所以它肯定好像是用一個模擬請求對象。
所以,這些問題。
我是否正確使用FiltersUnitTestCase來執行我的過濾器?
而且,如果是這樣:
爲什麼我遇到了這個例外?