Struts2 + Spring Security 2.06: Valuestack имеет значение null при попытке использовать @Secured в методе Action

Прежде чем я начну, я должен сказать, что ближайший ответ, который я нашел, это здесь, но, честно говоря, я не очень понимаю, что там происходит.

Я использую Struts2 + Spring Security 2.06 с настраиваемым поставщиком проверки подлинности и диспетчером решений о доступе, чтобы устранить необходимость в префиксе «ROLE_».

Мой applicationContext-security.xml выглядит так:

    <beans:bean id="customAuthenticationProvider"
                class="com.test.testconsole.security.CustomAuthenticationProvider">
        <beans:property name="userManagementService" ref="userManagementService"/>
        <custom-authentication-provider/>
    </beans:bean>

    <!--Customize Spring Security's access decision manager to remove need for "ROLE_" prefix-->
    <beans:bean
            id="accessDecisionManager"
            class="org.springframework.security.vote.AffirmativeBased">
        <beans:property name="decisionVoters">
            <beans:list>
                <beans:ref bean="roleVoter"/>
                <beans:ref bean="authenticatedVoter"/>
            </beans:list>
        </beans:property>
    </beans:bean>

    <beans:bean
            id="roleVoter"
            class="org.springframework.security.vote.RoleVoter">
        <beans:property name="rolePrefix" value=""/>
    </beans:bean>

    <beans:bean
            id="authenticatedVoter"
            class="org.springframework.security.vote.AuthenticatedVoter">
    </beans:bean>

<global-method-security secured-annotations="enabled" access-decision-manager-ref="accessDecisionManager"/>

Соответствующая часть моего web.xml:

    <!--Spring Security-->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>
        org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
    </filter-class>
</filter>

<!--Has to be placed _Before_ the struts2 filter-mapping-->
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

И я просто использую @Secured в одном из своих классов действий, например:

@Secured({"TEST_ADMIN"})
public String editAccount() {
    logger.info("Editing account for: " + email);
    //blah blah blah
}

С аннотацией @Secured, добавленной к методу в действии, все параметры становятся нулевыми, фактически выглядит так, как будто стек значений равен нулю:

