0

我正在使用 JBoss 7.1.1、JSF2.0、EJB 3.1。

我试图在重新访问时自动登录用户。(不是完全登录,但至少我给了他他的自定义视图——我永远不会让他/她根据那个 cookie 标识调用金融交易)。

因此,我认为获取 JSF 阶段侦听器、检查先前设置的 cookie(包含 UUID)并自动登录该用户很容易。我很快注意到,我不能注射豆子。

嗯。好的。但是,您将如何建立自动登录?它肯定必须在每个请求都通过的地方——与请求的 URI 无关。

所以,我最初的方法是下面的代码——当然不起作用,因为所有注入的对象都设置为空。

1)知道如何做到这一点吗?
2)这看起来像一个昂贵的计算(考虑到每个请求都会通过这个阶段监听器)。一个更聪明的方式强加?

public class ReLoginPhaseListener implements PhaseListener {

private static final long serialVersionUID = 3690040902641689160L;
@Inject
private Logger log;

@Inject
private FacesContext ctx;

@Inject 
BeanManager beanMgr;

/**
 * The existing loginController (as a managed property since it's a managed
 * bean.)
 */
@ManagedProperty(value = "#{loginController}")
private LoginController loginController;

/*
 * Cannot inject a EJB here, because it it's not managed by the JSF engine.
 * @Inject UserRepository userRepository;
 */
@Override
public void afterPhase(PhaseEvent event) {
    // No need to implement
}

@Override
public void beforePhase(PhaseEvent event) {
    // check if is in session????
    FacesContext ctx = event.getFacesContext();
    Map<String, Object> cookies = ctx.getExternalContext().getRequestCookieMap();
    Cookie rmCookie = (Cookie) cookies.get("cCode");
    Cookie userCookie = (Cookie) cookies.get("userid");
    // Only go further if cCode exists
    if (rmCookie != null && userCookie != null) {
        Map<String, Object> sessionMap = ctx.getExternalContext().getSessionMap();
        User currentUser = (User) sessionMap.get("user");
        if (currentUser != null) {
            String rmKey = currentUser.getRememberMeKey();
            // If the remember key exists, then check if it corresponds to
            // the cookie code.
            if (rmKey != null && !rmKey.isEmpty()) {

            }
        } else {
            // Read from the database if there's a user with this id and
            // cCode.
            UserRepository userRep = getUserRepFacade();
            User user = userRep.findById(Long.parseLong(userCookie.getValue()));
            if (user.getRememberMeKey().equals(rmCookie.getValue()))
                loginController.setUser(user);
        }
    }
    // get request object and check if cookie is available. if corresponds
    // to the database, then do a restricted-log in.
}

@Override
public PhaseId getPhaseId() {
    // TODO Auto-generated method stub
    return PhaseId.RESTORE_VIEW;
}

public UserRepository getUserRepFacade() {      
    Bean<UserRepository> bean = (Bean<UserRepository>) beanMgr.getBeans(UserRepository.class)
            .iterator().next();
    CreationalContext<UserRepository> ctx = beanMgr.createCreationalContext(bean);
    UserRepository userRep = (UserRepository) beanMgr.getReference(bean, UserRepository.class, ctx);
    // this could be inlined, but intentionally left this way
    return userRep;
}

}

4

2 回答 2

1

为了使您的解决方案更加安全,请使用 AES-256 加密 cookie。(您可以将所有参数放在同一个 cookie 中)。这将防止对您的应用程序的暴力攻击:不允许攻击者猜测用户名。在您的情况下,您将打开其他页面并告知攻击者用户名。

于 2013-05-16T12:35:24.123 回答
0

这是一篇关于看似 CDI-PhaseListener 集成的文章:http ://planet.jboss.org/post/how_to_use_cdi_with_jsf_2_phaselisteners_explained

很好,尽管我仍然想知道在这个库出现之前这是如何做到的。

于 2013-05-15T06:18:02.447 回答