Обновление Spring Security 3 до 4 с помощью Primefaces 5.2 - PullRequest
0 голосов
/ 22 мая 2018

В настоящее время мы пытаемся обновить версию 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

1 Ответ

0 голосов
/ 28 июня 2018

Вам необходимо удалить префикс /WEB-INF/ из перенаправленного запроса на вход в систему:

final RequestDispatcher dispatcher = ((ServletRequest) context.getRequest())
            .getRequestDispatcher("/j_spring_security_check");

Кроме того, вы также должны использовать фактический URL-адрес формы входа, а не проверочный, в authenticationEntryPoint bean:

<bean id="authenticationEntryPoint" class= "o.s.s.w.authentication.LoginUrlAuthenticationEntryPoint">
    <constructor-arg value="/your-login-form-url"/>
</bean>

Кроме того, добавление дважды authenticationFilter в лучшем случае бесполезно, а в худшем - вредно.Удалите следующую строку:

<security:custom-filter before="FORM_LOGIN_FILTER" ref="authenticationFilter"/>
...