0

我在 WebSphere App Server v8.0.0.5 中使用 JSF 2.0、CDI 1.0。

我有一个奇怪的情况......成功登录后,会创建一个 CDI 会话范围的 bean,并将用户重定向到欢迎页面。会话范围的 bean 被注入到欢迎页面上引用的请求范围的 bean 中。问题是会话范围的 bean 仅在每个浏览器首次成功登录时保留其字段值。我已经尝试过使用 Chrome、Firefox 甚至 IE 的同一用户。如果我注销或重新启动 WAS 并尝试再次登录,则会话范围 bean 的值在注入请求范围 bean 时都设置为 null。

我对所有范围都使用 javax.enterprise.context。

拜托,我需要紧急帮助。由于这个问题,很多事情都处于危险之中。

登录表单的 Auth bean 的相关片段(我在重定向后省略了一些代码):

import com.ibm.websphere.security.WSSecurityException;
import com.ibm.websphere.security.auth.WSSubject;
import com.ibm.websphere.security.cred.WSCredential;
import com.ibm.websphere.wim.exception.WIMException;
import com.ibm.websphere.wim.util.SDOHelper;

import java.io.IOException;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.security.Principal;

import javax.annotation.PostConstruct;
import javax.enterprise.context.ConversationScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.security.auth.Subject;
import javax.security.auth.login.CredentialExpiredException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import com.ibm.websphere.wim.SchemaConstants;
import com.ibm.websphere.wim.Service;
import com.ibm.websphere.wim.client.LocalServiceProvider;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import com.ibm.ws.security.core.ContextManagerFactory;

import commonj.sdo.DataObject;

@Named
@ConversationScoped
public class Auth implements Serializable {
/**
 * 
 */
private static final long serialVersionUID = -6106803531512607236L;
private String userId;
private String password;
private String originalURL;

@Inject
UserService userService;
private Service service;
private String uniqueSecurityName;
private String l;

@PostConstruct
    public void init() {
    ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
    originalURL = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);

    System.out.println("The PostContstruct has been called.");

    if (originalURL == null) {
        originalURL = externalContext.getRequestContextPath() + "/index.xhtml";
    } else {
        String originalQuery = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_QUERY_STRING);

        if (originalQuery != null) {
            originalURL += "?" + originalQuery;
        }
    }
}

public void login() throws IOException, WIMException, PrivilegedActionException {
    FacesContext context = FacesContext.getCurrentInstance();
    ExternalContext externalContext = context.getExternalContext();
    HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
    System.out.println("The login method has been called.");

    try {
        Principal userPrincipal = request.getUserPrincipal();
        request.getUserPrincipal();
        if (userPrincipal != null) {
            request.logout();
        }
        request.login(userId, password);

        User user = new User();

        if (request.isUserInRole("STAFF")) {
            Staff staff = userService.getStaff(userId);
            user.setLocation(staff.getCenter().getCity());
            user.setRole("STAFF");
            user.setUserId(userId);
            externalContext.getSessionMap().put("user", user);
            externalContext.redirect("staff/staff-home?faces-redirect=true");
        }
}

public String logout() {
    FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
    return "/index?faces-redirect=true";
}  

用户 bean:

import java.io.Serializable;

import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@Named
@SessionScoped
public class User implements Serializable {
/**
 * 
 */
private static final long serialVersionUID = 7198980241243868166L;
private String role;
private String location;
private String userId;
private Role sessionRole;

public User() { }

/**
 * @return the role
 */
public String getRole() {
    return role;
}

/**
 * @param role the role to set
 */
public void setRole(String role) {
    this.role = role;
}

/**
 * @return the location
 */
public String getLocation() {
    return location;
}

/**
 * @param location the location to set
 */
public void setLocation(String location) {
    this.location = location;
}

/**
 * @return the userId
 */
public String getUserId() {
    return userId;
}

/**
 * @param userId the userId to set
 */
public void setUserId(String userId) {
    this.userId = userId;
}   
}

欢迎页面 bean 的相关部分:

import java.text.DateFormatSymbols;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;

@Named
@RequestScoped
public class CenterInfoBean {    
@Inject
CenterInfo centerInfo;

@Inject
User user;

private State state;
private Center center;

@PostConstruct
public void init() {
    center = centerInfo.getCenterByCityName(user.getLocation());
}

为什么 auth 仅在使用唯一浏览器初始登录时填充值,而在后续登录时从未填充值?

4

1 回答 1

0

将容器管理的 bean 代码与类似的东西混合不是一个好主意,

User user = new User();

在 sessionMap 中添加它应该可以工作,但是如果容器已经在您的请求 bean 中解决了会话 bean 的注入,因为您已经在会话中。

尝试避免像User user = new User();用户受容器管理时那样的代码。

在您的情况下,我建议检查用户是否已经在会话中。

User user = (User)externalContext.getSessionMap().get("user");

如果是,则更新此参考,如果不可用,则继续

User user = new User();
于 2013-03-07T06:40:25.287 回答