java - Spring 安全奇怪的行为

标签 java spring-mvc spring-security

我正在使用 Spring Security 和 MongoDB 进行测试,因此我使用 MongoDB 构建了一个自定义 UserDetailService 并且它可以工作,但突然它开始抛出异常,我尝试解决问题但我无法解决,所以我将代码恢复为在实现自定义 UserDetailService 之前的先前状态,它再次开始工作,我重新实现了 UserDetailService 并发生了完全相同的事情,它只是停止工作,甚至没有更改任何内容,只需停止并重新启动 tomcat。

这是我的 web.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name />
<listener>
    <listener-class>
        org.springframework.web.context.request.RequestContextListener
    </listener-class>
</listener>
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>
<filter>
    <description>
        generated-spring-security-session-integration-filter
    </description>
    <filter-name>
        SpringSecuritySessionIntegrationFilter
    </filter-name>
    <filter-class>
        org.springframework.security.web.context.SecurityContextPersistenceFilter
    </filter-class>
</filter>
<filter>
    <description>generated-sitemesh-filter</description>
    <filter-name>Sitemesh Filter</filter-name>
    <filter-class>
        com.opensymphony.module.sitemesh.filter.PageFilter
    </filter-class>
</filter>
<filter>
    <description>generated-spring-security-filter</description>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>
        org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>
        SpringSecuritySessionIntegrationFilter
    </filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>Sitemesh Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
    <description>generated-servlet</description>
    <servlet-name>MongoSecurity Servlet</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:MongoSecurity-web-context.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet>
    <description>generated-resources-servlet</description>
    <servlet-name>Resource Servlet</servlet-name>
    <servlet-class>
        org.springframework.js.resource.ResourceServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Resource Servlet</servlet-name>
    <url-pattern>/resources/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>MongoSecurity Servlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

以及我遇到的异常:

java.lang.ClassCastException: org.springframework.security.web.firewall.FirewalledResponse cannot be cast to org.springframework.security.web.context.SaveContextOnUpdateOrErrorResponseWrapper
org.springframework.security.web.context.HttpSessionSecurityContextRepository.saveContext(HttpSessionSecurityContextRepository.java:99)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:139)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:65)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129)
com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)

这是我的 security-context.xml:

<http auto-config="true">
    <intercept-url pattern="/pages/login.jsp" />
    <intercept-url access="ROLE_ADMIN" pattern="/secure/**" />
    <form-login authentication-failure-url="/pages/login.jsp?login_error=true" login-page="/pages/login.jsp" />
<logout invalidate-session="true" logout-success-url="/pages/logout-redirect.jsp" />
    <remember-me key="formsRMKey" user-service-ref="userDetailsService" />
</http>
<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="userDetailsService">
        <password-encoder hash="sha" />
    </authentication-provider>
</authentication-manager>
<beans:bean id="userDetailsService" class="com.realestate.service.MongoUserDetailService" />

以及MongoUserDetailService的实现:

public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException {
    UserAccount user = userDao.findByUsername(username);
    if(user == null){
        return null;
    }
    return new User(user.getUsername(), user.getPassword(), true, true, true, true, getGrantedAuthorities(user.getRoles()));
}

public static List<SimpleGrantedAuthority> getGrantedAuthorities(List<Role> roles) {
    List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
    for (Role role : roles) {
        authorities.add(new SimpleGrantedAuthority(role.getName()));
    }
    return authorities;
}

任何帮助将不胜感激。

最佳答案

我遇到了类似的问题,从 web.xml 中删除 SecurityContextPersistenceFilter 解决了我的问题。 http-config 元素使用它自己的 SecurityContextPersistenceFilter 创建过滤器链,因此显式声明的过滤器会出现故障。 顺便说一句,您的 web.xml 中还存在其他一些 Spring Security 过滤器,因此您可能不仅需要删除此过滤器才能正常工作。 请引用Spring Security Core Filters Documentation获取有关默认注册的 Spring Security 过滤器的信息。

关于java - Spring 安全奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13153504/

相关文章:

java - 12 小时格式的时间验证

java - Spring - 使用 x-www-form-urlencoded 编码 POST 请求错误

REST Controller 中的 Spring Boot 绑定(bind)和验证错误处理

java - 在 Spring 中使用 ResponseBody 注释返回一个不工作的 Json

grails - 强制 Grails/Weblogic 仅使用 HTTPS 协议(protocol)重定向

java - 过滤器在注册为 Spring bean 时调用两次

spring-boot - 在 spring-boot 中禁用特定 url 的 Keycloak 身份验证

java - 在运行时识别子类

java - 更改 Netbeans 自动完成

java - 如何让扫描仪输入不触发第三种方法?