0

jsf2環境でログイン/ログアウトメカニズムを作成する正しい方法を知りたいです。ログイン xhtml フォームと、静的ブール (is_authenticated) を格納する管理 Bean を作成しました。true の場合、すべての xhtml ページでその変数をチェックしたいですか? continue 、それ以外の場合はログイン ページにリダイレクトします。

これは Admin.java Bean です。

@ManagedBean
@SessionScoped
public class Admin implements Serializable {
/**
 * 
 */
private static final long serialVersionUID = 1L;
static Boolean authenticated;
String username;
String password;

@PostConstruct
public void initialisation() {      // init bean on new instance
    Admin.authenticated = false;
}

public Boolean getAuthenticated(){
    return Admin.authenticated;
}

public String getUsername() {
    return username;
}
public void setUsername(String username) {
    this.username = username;
}
public String getPassword() {
    return password;
}
public void setPassword(String password) {
    this.password = password;
}

public String doLogout() {
    Admin.authenticated=false;  

    return "login?faces-redirect=true";
}

public String validity() {


    if(username.equals("admin") && password.equals("admin")) {
        Admin.authenticated=true;
        return "success";
    }   else   {
        Admin.authenticated=false;
        return "failure";
    }
}

}

これは main.xhtml です:

<?xml version="1.0" encoding="UTF-8" ?>
<ui:composition template="template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"      
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:define name="content">

<c:if test="#{admin.authenticated == false}">
// update Admin.authenticate to false
<meta http-equiv="refresh" content="0;URL=login.xhtml" />
</c:if>


<h1>Statistics</h1>
<div style="margin:10px">
<h:panelGrid columns="3">
Advertisers:
<h:outputText value="#{stats.advertisers}"/> 
<h:outputText value=""/>
Publishers:
<h:outputText value="#{stats.publishers}"/> 
<h:outputText value=""/>
Campaigns:
<h:outputText value="#{stats.campaigns}"/>
<h:outputText value="(#{stats.activeCampaigns} active)"/>
Banners:
<h:outputText value="#{stats.banners}"/>
<h:outputText value="(#{stats.activeBanners} active)"/>
Games:
<h:outputText value="#{stats.games}"/>
<h:outputText value="(#{stats.activeGames} active)"/>
</h:panelGrid>
</div>
</ui:define>
</ui:composition>

2 つの質問:

  1. jstl 'if' で、「com.pkg.name.Admin タイプでプロパティ 'authenticated' が見つかりません」

  2. Admin.authenticate を xhtml ファイルから false に更新するにはどうすればよいですか (不自由な質問で申し訳ありませんが、私は一般的に jsf と Web 開発に本当に慣れていません)

  3. この静的変数を使用するのは良い習慣ですか? (セッション変数のインスタンスのように)

4

1 に答える 1

1

私によると、ログイン/ログアウトを実装するための正しくてクリーンな方法は、フィルターを作成し、それを保護する必要がある URL (例: /admin/*) に適用することです。

ユーザーがログインに成功したら、セッション Bean に詳細をロードします。ユーザーが保護されたページを要求すると、フィルターが最初に実行されます。フィルターで、リクエストからセッションを取得し、その getAttribute メソッドを呼び出してセッション Bean を取得します (jsf は、セッション スコープの Bean をセッション属性として格納します)。Bean オブジェクトを取得した場合、彼はログインしていますが、null を取得した場合、彼は許可されておらず、ログインページにリダイレクトできます。

ログアウトの場合、セッションで無効化を呼び出すだけで、すべてのセッション スコープ属性が破棄されます。

実際の例は次のようになります。

ログイン情報を保存する SessionScoped Bean:

UserBean.java

    @ManagedBean
    @SessionScoped
    class UserBean implements Serializable{
    private User user;
    //getter/setter for user

  }

LoginBean.java

    @ManagedBean
    class LoginBean
    {
    @ManagedProperty(value="#{userBean}")
    private UserBean userBean;
    public UserBean getUserBean(){
    return userBean;
    }
    public void setUserBean(UserBean userBean){
    this.userBean=userBean;
    }
    private String username,password;
    //getter and setter for username,password
    public String checkLogin(){
   //check database for user
   if(user!=null){
   userBean.setUser(user);
   }
   //...
   }
   }

LoginFilter.java - このフィルターを URL パターンに適用します: /admin/*

@WebFilter("/admin/*")
    class LoginFilter implements Filter{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {    
       HttpSession session=((HttpServletRequest)request).getSession();
       userBean userBean=(userBean)session.getAttribute("userBean");
       if(userBean!=null){
       User user=userBean.getUser();
       if(user==null){
          ((HttpServletResponse)response).sendRedirect("login.jsf");
       }
       else
        chain.doFilter(request, response);
       }
       else
         ((HttpServletResponse)response).sendRedirect("login.jsf");
    }

    public void init(FilterConfig fc){}
    public void destroy(){}
}

login.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core">
    <h:head><title>Login To Admin Panel</title>
    </h:head>
    <h:body>
    <h:form>
    Username : <h:inputText value="#{loginBean.username}"/>
    Password : <h:inputSecret value="#{loginBean.password}"/>
    <h:commandButton value="Login" action="#{loginBean.checkLogin}" />
    </h:form>

    </h:body>
    </html>

ログアウトするには、session.invalidate() を呼び出すだけで、セッション スコープの属性とともにセッションが破棄されます。

この方法では、ユーザーがログインしているかどうかを判断するために、条件付きの jstl タグを記述する必要はありません。

お役に立てれば。

于 2012-08-28T16:28:15.780 に答える