:定位
如果用户在登录后尝试访问登录页面,则会将用户重定向到主页。
APPROACH
在过滤级别而不是在登录控制器中重定向用户。
系统详细信息
JSF
Spring security
UrlRewriteFilter
详情
基于此link我创建了一个类来访问spring security并询问用户是否已登录(不是匿名用户):
public class SecurityContextAccessorImpl implements SecurityContextAccessor {
@Autowired
private AuthenticationTrustResolver authenticationTrustResolver;
public SecurityContextAccessorImpl() {
}
@Override
public boolean isCurrentAuthenticationAnonymous() {
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return authenticationTrustResolver.isAnonymous(authentication);
}
}
然后我开发了一个过滤器,它使用以前的类来重定向用户:
@WebFilter
@Component
public class LoginFilter implements Filter {
@Autowired
private SecurityContextAccessor securityContextAccessor;
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if(securityContextAccessor != null){
if(securityContextAccessor.isCurrentAuthenticationAnonymous()){
String contextPath = ((HttpServletRequest)request).getContextPath();
((HttpServletResponse)response).sendRedirect(contextPath + "/ASSDA/home/home");
}
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
过滤器在spring和urlrewrite之后的web.xml中定义:
<!-- ============== Spring security ============= -->
<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>
<!-- ============== UrlRewriteFilter ============= -->
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ============== Login Filter ============= -->
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>es.assda.ged.web.controller.security.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/login.xhtml</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Bean在相应的applicationContext.xml中定义
<beans:bean id="defaultTargetUrl" class="java.lang.String">
<beans:constructor-arg value="/ASSDA/home/home" />
</beans:bean>
<beans:bean id="authenticationTrustResolver" name="authenticationTrustResolver" class="org.springframework.security.authentication.AuthenticationTrustResolverImpl" />
<bean id="securityContextAccessor" name="securityContextAccessor" class="es.assda.ged.api.security.SecurityContextAccessorImpl" />
当前行为
重定向功能正常并且达到了LoginFilter,但是没有初始化自动连接的securityContextAccessor变量。我认为它没有初始化,因为bean authenticationTrustResolver为null。
另一方面,如果我在登录控制器中声明自动变量securityContextAccessor,则会正确注入。
为什么securityContextACcessor在LoginFilter中为null并在登录控制器中正确实例化?
答案 0 :(得分:1)
看起来你没有通过Spring实例化你的Filter
,所以你没有得到依赖注入。它应该使用DelegatingFilterProxy:
的web.xml:
<filter>
<filter-name>springLoginFilter</filter-name><!-- Your filter bean in Spring -->
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
的applicationContext.xml:
<bean id="springLoginFilter" class="es.assda.ged.web.controller.security.LoginFilter" />