Details
-
Type:
Bug
-
Status:
Resolved
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: 1.0
-
Fix Version/s: 1.1
-
Labels:None
-
Testcase included:yes
Description
I had a look a the Shiro plugin and couldn't see anything wrong there (but I'm not a plugin/grails expert) and the problem looks like it lies within grails itself.
If you use a url mapping like this:
... "/$controller/$action?/$id?"{ constraints { // apply constraints here } } "404"(controller: 'error', action: 'notFound') ...
and use a url that doesn't exist so that the "/errors/notFound" view is used and that view uses <shiro:authenticated> then an exception occurs.
If you access the controller and it's action directly using a use a url like this: 'error/notFound' then everything works as expected.
Further to this, if you create a view which has this code:
<html>
<head>
<title>Not Found</title>
<meta name="layout" content="main" />
</head>
<body>
View: org.apache.shiro.util.ThreadContext.getSecurityManager returns null?: ${org.apache.shiro.util.ThreadContext.getSecurityManager() == null }
</body>
</html>
The result will be "View: org.apache.shiro.util.ThreadContext.getSecurityManager returns null?: true" when accessing a page that doesn't exist
and "View: org.apache.shiro.util.ThreadContext.getSecurityManager returns null?: false" when accessing the controller and action directly.
Thus, any tag in the ShiroTagLib that uses SecurityManager.getSubject() will fail.
Attempting to use "<shiro:authenticated>Authenticated</shiro:authenticated>" in the "main" layout or the "notFound" view results in the following exception:
2009-10-15 12:06:49,899 [http-8080-3] ERROR errors.GrailsExceptionResolver - Error executing tag <shiro:authenticated>: java.lang.IllegalStateException: No SecurityManager accessible to this method, ... at Users_dclifton_Sites_shirobug_grails_app_views_layouts_main_gsp.run(Users_dclifton_Sites_shirobug_grails_app_views_layouts_main_gsp:27) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646) at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:551) at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:488) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646) at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:438) at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374) at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302) at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:416) at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:343) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:144) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454) at java.lang.Thread.run(Thread.java:613) Caused by: org.codehaus.groovy.runtime.InvokerInvocationException: java.lang.IllegalStateException: No SecurityManager accessible to this method, ... ... 22 more Caused by: java.lang.IllegalStateException: No SecurityManager accessible to this method, ... at org.apache.shiro.SecurityUtils.getSubject(SecurityUtils.java:79) at ShiroTagLib.checkAuthenticated(ShiroTagLib.groovy:261) at ShiroTagLib.this$2$checkAuthenticated(ShiroTagLib.groovy) at ShiroTagLib$_closure1.doCall(ShiroTagLib.groovy:32) ... 22 more
I've attached an example project, two example urls that highlight the problem are:
http://localhost:8080/shirobug/i-dont-exist <-- throws exception
http://localhost:8080/shirobug/error/notFound <-- works as expected
-
- GRAILSPLUGINS-1980-stacktrace.txt
- 24/Feb/10 3:05 AM
- 9 kB
- Peter Ledbrook
-
Hide
- shirobug.zip
- 15/Oct/09 6:24 AM
- 183 kB
- Dominic Clifton
-
- shirobug/.classpath 8 kB
- shirobug/.project 0.5 kB
- shirobug/.../org.codehaus.groovy.eclipse.preferences.prefs 0.1 kB
- shirobug/application.properties 0.2 kB
- shirobug/build.xml 5 kB
- shirobug/grails-app/.../BootStrap.groovy 0.1 kB
- shirobug/grails-app/conf/Config.groovy 3 kB
- shirobug/grails-app/.../DataSource.groovy 0.6 kB
- shirobug/grails-app/.../resources.groovy 0.0 kB
- shirobug/grails-app/.../UrlMappings.groovy 0.2 kB
- shirobug/.../ErrorController.groovy 0.0 kB
- shirobug/grails-app/.../messages.properties 3 kB
- shirobug/.../messages_de.properties 3 kB
- shirobug/.../messages_es.properties 3 kB
- shirobug/.../messages_fr.properties 2 kB
- shirobug/.../messages_it.properties 2 kB
- shirobug/.../messages_ja.properties 2 kB
- shirobug/.../messages_nl.properties 3 kB
- shirobug/.../messages_pt_BR.properties 3 kB
- shirobug/.../messages_pt_PT.properties 3 kB
- shirobug/.../messages_ru.properties 4 kB
- shirobug/.../messages_th.properties 5 kB
- shirobug/.../messages_zh_CN.properties 2 kB
- shirobug/grails-app/.../shiro.properties 0.0 kB
- shirobug/grails-app/.../error/notFound.gsp 0.3 kB
- shirobug/grails-app/views/error.gsp 2 kB
- shirobug/grails-app/views/index.gsp 3 kB
- shirobug/grails-app/.../layouts/main.gsp 0.4 kB
- shirobug/ivy.xml 2 kB
- shirobug/ivysettings.xml 0.8 kB
Activity
Also note, that it's still impossible to use a url mapping like the one below if you need to use the shiro tag library:
...
"404"(view: '/error/notFound')
...
This is of course because the workaround in my previous comment isn't being called.
This isn't a simple issue. I'll try to take a look when I have a chance. It may be that the Shiro filter isn't being invoked on an error context. In which case, it may be a bug that can be fixed in the plugin.
additionally, if you use "<g:applyLayout name="main" />" in the default error.gsp file the same problem occurs, here's a stacktrace:
2009-12-21 13:27:48,303 [http-8080-1] ERROR [Tomcat].[localhost] - Exception Processing ErrorPage[errorCode=500, location=/grails-errorhandler]
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is ...
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:659)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:438)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:416)
at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:343)
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:287)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:613)
Caused by: org.codehaus.groovy.grails.web.mapping.exceptions.UrlMappingException: Error mapping onto view [/error]: Error processing GroovyPageView: Error executing tag <g:applyLayout>: ...
at org.codehaus.groovy.grails.web.servlet.ErrorHandlingServlet$1.doFilter(ErrorHandlingServlet.java:145)
at org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:65)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.codehaus.groovy.grails.web.servlet.ErrorHandlingServlet.doDispatch(ErrorHandlingServlet.java:98)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
... 20 more
Caused by: org.codehaus.groovy.grails.web.pages.exceptions.GroovyPagesException: Error processing GroovyPageView: Error executing tag <g:applyLayout>: ...
at org.codehaus.groovy.grails.web.servlet.view.GroovyPageView.handleException(GroovyPageView.java:180)
at org.codehaus.groovy.grails.web.servlet.view.GroovyPageView.renderWithTemplateEngine(GroovyPageView.java:158)
at org.codehaus.groovy.grails.web.servlet.view.GroovyPageView.renderMergedOutputModel(GroovyPageView.java:83)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
at org.codehaus.groovy.grails.web.servlet.ErrorHandlingServlet$1.doFilter(ErrorHandlingServlet.java:143)
... 25 more
Caused by: org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException: Error executing tag <g:applyLayout>: ...
at Users_dclifton_Sites_managementconsole_grails_app_views_error_gsp.run(Users_dclifton_Sites_managementconsole_grails_app_views_error_gsp:22)
... 1 more
Caused by: org.codehaus.groovy.runtime.InvokerInvocationException: org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException: Error executing tag <shiro:authenticated>: ...
... 2 more
Caused by: org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException: Error executing tag <shiro:authenticated>: java.lang.IllegalStateException: ...
at Users_dclifton_Sites_managementconsole_grails_app_views_layouts_main_gsp$_run_closure2.doCall(Users_dclifton_Sites_managementconsole_grails_app_views_layouts_main_gsp:50)
at Users_dclifton_Sites_managementconsole_grails_app_views_layouts_main_gsp$_run_closure2.doCall(Users_dclifton_Sites_managementconsole_grails_app_views_layouts_main_gsp)
at Users_dclifton_Sites_managementconsole_grails_app_views_layouts_main_gsp.run(Users_dclifton_Sites_managementconsole_grails_app_views_layouts_main_gsp:126)
... 2 more
Caused by: org.codehaus.groovy.runtime.InvokerInvocationException: java.lang.IllegalStateException: No SecurityManager accessible to this method, ...
... 5 more
Caused by: java.lang.IllegalStateException: No SecurityManager accessible to this method, ...
at org.apache.shiro.SecurityUtils.getSubject(SecurityUtils.java:79)
at ShiroTagLib.checkAuthenticated(ShiroTagLib.groovy:261)
at ShiroTagLib.this$2$checkAuthenticated(ShiroTagLib.groovy)
at ShiroTagLib$_closure1.doCall(ShiroTagLib.groovy:32)
... 5 more
I tried modifying the way the plugin generates the web.xml to include the ERROR, FORWARD, and INCLUDE dispatchers in the filter-mapping definition for the ShiroFilter, but that didn't seem to have any effect; the error still occurs.
<filter-mapping>
<filter-name>securityContextFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
Does anybody have insight into anything else that can be done to get past this?
Can anyone attach a reproducible example? I've just tried with Grails 1.2.0 and Shiro plugin 1.0.1, but it seems to work.
I was able to do this with Grails 1.2.1:
1) grails create-app newapp
2) cd newapp
3) grails install-plugin shiro
4) grails quick-start
5) Create a controller called ErrorsController.groovy
class ErrorsController {
def serverError =
def notFound =
{ render(view:'notFound') }
}
[Note: The error view already exists from when you generated the app, but the notFound one doesn't. You can create the notFound view, but it won't make a difference. ]
6) Change grails-app/conf/UrlMappings.groovy and add the following 404 definition -
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
constraints
}
"/"(view:"/index")
"500"(view:'/error')
"404"(controller:"errors", action:"notFound")
}
}
7) grails run-app
8) Go to
http://localhost:8080/newapp/asdf
and you'll get the following Stack Trace:
java.lang.IllegalStateException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton. This is an invalid application configuration.
at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:115)
at org.apache.shiro.SecurityUtils.getSubject(SecurityUtils.java:57)
at ShiroGrailsPlugin.accessControlMethod(ShiroGrailsPlugin.groovy:414)
at ShiroGrailsPlugin.accessControlMethod(ShiroGrailsPlugin.groovy)
at ShiroGrailsPlugin$_closure3_closure19.doCall(ShiroGrailsPlugin.groovy:228)
at SecurityFilters$_closure1_closure2_closure3.doCall(SecurityFilters.groovy:12)
at SecurityFilters$_closure1_closure2_closure3.doCall(SecurityFilters.groovy)
at java.lang.Thread.run(Thread.java:619)
9) Now if you want to see things get nasty, add the following 500 definition to you UrlMappings.groovy and watch the console:
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
constraints { // apply constraints here }
}
"/"(view:"/index")
"500"(controller:"errors", action:"serverError")
"404"(controller:"errors", action:"notFound")
}
}
I'm having the same problem as described here.
Grails 1.2.1, Shiro Plugin 1.0.1.
Here's what I've done to temporarily work around this in my error pages.
This workaround only works if no Shiro references are made during the processing of the error page request (no <shiro: />, etc).
Basically, I have an ErrorsController that handles 404, 500 errors. In my UrlMappings I map the controller to the HTTP status codes as usual. The trick is that in SecurityFilters there is a check to see if an error page is rendering. If so, the accessControl() method is NOT called.
class UrlMappings {
static mappings = {
// ...other mappings omitted...
"404"(controller: 'error', action: 'notfound')
"500"(controller: 'error', action: 'fault')
}
}
class SecurityFilters {
// GRAILS-5234
private static final String ERROR_CONTROLLER_NAME = 'error'
private static final String FAULT_ACTION_NAME = 'fault'
private static final String NOTFOUND_ACTION_NAME = 'notfound'
private boolean isErrorPage(controllerName, actionName) {
def isErrorPage = ERROR_CONTROLLER_NAME.equals(controllerName) || FAULT_ACTION_NAME.equals(actionName) || NOTFOUND_ACTION_NAME.equals(actionName)
if (isErrorPage) log.debug "error page is being displayed with controller $controllerName and action $actionName"
isErrorPage
}
def filters = {
app(uri: "/app/**") {
before = {
// GRAILS-5234
if (!isErrorPage(controllerName, actionName)) {
// Access control by convention.
accessControl()
}
}
}
}
class ErrorController {
/** Handle's 404 errors. */
def notfound = {
}
/** Handle's server 500 errors. */
def fault = {
}
}
Edited the stack traces because the long lines mess up the formatting of the issue page.
Full stack trace, since I edited out bits from the description and comments.
I believe this is fixed in the current code, which will be released as 1.1. We just have one more thing to sort out before releasing 1.1 final.
I have tried again with the latest 1.1-SNAPSHOT. The issue has not been fixed. I am still getting the "No SecurityManager accessible to this method" error when a shiro tag is used in a sitemash layout that my error page extends.
Caused by: org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton. This is an invalid application configuration. at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:124)
I see other users saying this isn't fixed, but it's still marked fixed two years later. Is this fixed or not?
I get this error all the time but randomly. Sometimes it works, sometimes this happens. My config never changes.
2012-08-09 18:40:17,764 ERROR [GrailsExceptionResolver] Exception occurred when processing request: [POST] /testapp/resource/show - parameters: org.codehaus.groovy.grails.SYNCHRONIZER_URI: /testapp/resource/list org.codehaus.groovy.grails.SYNCHRONIZER_TOKEN: d3296009-caa9-4ffb-b45a-e899e0a6356c Stacktrace follows: org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton. This is an invalid application configuration. at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:124) at org.apache.shiro.subject.Subject$Builder.<init>(Subject.java:616) at org.apache.shiro.SecurityUtils.getSubject(SecurityUtils.java:57) at ShiroGrailsPlugin.accessControlMethod(ShiroGrailsPlugin.groovy:444) at ShiroGrailsPlugin$_closure3_closure25.doCall(ShiroGrailsPlugin.groovy:252) at SecurityFilters$_closure1_closure2_closure3.doCall(SecurityFilters.groovy:17) at SecurityFilters$_closure1_closure2_closure3.doCall(SecurityFilters.groovy) at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190) at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291) at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:776) at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:705) at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:898) at java.lang.Thread.run(Thread.java:662)
Do you have a reproducible example? Or at least one that demonstrates the issue intermittently?
No, not right now. I can try to put something together, but it would be extremely difficult to put together an example that resembles our project. There are simply so many moving parts. This fact along with the fact that this happens randomly and that there is absolutely no application-referencing elements in the stack trace of this error makes it impossible for me to reproduce consistently.
Typically, here is the usage pattern I think exists when I notice this happening. Often I think that a form is involved. A user prepares a form, and clicks submit. Then, something happens. Perhaps the users stops the browser action, clicks the back button, or perhaps initiates a sign-out action. Perhaps code gets changes and the development environment begins to recompile certain groovy files.
It seems that sometimes (not always) when the user begins to interact with the form page again, or certain other pages where application session fields are accessed, this error seems to occur.
I wonder if it's related to an issue in the core library. That's fixed in Shiro 1.2, which is what version 1.2.0-SNAPSHOT of the plugin is based on. Do you mind trying 1.2.0-SNAPSHOT? It passes the tests in the project and works in grails.org.
As a workaround, I updated my errorController to look like this:
Though why I have to do this remains a mystery to me, is this a grails bug or a shiro plugin bug?