WFLYJPA0059:javax.persistence.PersistenceContext 注入目标无效。只允许 setter 方法:boolean secureConnect(String, String)

WFLYJPA0059: javax.persistence.PersistenceContext injection target is invalid. Only setter methods are allowed: boolean secureConnect(String, String)

我正在尝试在我的 Java EE 桌面应用程序(maven 项目)中实施 JAAS,并且我正在使用 Wildfly9 服务器。但是我遇到了这个问题:

Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: WFLYEE0041: Component class tn.esprit.jaas.EgovDriver for component EgovDriver has errors: 
WFLYJPA0059: javax.persistence.PersistenceContext injection target is invalid.  Only setter methods are allowed: boolean tn.esprit.jaas.EgovDriver.secureConnect(java.lang.String, java.lang.String)
    at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.handle(ModuleJndiBindingProcessor.java:158)
    at org.jboss.as.ee.component.ClassDescriptionTraversal.run(ClassDescriptionTraversal.java:54)
    at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.processClassConfigurations(ModuleJndiBindingProcessor.java:187)
    at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.deploy(ModuleJndiBindingProcessor.java:144)
    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:156)
    ... 5 more

这是我的JAAS代码,我知道它存在很多问题,请帮我修复它。 CallbackHundler:

package tn.esprit.jaas;

import java.io.IOException;

import javax.ejb.Stateless;
import javax.persistence.PersistenceContext;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

/**
 * Session Bean implementation class EgovCallbackHandler
 */

@Stateless
public class EgovCallbackHandler implements EgovCallbackHandlerRemote ,CallbackHandler {
@PersistenceContext(name="egovernment")
private static String[] details=null;
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

    System.out.println("EgovCallbackHandler");
    NameCallback nameCallback = (NameCallback) callbacks[0];
    System.out.println(nameCallback.getPrompt());
    nameCallback.setName(details[0]);
    PasswordCallback passwordCallback = (PasswordCallback) callbacks[1];
    System.out.println(passwordCallback.getPrompt());
    passwordCallback.setPassword(details[1].toCharArray());
}
@Override
public String[] enterDetailConnexion(String login, String password){
    details = new String[2];
    details[0]=login;
    details[1]=password;

    return details;
} 
}

登录模块:

import java.io.IOException;
import java.util.Map;

import javax.ejb.Stateless;
import javax.persistence.PersistenceContext;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

import tn.esprit.domain.Agent;
import tn.esprit.services.AgentGestion;

/**
 * Session Bean implementation class EgovLoginModule
 */
@Stateless
public class EgovLoginModule implements EgovLoginModuleRemote,LoginModule {
    @PersistenceContext(name="egovernment")
    public static final String[][] TEST_USERS = {{"u1","p1"},{"u2","p2"}};
    private Subject subject = null;
    private CallbackHandler callbackHandler = null;
    private EgovPrincipal egovPrincipal = null;
    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
            Map<String, ?> options) {
        this.subject=subject;
        this.callbackHandler=callbackHandler;
        System.out.println("initialize");

    }

    @Override
    public boolean login() throws LoginException {
        boolean flag=false;
        Agent agent=null;
        AgentGestion ag;
        System.out.println("login");
        Callback[] callbacksArray =new Callback[2];
        callbacksArray[0]=new NameCallback("Username: ");
        callbacksArray[1]=new PasswordCallback("Password: ",false);
        try {
            callbackHandler.handle(callbacksArray);
            String name =((NameCallback) callbacksArray[0]).getName();
            String password = new String (((PasswordCallback) callbacksArray[1]).getPassword());
            agent = new Agent();
            ag = new AgentGestion();
            agent = ag.Authentification(name, password);
            if (agent.getLogin().equals(name) && agent.getPwd().equals(password)){
                egovPrincipal = new EgovPrincipal(name);
                System.out.println("log succeess......");
                flag = true;

            }

            if(flag==false) throw new FailedLoginException("log fail............");
        } catch (IOException | UnsupportedCallbackException e) {

            e.printStackTrace();
        }
        return flag;
    }

    @Override
    public boolean commit() throws LoginException {
        boolean flag = false;
        System.out.println("coomit");
        if(subject != null && !subject.getPrincipals().contains(egovPrincipal)){
            subject.getPrincipals().add(egovPrincipal);
            flag=true;
        }
        return flag;
    }

    @Override
    public boolean abort() throws LoginException {
        if(subject !=null && egovPrincipal != null && subject.getPrincipals().contains(egovPrincipal))
            subject.getPrincipals().remove(egovPrincipal);

        subject = null;
        egovPrincipal = null;
        System.out.println("abort");
        return true;
    }

    @Override
    public boolean logout() throws LoginException {
        subject.getPrincipals().remove(egovPrincipal);
        subject=null;
        System.out.println("logout");
        return true;
    }


}

