Jakarta ee ApacheShiro在EJB应用程序中不保留用户

Jakarta ee ApacheShiro在EJB应用程序中不保留用户,jakarta-ee,jpa,ejb,shiro,Jakarta Ee,Jpa,Ejb,Shiro,我正在尝试在ear应用程序中使用ApacheShiro。我的想法是在ejb后端使用shiro,然后向war前端提供服务,因为我希望在后端管理所有与权限相关的内容 为了进行身份验证,我正在使用JpaRealm类: public class JpaRealm extends AuthorizingRealm { private static final Logger LOG = Logger.getLogger(JpaRealm.class.getName()); private stat

我正在尝试在ear应用程序中使用ApacheShiro。我的想法是在ejb后端使用shiro,然后向war前端提供服务,因为我希望在后端管理所有与权限相关的内容

为了进行身份验证,我正在使用JpaRealm类:

public class JpaRealm extends AuthorizingRealm {
  private static final Logger LOG = Logger.getLogger(JpaRealm.class.getName());

  private static final String AUT_USUARIO_EJB = "java:global/Engine/Engine-ejb/AutUsuarioServices";
  private AutUsuarioServices autUsuarioServices;

  protected void lookup() {
    try {
      this.autUsuarioServices = (AutUsuarioServices) new InitialContext().lookup(AUT_USUARIO_EJB);
    } catch (NamingException ex) {
      LOG.log(Level.SEVERE, null, ex);
    }
  }  

  public JpaRealm() {
    setName("JpaRealm"); 
  }

  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
    try {
      this.lookup();
      UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
      AutUsuario usuario = autUsuarioServices.cargarUsuario(token.getUsername());
      if (usuario != null) {
        return new SimpleAuthenticationInfo(usuario.getIdUsuario(), usuario.getContrasena(), this.getName());
      } else {
        return null;
      }
    } catch (Exception ex) {
      LOG.log(Level.SEVERE, null, ex);
      return null;      
    }
  }

  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    try {
      this.lookup();      
      Integer id = (Integer) principals.fromRealm(getName()).iterator().next();
      AutUsuario usuario = autUsuarioServices.cargarUsuario(id);
      if (usuario != null) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        for (AutRol rol : usuario.getAutRolCollection()) {
          info.addRole(rol.getNombre());
          ArrayList<String> permisos = new ArrayList<>();
          for (AutPermiso permiso : rol.getAutPermisoCollection()) {
            permisos.add(permiso.getPermiso());
          }
          info.addStringPermissions(permisos);
        }
        return info;          
      } else {
        return null;
      }
    } catch (Exception ex) {
      LOG.log(Level.SEVERE, null, ex);
      return null;
    }
  }

}
当我调用login方法时,它工作正常,使用ign jpa从数据库等调用用户数据,并且我有一个正确登录的用户:随后调用UserServices.login告诉我该用户已经登录。 无论如何,如果我把{userBean.username}放在任何其他页面中,我总是会得到null subject.getPrincipal和false subject.isAuthenticated

我读了很多例子和文档,但我觉得很失落。我想知道我的方法是否正确

我很欣赏在ejb后端使用shiro的示例的建议和指针

多谢各位

@Stateless
@LocalBean
public class UserServices implements UserServicesRemote {
  private static final Logger LOG = Logger.getLogger(UserServices.class.getName());

  private SecurityManager securityManager;  
  private String username;

  @PostConstruct
  public void init() {
    LOG.log(Level.INFO, "*** UserServices:PostConstruct");
    Factory<SecurityManager> factory = new IniSecurityManagerFactory("/opt/shiro.ini");
    this.securityManager = factory.getInstance();
    SecurityUtils.setSecurityManager(securityManager);
  }

  @Override
  public boolean login(String login, String contrasena) {
    Subject subject = SecurityUtils.getSubject();
    if (subject.isAuthenticated()) {
      return true;
    } else {
      this.username = null;
      UsernamePasswordToken token = new UsernamePasswordToken(login, contrasena);
      token.setRememberMe(true);
      try {
        subject.login(token);
        this.username = login;
        return true;
      } catch (Exception e) {
      }
    }
    return false;
  }

  @Override
  public String getUsuario() {
    Subject subject = SecurityUtils.getSubject();
    return "[" + subject.getPrincipal() + " " + subject.isAuthenticated() + "]" + this.username;
  }

}
@Named
@SessionScoped
public class UserBean implements Serializable {
  private static final Logger LOG = Logger.getLogger(UserBean.class.getName());

  private String loginFormUser;
  private String loginFormPass;

  @EJB
  private UserServicesRemote userServices;

  public String getLoginFormUser() {
    return loginFormUser;
  }

  public void setLoginFormUser(String loginFormUser) {
    this.loginFormUser = loginFormUser;
  }

  public String getLoginFormPass() {
    return loginFormPass;
  }

  public void setLoginFormPass(String loginFormPass) {
    this.loginFormPass = loginFormPass;
  }

  public String getUsername() {
    return userServices.getUsuario();
  }

  public String login() {
    LOG.log(Level.INFO,"*** login "+loginFormUser+" "+loginFormPass);
    userServices.login(this.loginFormUser, this.loginFormPass);
    // @TODO
    return "ok";
  }

}