0

balusC の回答の 1 つから着想を得たコードで遊んでいます。基本的には、remember me cookie がある場合にユーザーのログインを試みる webfilter です。

ログインは、最初に userService-EJB から MyUser エンティティを取得し、それを @SessionScoped jsf-ManagedBean である MUserSessionBean に配置するように行われます。

問題は、最初の応答で、ユーザーがログインしていないように見えることです。

しかし、ログでは、ログインしていることがわかります。ブラウザでページの更新を要求するだけで、応答にはログインしているユーザーが表示されます。

ログイン後、いろいろなところにリダイレクトを入れようとしたのですが、試してみるとページレイアウトが崩れてしまいました..

最初の応答でログインしているユーザーを正常に表示するにはどうすればよいですか?

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
        ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    MUserSessionBean mUserSessionBean = (MUserSessionBean) request.getSession(true)
            .getAttribute("mUserSessionBean");

    if (mUserSessionBean != null && mUserSessionBean.getCurrentUser() == null) {

        String uuid = CookieUtil.getCookieValue(request, CookieUtil.COOKIE_NAME);

        if (uuid != null) {
            MyUser user = userService.findUserByUUID(uuid);

            if (user != null) {
                mUserSessionBean.setCurrentUser(user);
                CookieUtil.addCookie(response, CookieUtil.COOKIE_NAME, uuid, CookieUtil.COOKIE_AGE); 
            } else {
                CookieUtil.removeCookie(response, CookieUtil.COOKIE_NAME);
            }
        }
    }

    // pass the request along the filter chain
    chain.doFilter(req, res);
}
4

2 に答える 2

1

私が見ることができることから、あなたは実際に最初の周回でユーザーをログインさせていません。これまでに行っているのは、コンテナが実際にユーザーを認証せずに作成されたセッションに値を設定することだけです。

Remember-me機能では、remember-meトークンで取得した資格情報を使用して、ユーザーに代わってレルムに対して認証する必要があります。あなたはそれをしていません。ユーザーがログインしたように見えるページが更新されても、技術的にはそうではありません。ログインしているように見えるのは

     if (mUserSessionBean != null && mUserSessionBean.getCurrentUser() == null) 

ページが最初に要求された後に解決さtrueれ、すべてのチェックをスキップします。MyUser後続のリクエストは、インスタンスをセッションに強制的に配置したという理由だけで通過します。実際には、ユーザーはログインしておらず、これがアプリケーション内の他の場所で発生するページ分割の原因である可能性があります。

平和が支配するためには、レルムに対してユーザーを本当に認証する必要があります:)

    if (uuid != null) {
        MyUser user = userService.findUserByUUID(uuid);

        if (user != null) {
            request.login(user.username,user.password); //Authenticate!!!!
            mUserSessionBean.setCurrentUser(user);
            CookieUtil.addCookie(response, CookieUtil.COOKIE_NAME, uuid, CookieUtil.COOKIE_AGE); 
        } else {
            CookieUtil.removeCookie(response, CookieUtil.COOKIE_NAME);
        }
    }
于 2013-03-06T03:37:15.593 に答える
0

問題を解決するクイックフィックスを実行しました。ユーザーエンティティを SessionScoped ManagedBean に格納する代わりに、セッションに直接格納しました。したがって、フィルタ メソッドは次のようになります。

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
        ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    MyUser user = (MyUser) request.getSession(true).getAttribute("user");

    if (user == null) {

        String uuid = CookieUtil.getCookieValue(request, CookieUtil.COOKIE_NAME);

        if (uuid != null) {
            user = ub.findUserByUUID(uuid);

            if (user != null) {
                request.getSession().setAttribute("user", user);
                CookieUtil.addCookie(response, CookieUtil.COOKIE_NAME, uuid, CookieUtil.COOKIE_AGE);
            } else {
                CookieUtil.removeCookie(response, CookieUtil.COOKIE_NAME);
            }
        }
    }

    // pass the request along the filter chain
    chain.doFilter(req, res);
}

利点は、フィルタが ManagedBean の構築を待つ必要がないことです。次に、SessionScoped-Bean がセッションにピークを迎え、フィルターがそこに配置した可能性のあるエンティティをフェッチします。

@ManagedBean
@SessionScoped
public class MUserSessionBean {

    private MyUser currentUser;

    @PostConstruct
    public void init() {
        if (currentUser == null) {
            ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();

            currentUser = (MyUser) context.getSessionMap().get("user");
        }
    }
...
}

私は servlet-managed-authentication または Kollossus sugested と呼ばれるものを調べますが、差し迫った問題は少なくともなくなりました。

于 2013-03-06T17:55:40.883 に答える