校长:

package tn.esprit.jaas;

import java.io.Serializable;
import java.security.Principal;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.PersistenceContext;



/**
 * Session Bean implementation class EgovPrincipal
 */
@Named
@RequestScoped
public class EgovPrincipal implements Principal, Serializable {
    @PersistenceContext(name="egovernment")
    private static final long serialVersionUID = 1L;
    @Inject
    private final String name;


     public EgovPrincipal(String name) {

        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public boolean equals(Object obj) {
        boolean flag = false;
        if(obj instanceof EgovPrincipal) 
            flag = name.equals(((EgovPrincipal)obj).getName());
        return flag;
    }


}

Driver:

package tn.esprit.jaas;

import javax.ejb.Stateless;
import javax.persistence.PersistenceContext;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

import tn.esprit.jaas.EgovCallbackHandler;

/**
 * Session Bean implementation class EgovDriver
 */
@Stateless
public class EgovDriver implements EgovDriverRemote {

    @PersistenceContext(name="egovernment")
public boolean secureConnect(String login, String password){
    boolean flag = false;
        EgovCallbackHandler ech = new EgovCallbackHandler();
        System.setProperty("java.security.auth.login.config", "jaas.configFile");
        LoginContext loginContext=null;
        while (true){

            try {
                ech.enterDetailConnexion(login, password);
                loginContext = new LoginContext("EgovJaas", new EgovCallbackHandler());
                loginContext.login();
                return flag = true;
                //while (flag) flag = egovDriver.performedAction(loginContext);
            } catch (LoginException  e) {
                System.out.println("++++++++" +e.getMessage());
                return flag;
            }
        }

    }


}

并不是 100% 清楚您到底想做什么。 "Java EE desktop application" 是否意味着您正在尝试从客户端应用程序访问远程 EJB?

无论如何,你的方法似乎有问题,而且从哪里开始有点困难。

但是从某个地方开始,您在这里使用的是纯 JAAS 代码,但是 JAAS is not the universal standard you may think it is. Not every application server is using it all. When they do, specifically JBoss/WildFly here, they all do it totally differently

具体来说,您在 LoginModule

public boolean commit() throws LoginException {
    boolean flag = false;
    if (subject != null && !subject.getPrincipals().contains(egovPrincipal)) {
        subject.getPrincipals().add(egovPrincipal);
        flag=true;
    }

    return flag;
}

我假设您认为 WildFly 会以某种方式知道 egovPrincipal 将变成 user principal(例如 HttpServletRequest#getUserPrincipal 返回的那个)。不幸的是,严格来说并非如此。如前所述,每个服务器在这里都有自己的方法。如果是 JBoss/WildFly,则为 the first principal that is not of type Group, or the single principal in the CallerPrincipal group

下一个大问题是您将所有 JAAS 工件 EJB 组件和 Principal 设为作用域 CDI bean。这也行不通。 IFF 一个服务器正在使用它自己的 JAAS 风格(并且记住甚至不是所有的服务器都使用它),那么它总是通过普通的 classes(没有 EE 组件注释)使用。入口点 (bootstrap) 通常是通过在特定于服务器的 XML 文件中列出 LoginModule class 来完成的。在 JBoss/WildFly 的情况下,这是 standalone.xml

请注意,对于 Java EE 8,我们正在努力大大简化设置和自定义安全性。通过这种方法,您确实可以使用 Java EE 组件 (CDI) 来实现各种工件。见 reference implementation Soteria, and specifically the examples.