Spring Security - SecurityContext.authentication null em taglib e jsp, mas ok no controlador
-
21-09-2019 - |
Pergunta
Estou lutando com esse problema há um tempo agora. Encontrei várias postagens sobre isso, mas nenhuma resolveu meu problema. Provavelmente terá algo a ver com o fato de que um SecurityContext é um tópico específico, mas mesmo assim eu não sei como resolvê -lo:
Considere seguir o código para recuperar o usuário que foi conectado:
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
Executando esse código em um controlador retornaria (corretamente), o usuário está conectado. A execução deste código de um taglib ou JSP lança NPE (autenticação = null). Também a tag de primavera não funciona (presumivelmente pelo mesmo motivo).
Extract de web.xml:
<filter>
<filter-name>AcegiFilter</filter-name>
<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>org.acegisecurity.util.FilterChainProxy</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>AcegiFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Extrair do arquivo de configuração de segurança da primavera:
<bean id="filterChainProxy" class="org.springframework.security.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionIntegrationFilter,authenticationProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor
</value>
</property>
</bean>
<bean id="filterSecurityInterceptor"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
<property name="alwaysReauthenticate" value="true" />
<property name="objectDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/myaccount.htm=ROLE_CUSTOMER
</value>
</property>
</bean>
Solução
RESOLVIDO
O problema surgiu da sequência do filtro. O PageFilter (Sitemesh) foi invocado antes do filtro de segurança da primavera e, por isso, o contexto de segurança ainda não estava disponível no JSP. Alterar a ordem dos filtros no web.xml (filtro de segurança primeiro) corrigiu o problema.
Outras dicas
Isso pode parecer uma pergunta óbvia, mas você forçou o usuário a fazer login (ou seja, autenticar) a qualquer momento antes de acessar a página /myaccount.htm? Não vi nenhum mapeamento para uma página de login exigindo acesso anônimo em sua fonte de definição de objeto, e é por isso que peço. Se o usuário puder acessar /myaccount.htm sem autenticação, nenhum principal teria sido criado no contexto de segurança quando eles tenham acessado a página, daí a sua nullpointerException. Além disso, você está usando a autenticação baseada em formulário? Autenticação básica HTTP? Algum outro tipo suportado por ACEGI?