@EnableResourceServer 不适用于 spring-webflux

Posted

技术标签:

【中文标题】@EnableResourceServer 不适用于 spring-webflux【英文标题】:@EnableResourceServer not working with spring-webflux 【发布时间】:2018-08-16 01:47:09 【问题描述】:

我在http://start.spring.io 创建了一个应用程序,指定了“Reactive Web”和“Security”。然后我构建并运行了应用程序,没有任何问题。

然后我将 spring-security-oauth2-autoconfigure 依赖项添加到我的 pom 中,并将 @EnableResourceServer 添加到我的应用程序类中。我现在看到一个异常,因为即使我的应用程序不是基于 servlet 的,也在寻找 javax.servlet.Filter

这是我看到的例外情况:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration': Post-processing of merged bean definition failed; nested exception is java.lang.TypeNotPresentException: Type javax.servlet.Filter not present
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:61) ~[spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at com.example.demo.DemoApplication.main(DemoApplication.java:12) [classes/:na]
Caused by: java.lang.TypeNotPresentException: Type javax.servlet.Filter not present
    at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:117) ~[na:1.8.0_161]
    at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125) ~[na:1.8.0_161]
    at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49) ~[na:1.8.0_161]
    at sun.reflect.generics.visitor.Reifier.reifyTypeArguments(Reifier.java:68) ~[na:1.8.0_161]
    at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:138) ~[na:1.8.0_161]
    at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49) ~[na:1.8.0_161]
    at sun.reflect.generics.repository.ClassRepository.getSuperInterfaces(ClassRepository.java:108) ~[na:1.8.0_161]
    at java.lang.Class.getGenericInterfaces(Class.java:913) ~[na:1.8.0_161]
    at org.springframework.core.ResolvableType.getInterfaces(ResolvableType.java:471) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.core.ResolvableType.as(ResolvableType.java:436) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.core.ResolvableType.as(ResolvableType.java:437) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.core.ResolvableType.as(ResolvableType.java:442) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.core.ResolvableType.as(ResolvableType.java:442) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.core.ResolvableType.forMethodParameter(ResolvableType.java:1283) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.core.ResolvableType.forMethodParameter(ResolvableType.java:1250) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.core.ResolvableType.forMethodParameter(ResolvableType.java:1240) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.core.BridgeMethodResolver.isResolvedTypeMatch(BridgeMethodResolver.java:154) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.core.BridgeMethodResolver.isBridgeMethodFor(BridgeMethodResolver.java:138) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.core.BridgeMethodResolver.searchCandidates(BridgeMethodResolver.java:117) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.core.BridgeMethodResolver.findBridgedMethod(BridgeMethodResolver.java:79) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.lambda$buildResourceMetadata$1(CommonAnnotationBeanPostProcessor.java:379) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.util.ReflectionUtils.doWithLocalMethods(ReflectionUtils.java:522) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.buildResourceMetadata(CommonAnnotationBeanPostProcessor.java:378) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.findResourceMetadata(CommonAnnotationBeanPostProcessor.java:339) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(CommonAnnotationBeanPostProcessor.java:298) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:1016) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    ... 15 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.servlet.Filter
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_161]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_161]
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338) ~[na:1.8.0_161]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_161]
    at java.lang.Class.forName0(Native Method) ~[na:1.8.0_161]
    at java.lang.Class.forName(Class.java:348) ~[na:1.8.0_161]
    at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114) ~[na:1.8.0_161]
    ... 41 common frames omitted

这是我的 pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

这是我的应用程序类:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;

@SpringBootApplication
@EnableResourceServer
public class DemoApplication 

    public static void main(String[] args) 
        SpringApplication.run(DemoApplication.class, args);
    

【问题讨论】:

你解决了这个问题吗? 还没开始。下面是创建资源服务器的 webflux 方式:docs.spring.io/spring-security/site/docs/current/reference/html/… 【参考方案1】:

spring-security-oauth2 项目目前严重依赖 Spring MVC 和 Servlet API。我不认为这个项目已经支持 Spring WebFlux。

你可以reach out to the project team on their issue tracker。

【讨论】:

以上是关于@EnableResourceServer 不适用于 spring-webflux的主要内容,如果未能解决你的问题,请参考以下文章

Spring security 的 @EnableWebSecurity 与 oauth 的 @EnableResourceServer

使用 @EnableResourceServer 支持 Spring Boot 反应式 (webflux)

@EnableResourceServer 不适用于 spring-webflux

EnableResourceServer 中断 oAuth2 授权服务器

@EnableOAuth2Sso 和 @EnableResourceServer 在同一个应用程序中

Spring OAuth @EnableResourceServer 阻止来自 OAuth 服务器的登录页面