spring security 动态管理IP(hasIpAddress)限制爆出异常UnsupportedOperationException

本文探讨了在使用 Spring Security 的情况下出现 java.lang.UnsupportedOperationException 的原因及解决方法。该问题通常发生在使用 springsecurity 标签时,由于 DefaultWebInvocationPrivilegeEvaluator 的限制导致。
org.apache.jasper.JasperException: java.lang.UnsupportedOperationException
	org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:541)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:435)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343)
	org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:99)
	org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
	org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:119)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:109)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
	org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
	org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
	com.mawujun.util.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:124)

root cause

java.lang.UnsupportedOperationException
	org.springframework.security.web.access.DummyRequest.getRemoteAddr(DefaultWebInvocationPrivilegeEvaluator.java:359)
	org.springframework.security.web.util.IpAddressMatcher.matches(IpAddressMatcher.java:40)
	org.springframework.security.web.access.expression.WebSecurityExpressionRoot.hasIpAddress(WebSecurityExpressionRoot.java:33)
	sun.reflect.GeneratedMethodAccessor35.invoke(Unknown Source)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	java.lang.reflect.Method.invoke(Method.java:597)
	org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:58)
	org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:76)
	org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:102)
	org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:97)
	org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:11)
	com.mawujun.util.security.CustomWebExpressionVoter.vote(CustomWebExpressionVoter.java:49)
	org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:50)
	org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator.isAllowed(DefaultWebInvocationPrivilegeEvaluator.java:137)
	org.springframework.security.taglibs.authz.AuthorizeTag.authorizeUsingUrlCheck(AuthorizeTag.java:78)
	org.springframework.security.taglibs.authz.AuthorizeTag.doStartTag(AuthorizeTag.java:50)
	org.apache.jsp.permission.accountManager_jsp._jspx_meth_sec_005fauthorize_005f0(accountManager_jsp.java:1049)
	org.apache.jsp.permission.accountManager_jsp._jspService(accountManager_jsp.java:321)
	org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:393)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343)
	org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:99)
	org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
	org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:119)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:109)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
	org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
	org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
	org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
	com.mawujun.util.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:124)

 

 

原因:是因为在页面上使用了spring security的标签,该标签使用DefaultWebInvocationPrivilegeEvaluator进行判断,要在自己定义的CustomWebExpressionVoter排除这种情况

Spring WebFlux 中自定义 `HttpClient` 时,若配置不当或依赖版本冲突,可能会导致 `UnsupportedOperationException` 异常。为了避免此类问题,需要确保使用的 `HttpClient` 实例构建方式与当前项目的依赖版本兼容,并遵循正确的使用模式。 首先,在创建 `HttpClient` 时应使用 `HttpClient.create()` 方法,并结合 `Reactor Netty` 提供的 API 来进行配置。例如: ```java @Bean public HttpClient httpClient() { return HttpClient.create() .secure(ssl -> ssl.sslContext(...)) // 确保 SSL 上下文正确 .proxy(proxySpec -> proxySpec.type(ProxyProvider.ProxyType.HTTP).host("example.com").port(8080)); } ``` 此配置方式允许对连接池、SSL 设置、代理等进行细粒度控制[^1]。然而,如果项目中存在多个不同版本的 `Reactor Netty` 或 `Netty` 库,则可能因类路径冲突而导致初始化失败。为避免这种情况,应在 `pom.xml` 或 `build.gradle` 文件中显式声明 `Reactor Netty` 的版本,并排除其他不兼容的依赖项。 其次,Spring Boot 2.x 及其后续版本默认使用 Reactor Netty 作为底层 HTTP 客户端实现。因此,应确保所选版本与 Spring Boot 主版本保持一致。例如,Spring Boot 2.6.x 推荐使用 Reactor Netty 1.0.x 版本: ```xml <dependency> <groupId>io.projectreactor.netty</groupId> <artifactId>reactor-netty-http</artifactId> <version>1.0.17</version> </dependency> ``` 此外,若项目中包含 Spring Cloud Gateway 或 FeignClient 等组件,也需注意它们与 Spring Boot 和 Reactor Netty 的兼容性关系。例如,FeignClient 在某些版本中可能隐式引入旧版 Netty 组件,从而干扰 WebFlux 的正常运行 [^1]。 最后,启用调试日志有助于进一步诊断 `HttpClient` 初始化过程中的异常来源: ```yaml logging: level: reactor.netty: DEBUG org.springframework.web.reactive.function.client: DEBUG ``` 通过以上方法,可以有效规避 `UnsupportedOperationException`,并在 Spring WebFlux 中安全地自定义 `HttpClient` 实例。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值