Apache Shiro不会在EJB应用程序中保留用户

时间:2015-01-28 17:27:15

标签: java-ee jpa ejb shiro

我试图在耳朵应用程序中使用apache shiro。我的想法是在ejb后端使用shiro,然后为战争前端提供服务,因为我希望在后端管理所有与权限相关的内容。

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

}

AutUsuarioServices是一个@Stateless bean,它使用JPA加载和保存用户,因此没有任何谜。 在我的ejb中,我有一个ejb,在我的想法中,必须管理所有与用户相关的东西:

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

}

最后,在我的战争中,我有一个使用UserServices的UserBean,这个烘焙bean在登录页面和工作中使用:

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

}

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

我已经阅读了很多示例和文档,但我感到迷茫。我想知道我的方法是否正确......

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

谢谢

0 个答案:

没有答案