1

JBoss 7.1、MySQL/PostgreSQL DB、JSF 2.0 と CDI Bean を使用しています。

ログインとパスワードによるDBに基づく認証を実装する必要があります。管理(管理)ポータルがあります。クライアントがログインせずに制限されたページを開くと、クライアントがログインしていない場合、要求をlogin.*ページにリダイレクトする必要があります。

を使用してそれを実行しようとしましたPhaseListener。ログインとログアウトはできますが、別のページを開こうとすると問題が発生しました。クラス@Named("user") public class UserManager内で Bean を取得できません。PhaseListener、& EL ...を使用して取得しようとしましたがFacesContext、すべてが役に立ちませんでした。

UserManagerログインを検証し、ログインしているユーザーをcurrentプロパティとして保存します。PhaseListenerすべてのリクエストで、 if #{user.current}is notをチェックインしたいと思いnullます。しかし、私は#{user}豆を手に入れることができませんPhaseListener

@Namedまたは でBeanを取得するにはどうすればよいですbeforePhase()afterPhase()?


更新:これまでの私の試みは次のとおりです:

private boolean loggedIn( FacesContext context ) throws IOException, ServletException
{
    LOGSTORE.debug( "loggedIn().2 " );

    HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
    HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();

//  ELContext elContext = FacesContext.getCurrentInstance().getELContext();
//  UserManager userManager = (UserManager) FacesContext.getCurrentInstance().getApplication()
//      .getELResolver().getValue( elContext, null, "user" );

    HttpSession session = (HttpSession) context.getExternalContext().getSession( true );
    UserManager userManager = (UserManager) session.getAttribute( "user" );

//  UserManager userManager = (UserManager) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get( "user" );

    if (!StringUtils.contains( ((HttpServletRequest) context.getExternalContext().getRequest())
        .getRequestURL().toString(), URL_SESSION_EXPIRED ))
    {

        if (userManager == null || !userManager.isLoggedIn())
        {
            LOGSTORE.debug( " userManager is " + (userManager == null ? "" : "not ") + " null" );
            if (userManager != null)
            {
                LOGSTORE.debug( " userManager.isLoggedIn() is "
                    + (userManager.isLoggedIn() ? "TRUE" : "FALSE") );
            }
            LOGSTORE.debug( " doPhaseFilter() - START REDIRECT " );
            response.sendRedirect( request.getContextPath() + "/" + homepage + "?auth-failed" );
        }
        return false;

    } else
    {
        LOGSTORE.debug( "loggedIn().3 it is " + homepage );
        return true;
    }
}
4

4 に答える 4

7

セッションスコープのCDIマネージドBeanは、通常のセッションスコープのJSFマネージドBeanと同じようにHTTPセッションに保存されません。管理されているセッションスコープのJSFは、実際にBean名をキーとしてセッションに格納されます。ただし、セッションスコープのCDI管理対象Beanは、セッションスコープ内の別のマップを介してさらに抽象化されます。

ELをセッションマップから取得するのではなく、プログラムで評価して取得する必要があります。ELリゾルバーの試行に1つの間違いがあります。値に、式が含まれていません#{}

ELContext elContext = FacesContext.getCurrentInstance().getELContext();
UserManager userManager = (UserManager) FacesContext.getCurrentInstance().getApplication()
    .getELResolver().getValue(elContext, null, "user");

それに応じて修正します。

ELContext elContext = FacesContext.getCurrentInstance().getELContext();
UserManager userManager = (UserManager) FacesContext.getCurrentInstance().getApplication()
    .getELResolver().getValue(elContext, null, "#{user}");

ちなみに、上記の省略形はApplication#evaluateExpressionGet():です。

UserManager userManager = context.getApplication()
    .evaluateExpressionGet(context, "#{user}", UserManager.class);

FacesContext contextメソッド引数としてもすでに存在していることに注意してください。

于 2012-01-24T14:35:12.650 に答える
2

次のコードを使用して、 内から CDI Bean への参照を取得しますPhaseListener

public BeanManager getBeanManager() {
    BeanManager beanManager = null;
    try {
        InitialContext initialContext = new InitialContext();
        beanManager = (BeanManager) initialContext.lookup("java:comp/BeanManager");
    } catch (NamingException e) {
        logger.log(Level.SEVERE, "Couldn't get BeanManager through JNDI", e);
    }
    return beanManager;
}

public <T> T getBean(final Class<T> clazz) {
    BeanManager bm = getBeanManager();
    Bean<T> bean = (Bean<T>) bm.getBeans(clazz).iterator().next();
    CreationalContext<T> ctx = bm.createCreationalContext(bean);
    return (T) bm.getReference(bean, clazz, ctx);
}

したがって、Bean を取得するには、次のように呼び出します。

DataManager dataManager = getBean(DataManager.class);

この場合の@DependentBean は、 で使用されている BeanPhaseListenerです。

于 2012-12-20T19:56:39.500 に答える
0

うまくいけば、これは、このようなもののための実際のCDI統合を備えたJSFの次のバージョンで修正されます。実行する(そして移植性を維持する)必要があるのは、JNDIを介してBeanManagerを検索し、BeanManagerから名前付きBeanを取得することです。

于 2012-01-24T19:34:05.393 に答える
0

もう 1 つの可能性は、Seam Facesを使用することです。これは移植可能な CDI 拡張機能であり、faces イベントを監視できます。

于 2012-02-17T19:25:15.117 に答える