集成Java EE 7,Spring Security和EclipseLink的问题

时间:2019-05-02 13:58:04

标签: jpa java-ee spring-security eclipselink

资深开发人员。希望您今天过得愉快。

我遇到了一个我不知道如何解决的问题,已经解决了一段时间。我正在尝试将Java EE 7,Spring Security和EclipseLink集成在一起,以对将在Payara服务器上托管的应用程序进行表单基础身份验证。

我将列出与当前实现相对应的工件:

  

pom.xml

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-bom</artifactId>
                <version>5.1.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>                
            </dependency>
        </dependencies>
</dependencyManagement>

<dependencies>
        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>eclipselink</artifactId>
            <version>2.5.2</version>
            <scope>provided</scope>
        </dependency>
<!--        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
            <version>2.5.2</version>
            <scope>provided</scope>
        </dependency>-->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
        </dependency>
</dependencies>

注意:正如您在pom.xml文件中看到的那样,我不得不注释掉EclipseLink的modelgen处理器,因为该项目将无法对其进行编译。因此,每当我进行反向工程以从数据库中生成实体时,都必须取消注释它,并再次对其进行注释以构建和运行应用程序。如果项目中还存在Spring Security,似乎CanonicalModelProcessor(用于生成类型安全的JPAQueries的EclipseLink的modelgen)会出现问题。我在StackOverflow上发现this,证明了这一点,因为另一个用户与我有相同的问题。

  

WebSecurityConfig.java

@Configuration
@EnableWebSecurity
@ComponentScan("com.myapp.testapp.security")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomAuthenticationProvider customAuthenticationProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/Views/**").hasAnyRole("ADMIN","USER")
                .anyRequest().fullyAuthenticated()
                .and()
                .formLogin()
                .and().exceptionHandling().accessDeniedPage("/Views/accesodenegado.xhtml");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.authenticationProvider(customAuthenticationProvider);
    }
}
  

CustomAuthenticationProvider.java

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Inject
    private UsuarioFacade usuarioFacade; 

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();

        System.out.println(password);

        boolean authenticationIsSuccessful = WsAutenticacion.login(username, password);

        if (authenticationIsSuccessful) {
            System.out.println("Authentication successful");

            Usuario usuario = usuarioFacade.obtenerUsuario(username);

            return new UsernamePasswordAuthenticationToken(username, password, usuario.authorities);
        }

        return null;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

}
  

UsuarioFacade.java

@Stateless
public class UsuarioFacade extends AbstractFacade<Usuario> {

    @PersistenceContext(unitName = "com.myapp.testapp_war_1.0PU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public UsuarioFacade() {
        super(Usuario.class);
    }

    public Usuario obtenerUsuario(String username) {
        String qlString = "SELECT u FROM Usuario u JOIN u.perfil p WHERE u.username = :username";
        Usuario usuario = (Usuario) getEntityManager().createQuery(qlString).setParameter("username", username).getSingleResult();

        return usuario;
    }

}

如您所见,我正在使用自定义AuthenticationProvider类,因为按照要求,必须通过将用户名和密码发送到SOAP服务来执行身份验证,SOAP服务返回的是true还是false,具体取决于主体和凭据是否存在于Active中。 Web服务每次使用此服务时都会查询的目录。由于权限未存储在Active Directory中,因此我需要查询具有特定用户权限的数据库---我正在使用EclipseLink进行此步骤。

我遇到的问题是我试图将Facade注入到自定义AuthorizationProvider中,并且应用程序崩溃并显示以下错误:

Severe:   Exception during cleanup after start failed
org.apache.catalina.LifecycleException: Manager has not yet been started
    at org.apache.catalina.session.StandardManager.stop(StandardManager.java:867)
    at org.apache.catalina.core.StandardContext.stop(StandardContext.java:5735)
    at com.sun.enterprise.web.WebModule.stop(WebModule.java:551)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:5552)
    at com.sun.enterprise.web.WebModule.start(WebModule.java:522)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:917)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:900)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:684)
    at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2057)
    at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1703)
    at com.sun.enterprise.web.WebApplication.start(WebApplication.java:107)
    at org.glassfish.internal.data.EngineRef.start(EngineRef.java:122)
    at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:291)
    at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:353)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:501)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:220)
    at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:487)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:360)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:360)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1722)
    at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:534)
    at com.sun.enterprise.v3.admin.AdminAdapter.onMissingResource(AdminAdapter.java:224)
    at org.glassfish.grizzly.http.server.StaticHttpHandlerBase.service(StaticHttpHandlerBase.java:189)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:466)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:169)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
    at java.lang.Thread.run(Thread.java:748)

Severe:   ContainerBase.addChild: start: 
org.apache.catalina.LifecycleException: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'customAuthenticationProvider'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customAuthenticationProvider': Unsatisfied dependency expressed through field 'usuarioFacade'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.myapp.testapp.facade.UsuarioFacade' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:5556)
    at com.sun.enterprise.web.WebModule.start(WebModule.java:522)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:917)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:900)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:684)
    at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2057)
    at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1703)
    at com.sun.enterprise.web.WebApplication.start(WebApplication.java:107)
    at org.glassfish.internal.data.EngineRef.start(EngineRef.java:122)
    at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:291)
    at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:353)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:501)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:220)
    at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:487)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:360)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:360)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1722)
    at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:534)
    at com.sun.enterprise.v3.admin.AdminAdapter.onMissingResource(AdminAdapter.java:224)
    at org.glassfish.grizzly.http.server.StaticHttpHandlerBase.service(StaticHttpHandlerBase.java:189)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:466)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:169)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'customAuthenticationProvider'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customAuthenticationProvider': Unsatisfied dependency expressed through field 'usuarioFacade'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.myapp.testapp.facade.UsuarioFacade' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:849)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:400)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:291)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
    at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:4965)
    at com.sun.enterprise.web.WebModule.contextListenerStart(WebModule.java:574)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:5534)
    ... 49 more
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customAuthenticationProvider': Unsatisfied dependency expressed through field 'usuarioFacade'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.myapp.testapp.facade.UsuarioFacade' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1247)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
    ... 67 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.myapp.testapp.facade.UsuarioFacade' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1654)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1213)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
    ... 80 more

我知道,如果删除注入的无状态EJB,则应用程序可以平稳运行,但是,我将无法为特定用户加载权限。你们中的任何人都可以教我如何通过将EclipseLink注入到我的自定义AuthenticationProvider中来利用EclipseLink来加载用户的权限,或者是否有其他方法可以加载这些权限?

在此先感谢您的答复。

1 个答案:

答案 0 :(得分:0)

我看到您正在混合Spring bean注释和CDI / EJB注释。该错误基本上表明没有可注入到CustomAuthenticationProvider中的类型为UsuarioFacade的bean。您确定将UsuarioFacade选作Bean / EJB吗?

由于是Spring进行注入,因此需要拾取EJB注释@Stateless。 Spring组件扫描的软件包中的这个无状态会话bean吗?

我还没有找到让spring使用此注释的示例,您确定Spring会使用它吗? 如果您的无状态bean扩展了AbstractStatelessSessionBean怎么办? 或者再尝试一次,如果使用春天的@Singleton注释来注释呢?