В настоящее время мы пытаемся обновить версию 3.2.10. RELEASE до 4.0.4. RELEASE.Мы следовали документации по миграции, описанной в docs.spring.io Но мы по-прежнему сталкиваемся с проблемами, и любые советы будут приветствоваться.
С рабочим конфигурационным файлом Spring-Security 3 security_config.xml
выглядитследующим образом:
<security:global-method-security pre-post-annotations="enabled">
<security:expression-handler ref="expressionHandler" />
</security:global-method-security>
<security:http auto-config='true' use-expressions="true" access-denied-page="/accessDenied.jsf">
<!-- HTTP Security headers -->
<security:headers>
<!-- FEW HEADERS ...-->
<security:hsts ... />
<security:xss-protection ... />
<security:frame-options ... />
</security:headers>
<!-- Is useless in most cases because the primefaces handler catches all
exceptions before they can reach the servlet filter installed by Spring: -->
<!-- <security:access-denied-handler ref="accessDeniedHandler" /> -->
<!-- Few intercept-url configs ...-->
<security:intercept-url ... />
...
<!-- Custom login page -->
<security:form-login login-page="..." default-target-url="..." authentication-failure-url="..." />
<security:logout logout-success-url="..." />
</security:http>
<security:authentication-manager>
<security:authentication-provider ref="authenticationProvider" />
</security:authentication-manager>
<bean id="expressionHandler"
class="*.security.MethodSecurityExpressionHandler">
</bean>
<bean id="sessionManagementFilter" class="o.s.s.w.session.SessionManagementFilter">
<constructor-arg name="securityContextRepository" ref="httpSessionSecurityContextRepository" />
<property name="invalidSessionStrategy" ref="jsfRedirectStrategy" />
</bean>
<bean id="jsfRedirectStrategy" class="*.JsfRedirectStrategy">
<property name="invalidSessionUrl" value="..." />
</bean>
<bean id="httpSessionSecurityContextRepository" class="o.s.s.w.context.HttpSessionSecurityContextRepository" />
<bean id="permissionEvaluator"
class="*.PermissionEvaluator" />
Перенесенная и все еще не работающая конфигурация для Spring-Security 4 выглядит следующим образом:
<security:global-method-security pre-post-annotations="enabled">
<security:expression-handler ref="expressionHandler" />
</security:global-method-security>
<security:http auto-config='true' use-expressions="true" disable-url-rewriting="false" entry-point-ref="authenticationEntryPoint"
>
<security:csrf disabled="true" />
<!-- HTTP Security headers -->
<security:headers defaults-disabled="true">
<!-- FEW HEADERS ...-->
<security:hsts ... />
<security:xss-protection ... />
<security:frame-options ... />
</security:headers>
<!-- Few intercept-url configs ...-->
<security:intercept-url ... />
...
<!-- Is useless in most cases because the primefaces handler catches all
exceptions before they can reach the servlet filter installed by Spring: -->
<!-- <security:access-denied-handler ref="accessDeniedHandler" /> -->
<!-- <security:access-denied-handler error-page="..."/> -->
<!-- Custom login page -->
<security:form-login login-page="..."
default-target-url="..."
authentication-failure-url="..."
username-parameter="j_username" // default of Spring 3
password-parameter="j_password" // default of Spring 3
login-processing-url="/j_spring_security_check" // default of Spring 3
/>
<security:logout logout-success-url="..."
logout-url="j_spring_security_logout"
/>
<security:custom-filter before="FORM_LOGIN_FILTER" ref="authenticationFilter"/>
</security:http>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="authenticationProvider" />
</security:authentication-manager>
<bean id="authenticationFilter" class="o.s.s.w.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="authenticationEntryPoint" class= "o.s.s.w.authentication.LoginUrlAuthenticationEntryPoint">
<constructor-arg value="/j_spring_security_check"/>
</bean>
<bean id="expressionHandler" class="*.MethodSecurityExpressionHandler" />
<bean id="sessionManagementFilter" class="o.s.s.w.session.SessionManagementFilter">
<constructor-arg name="securityContextRepository" ref="httpSessionSecurityContextRepository" />
<property name="invalidSessionStrategy" ref="jsfRedirectStrategy" />
</bean>
<bean id="jsfRedirectStrategy" class="*.JsfRedirectStrategy">
<property name="invalidSessionUrl" value="/login.jsf" />
</bean>
<bean id="httpSessionSecurityContextRepository" class="o.s.s.w.context.HttpSessionSecurityContextRepository" />
<bean id="permissionEvaluator" class="*.PermissionEvaluator" />
<bean id="accessDeniedHandler" class="*.AccessDeniedHandler" />
Primefaces Config:
<faces-config-extension>
<facelets-processing>
<file-extension>.xhtml</file-extension>
<process-as>html5</process-as>
</facelets-processing>
</faces-config-extension>
<!-- Settings for application -->
<application>
<!-- General application content messages -->
<!-- Resource Bundles ...-->
<resource-bundle>
...
<locale-config>
<default-locale>en</default-locale>
<supported-locale>en</supported-locale>
</locale-config>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
<!-- This el-resolver is used to resolve EL expressions involving pfExceptionHandler, as used in the error page error.jsf for example -->
<el-resolver>
o.p.a.exceptionhandler.PrimeExceptionHandlerELResolver
</el-resolver>
</application>
<!-- We use custom exception handlers in order to log spring security exceptions -->
<factory>
<exception-handler-factory>
*.ExceptionHandlerFactory
</exception-handler-factory>
</factory>
<converter>
<converter-for-class>java.lang.Enum</converter-for-class>
<converter-class>javax.faces.convert.EnumConverter</converter-class>
</converter>
<converter>
<converter-for-class>java.lang.String</converter-for-class>
<converter-class>*.StringNormalizer</converter-class>
</converter>
<navigation-rule>
<from-view-id>*</from-view-id>
<navigation-case>
<from-outcome>...</from-outcome>
<to-view-id>...</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>error</from-outcome>
<to-view-id>/error.jsf</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>...</from-outcome>
<to-view-id>...</to-view-id>
</navigation-case>
</navigation-rule>
<!-- Disable browser-side caching. The page is reloaded when pressing the
back button. -->
<lifecycle>
<phase-listener id="nocache">*.CacheControlPhaseListener</phase-listener>
<phase-listener>*.LoginController</phase-listener>
<phase-listener>o.s.web.jsf.DelegatingPhaseListenerMulticaster</phase-listener>
</lifecycle>
Описание ошибки:
Мы получаем NullPointerException
в нашем классе LoginController
.Это происходит, когда мы пытаемся получить текущий экземпляр FacesContext
.
final ExternalContext context = FacesContext.getCurrentInstance().getExternalContext(); // Here Works
final RequestDispatcher dispatcher = ((ServletRequest) context.getRequest())
.getRequestDispatcher("/WEB-INF/j_spring_security_check");
dispatcher.forward((ServletRequest) context.getRequest(), (ServletResponse) context.getResponse());
FacesContext.getCurrentInstance().responseComplete(); // NullPointerExeption