154379 [1146701440@qtp-1897259366-0] DEBUG com.opensymphony.xwork2.conversion.impl.InstantiatingNullHandler  - Entering nullPropertyValue [target=[com.test.testconsole.sections.SettingsAction@da47641, com.opensymphony.xwork2.DefaultTextProvider@1cc50164], property=currentPage]        
154379 [1146701440@qtp-1897259366-0] WARN  com.opensymphony.xwork2.ognl.OgnlValueStack  - Caught an exception while evaluating expression 'currentPage.equals('Summary')' against value stack
    java.lang.NullPointerException: target is null for method equals
        at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1347)
        at ognl.ASTMethod.getValueBody(ASTMethod.java:90)
        at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
        at ognl.SimpleNode.getValue(SimpleNode.java:258)
        at ognl.ASTChain.getValueBody(ASTChain.java:141)
        at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
        at ognl.SimpleNode.getValue(SimpleNode.java:258)
        at ognl.Ognl.getValue(Ognl.java:494)
        at com.opensymphony.xwork2.ognl.OgnlUtil.getValue(OgnlUtil.java:217)
        at com.opensymphony.xwork2.ognl.OgnlValueStack.getValue(OgnlValueStack.java:342)
        at com.opensymphony.xwork2.ognl.OgnlValueStack.tryFindValue(OgnlValueStack.java:331)
        at com.opensymphony.xwork2.ognl.OgnlValueStack.tryFindValueWhenExpressionIsNotNull(OgnlValueStack.java:307)
        at com.opensymphony.xwork2.ognl.OgnlValueStack.findValue(OgnlValueStack.java:293)
        at org.apache.struts2.components.Component.findValue(Component.java:382)
        at org.apache.struts2.components.If.start(If.java:86)
        at org.apache.struts2.views.jsp.ComponentTagSupport.doStartTag(ComponentTagSupport.java:53)
        at org.apache.jsp.WEB_002dINF.views.layouts.header_jsp._jspx_meth_s_if_0(org.apache.jsp.WEB_002dINF.views.layouts.header_jsp:252)
        at org.apache.jsp.WEB_002dINF.views.layouts.header_jsp._jspService(org.apache.jsp.WEB_002dINF.views.layouts.header_jsp:97)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:109)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:389)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:486)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:380)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
        at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
        at org.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:192)
        at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:1013)
        at org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.java:698)
        at org.apache.tiles.jsp.context.JspTilesRequestContext.include(JspTilesRequestContext.java:80)
        at org.apache.tiles.jsp.context.JspTilesRequestContext.dispatch(JspTilesRequestContext.java:73)
        at org.apache.tiles.context.TilesRequestContextWrapper.dispatch(TilesRequestContextWrapper.java:72)
        at org.apache.struts2.tiles.StrutsTilesRequestContext.dispatch(StrutsTilesRequestContext.java:88)
        at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:283)
        at org.apache.tiles.jsp.taglib.InsertAttributeTag.render(InsertAttributeTag.java:140)
        at org.apache.tiles.jsp.taglib.InsertAttributeTag.render(InsertAttributeTag.java:117)
        at org.apache.tiles.jsp.taglib.RenderTagSupport.execute(RenderTagSupport.java:154)
        at org.apache.tiles.jsp.taglib.RoleSecurityTagSupport.doEndTag(RoleSecurityTagSupport.java:75)
        at org.apache.tiles.jsp.taglib.ContainerTagSupport.doEndTag(ContainerTagSupport.java:80)
        at org.apache.jsp.WEB_002dINF.views.layouts.bodyWithSidebar_jsp._jspx_meth_tiles_insertAttribute_0(org.apache.jsp.WEB_002dINF.views.layouts.bodyWithSidebar_jsp:121)
        at org.apache.jsp.WEB_002dINF.views.layouts.bodyWithSidebar_jsp._jspService(org.apache.jsp.WEB_002dINF.views.layouts.bodyWithSidebar_jsp:58)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:109)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:389)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:486)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:380)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
        at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
        at org.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:192)
        at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:1013)
        at org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.java:698)
        at org.apache.tiles.jsp.context.JspTilesRequestContext.include(JspTilesRequestContext.java:80)
        at org.apache.tiles.jsp.context.JspTilesRequestContext.dispatch(JspTilesRequestContext.java:73)
        at org.apache.tiles.context.TilesRequestContextWrapper.dispatch(TilesRequestContextWrapper.java:72)
        at org.apache.struts2.tiles.StrutsTilesRequestContext.dispatch(StrutsTilesRequestContext.java:88)
        at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:606)
        at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:280)
        at org.apache.tiles.jsp.taglib.InsertAttributeTag.render(InsertAttributeTag.java:140)
        at org.apache.tiles.jsp.taglib.InsertAttributeTag.render(InsertAttributeTag.java:117)
        at org.apache.tiles.jsp.taglib.RenderTagSupport.execute(RenderTagSupport.java:154)
        at org.apache.tiles.jsp.taglib.RoleSecurityTagSupport.doEndTag(RoleSecurityTagSupport.java:75)
        at org.apache.tiles.jsp.taglib.ContainerTagSupport.doEndTag(ContainerTagSupport.java:80)
        at org.apache.jsp.WEB_002dINF.views.layouts.main_jsp._jspx_meth_tiles_insertAttribute_0(org.apache.jsp.WEB_002dINF.views.layouts.main_jsp:473)
        at org.apache.jsp.WEB_002dINF.views.layouts.main_jsp._jspService(org.apache.jsp.WEB_002dINF.views.layouts.main_jsp:157)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:109)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:389)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:486)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:380)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
        at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
        at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:327)
        at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:126)
        at org.apache.tiles.servlet.context.ServletTilesRequestContext.forward(ServletTilesRequestContext.java:198)
        at org.apache.tiles.servlet.context.ServletTilesRequestContext.dispatch(ServletTilesRequestContext.java:179)
        at org.apache.tiles.context.TilesRequestContextWrapper.dispatch(TilesRequestContextWrapper.java:72)
        at org.apache.struts2.tiles.StrutsTilesRequestContext.dispatch(StrutsTilesRequestContext.java:88)
        at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:606)
        at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:246)
        at org.apache.struts2.views.tiles.TilesResult.doExecute(TilesResult.java:105)
        at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
        at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:373)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:277)
        at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:263)
        at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:270)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
        at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:498)
        at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
        at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378)
        at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
        at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
        at org.springframework.security.ui.SessionFixationProtectionFilter.doFilterHttp(SessionFixationProtectionFilter.java:67)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
        at org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(ExceptionTranslationFilter.java:101)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
        at org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
        at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:278)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
        at org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:89)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
        at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
        at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:175)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:236)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
        at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
        at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
        at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
        at org.mortbay.jetty.Server.handle(Server.java:326)
        at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:536)
        at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:915)
        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
        at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:405)
        at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
        at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

В FAQ по Spring Security я читал, что Controller/Action — не лучшее место для защиты методов, но описанный в FAQ сбой заключается в том, что аннотация @Secured не будет работать, т. е. метод не будет защищен.

В моем случае я получаю пустой стек значений даже до того, как достигну этого метода; execute() не защищен, только editUser(), и это еще даже не вызывалось.

Я надеюсь, что кто-то имеет такой же опыт и нашел решение .. спасибо.

Обновление: интересно, поможет ли это: Spring Security — как я могу включить аннотации Method Security?

