0

我正在尝试在我的 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$1.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 代码,我知道它存在很多问题,请帮我解决它。回调处理程序:

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;
    }


}

司机:

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;
            }
        }

    }


}
4

1 回答 1

1

目前还不是 100% 清楚你到底想要做什么。“Java EE 桌面应用程序”是否意味着您正在尝试从客户端应用程序访问远程 EJB?

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

但是从某个地方开始,您在这里使用的是纯 JAAS 代码,但JAAS 并不是您可能认为的通用标准。并非每个应用程序服务器都在使用它。当他们这样做时,特别是这里的 JBoss/WildFly,他们的做法完全不同

具体来说,您在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 的情况下,它是第一个不是 Group 类型的主体,或者是CallerPrincipalgroup中的单个主体。

下一个大问题是您将所有 JAAS 人工制品 EJB 组件和 Principal 都设置为范围内的 CDI bean。这也行不通。如果服务器完全使用它自己的 JAAS 风格(记住甚至不是所有服务器都使用它),那么它总是通过普通类使用(没有 EE 组件注释)。入口点(引导程序)通常是通过LoginModule在服务器特定的 XML 文件中列出类来完成的。对于 JBoss/WildFly,这是standalone.xml.

请注意,对于 Java EE 8,我们正在尝试极大地简化设置和自定义安全性。通过这种方法,您确实可以使用 Java EE 组件 (CDI) 来实现各种人工制品。请参阅参考实现 Soteria,尤其是示例

于 2016-03-13T11:47:34.623 回答