spring-security Spring Boot 3 Bean创建异常:创建名称为authorizationEndpoint的Bean时出错- ClassNotFoundException:javax.servlet.ServletException

66bbxpm5  于 2022-11-11  发布在  Spring
关注(0)|答案(3)|浏览(315)

我有一个尽可能简单的OAuth2 JWT Spring Boot 2.7.3 project,它很容易安装和运行,就像Github repository的自述文件中描述的那样。
除了Spring安全性之外,该项目还使用了spring-security-oauth2:

<dependency>
    <groupId>org.springframework.security.oauth.boot</groupId>
    <artifactId>spring-security-oauth2-autoconfigure</artifactId>
</dependency>

然后定义一些bean:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Value("${jwt.secret}")
    private String jwtSecret;

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter tokenConverter = new JwtAccessTokenConverter();
        tokenConverter.setSigningKey(jwtSecret);
        return tokenConverter;
    }

    @Bean
    public JwtTokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }
}

和授权服务器:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Value("${security.oauth2.client.client-id}")
    private String clientId;

    @Value("${security.oauth2.client.client-secret}")
    private String clientSecret;

    @Value("${jwt.duration}")
    private Integer jwtDuration;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private JwtAccessTokenConverter accessTokenConverter;

    @Autowired
    private JwtTokenStore tokenStore;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
        .withClient(clientId)
        .secret(passwordEncoder.encode(clientSecret))
        .scopes("read", "write")
        .authorizedGrantTypes("password")
        .accessTokenValiditySeconds(jwtDuration);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

        endpoints.authenticationManager(authenticationManager)
        .tokenStore(tokenStore)
        .accessTokenConverter(accessTokenConverter);
    }
}

和资源服务器:

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Value("${cors.origins}")
    private String corsOrigins;

    @Autowired
    private Environment env;

    @Autowired
    private JwtTokenStore tokenStore;

    private static final String[] PUBLIC = { "/oauth/token", "/h2-console/**" };

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(tokenStore);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {

        // H2
        if (Arrays.asList(env.getActiveProfiles()).contains("test")) {
            http.headers().frameOptions().disable();
        }

        http.authorizeRequests()
        .antMatchers(PUBLIC).permitAll()
        .anyRequest().authenticated();

        http.cors().configurationSource(corsConfigurationSource());
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {

        String[] origins = corsOrigins.split(",");

        CorsConfiguration corsConfig = new CorsConfiguration();
        corsConfig.setAllowedOriginPatterns(Arrays.asList(origins));
        corsConfig.setAllowedMethods(Arrays.asList("POST", "GET", "PUT", "DELETE", "PATCH"));
        corsConfig.setAllowCredentials(true);
        corsConfig.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfig);
        return source;
    }

    @Bean
    public FilterRegistrationBean<CorsFilter> corsFilter() {
        FilterRegistrationBean<CorsFilter> bean
                = new FilterRegistrationBean<>(new CorsFilter(corsConfigurationSource()));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }
}

现在我正在尝试upgrade it to Spring Boot 3.0.0-SNAPSHOT,但是项目抛出了BeanCreationException:创建名为“authorizationEndpoint”的Bean时出错。stack trace显示该错误是由ClassNotFoundException引起的:javax.servlet.ServletException.
如何解决这个问题?

vmdwslir

vmdwslir1#

问题是您使用的是不兼容的spring cloud版本(Hoxton.SR8)。它只与spring Boot 2.3.x和2.2.x兼容(请参阅https://spring.io/blog/2020/08/28/spring-cloud-hoxton-sr8-has-been-released)。您还需要升级spring cloud。
(Sping Boot 3使用了新的Jakarta API,因此jakarta.servlet.ServletException只能在您升级Spring boot之后才能使用并由maven下载。您的不兼容的Spring云版本需要旧的javax.servlet.ServletException类,但它已经不存在了。因此出现了ClassNotFoundException。)

km0tfn4u

km0tfn4u2#

依赖关系:

<dependency>
    <groupId>org.springframework.security.oauth.boot</groupId>
    <artifactId>spring-security-oauth2-autoconfigure</artifactId>
</dependency>

已在一段时间前达到其生命周期终止。因此,它将与Sping Boot 3不兼容。该项目已被OAuth2 support provided by Spring Security(客户端和资源服务器)和Spring Authorization Server取代。

ep6jt1vc

ep6jt1vc3#

当我第一次运行应用程序(转换为gradle)时,我遇到了异常java.lang.ClassNotFoundException: javax.servlet.Filter。添加了javax-servlet-api依赖项后,它就消失了。您是否也可以尝试添加下面的依赖项?

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

相关问题