Мои классы действий в настоящее время расширяют класс BaseAction, в который я добавляю общие функции.


person shaunlim    schedule 12.01.2012    source источник
comment
То есть вы говорите, что с ROLE_ADMIN все работало нормально, а теперь (с TEST_ADMIN) — нет?   -  person Matin Kh    schedule 04.08.2012
comment
Вы пытались удалить аннотацию или фильтр безопасности, чтобы убедиться, что проблема действительно связана с фильтром Spring Security, а не с чем-то еще? Кроме того, для пояснения, похоже, что переменная currentPage является null, а не самой ValueStack. Вы разместили весь код своего класса действий, но я предполагаю, что у вас действительно есть метод getCurrentPage()?   -  person rees    schedule 05.08.2012
comment
Было бы нечестно со стороны Spring Security потерпеть неудачу с NullPointerException, если бы он не смог найти метод получения для currentPage. Лучше потерпеть неудачу с PropertyNotFound или чем-то еще. Но я также не понимаю, почему вы пришли к выводу, что весь ValueStack равен нулю.   -  person Henrique Ordine    schedule 17.08.2012
comment
Вы поставили точку останова в методе Setter для currentPage, чтобы увидеть, вызывается ли он вообще?   -  person Henrique Ordine    schedule 17.08.2012


Ответы (4)


Мне просто интересно, эта проблема возникает, если вы используете конфигурацию Spring Security по умолчанию, где она ожидает имена с префиксом ROLE_.

См. этот вопрос: Как использовать пользовательские роли/полномочия в Spring Security?

Вы используете конфигурацию по умолчанию, ведь предполагается, что роли начинаются с префикса «ROLE_». Вам нужно будет добавить пользовательскую конфигурацию безопасности и установить для rolePrefix значение ""

Пример конфигурации из: Префикс роли безопасности Spring и Пользовательская служба сведений о пользователе

<beans:bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
    <beans:property name="rolePrefix" value="" />
</beans:bean>

Связанные вопросы:

person Marek Sebera    schedule 05.09.2012

Трассировка стека указывает на проблему в файле header.jsp, где есть проблема с тегом. Я подозреваю, что у вас просто проблема с нулевым указателем в выражении в теге. Можете ли вы поделиться фрагментом JSP header.jsp?

person blagerweij    schedule 27.10.2012

это не даст прямого ответа на ваш вопрос, но вам будет намного проще интегрироваться, если вы будете использовать контроллеры Spring 3 MVC с аннотациями и использовать соответствующую версию Spring Security. Это даст вам дополнительное преимущество, поскольку вы сможете быстрее разрабатывать его, отказаться от конфигурации XML для своих контроллеров, а переключение займет всего несколько минут. В зависимости от того, насколько далеко вы продвинулись в своей реализации, это может быть вариантом. Обычно аннотации Spring работают только тогда, когда они находятся в управляемых bean-компонентах Spring или когда вы вплетаете зависимости в классы, отличные от Spring, во время компиляции или выполнения.

person chrislhardin    schedule 22.10.2012

Я уже работал с таким проектом. Я использовал Struts 2, Spring 3.0.0 и Spring Security.

Я думаю, вы могли бы попытаться аннотировать действия Struts с помощью @org.springframework.stereotype.Controller... это текущий способ Spring управлять вашим действием Struts. Я думаю, что это решит проблему весенней безопасности, с которой вы столкнулись.

Я помню еще одну особенность этой архитектуры. В web.xml вы должны установить прослушиватели и фильтры spring перед фильтрами Struts 2. Я нашел свой старый проект, и мой web.xml был таким:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="starter" version="2.4" 
         xmlns="http://java.sun.com/xml/ns/j2ee" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>Onleague.com</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:META-INF/app-context.xml</param-value>
    </context-param>

    <!-- Spring -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>    
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>openSessionInViewFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>openSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- Struts 2 -->
    <filter>
        <filter-name>action2-cleanup</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>action2-cleanup</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
    <filter>
        <filter-name>action2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>action2</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

    <!-- Sitemesh -->    
    <filter>
        <filter-name>sitemesh</filter-name>
        <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>sitemesh</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

    <!-- Servlets -->
    <servlet>
        <servlet-name>dwr</servlet-name>
        <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>true</param-value>
        </init-param>
    </servlet>
    <servlet>
        <servlet-name>jspSupportServlet</servlet-name>
        <servlet-class>org.apache.struts2.views.JspSupportServlet</servlet-class>
        <load-on-startup>5</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dwr</servlet-name>
        <url-pattern>/dwr/*</url-pattern>
    </servlet-mapping>


    <!-- Welcome file lists -->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.jsp</welcome-file>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

</web-app>

Удачи!

person Marcio Barroso    schedule 01.11.2012