如何设计无会话的JSF 2.0 Web应用程序? [英] How to design a session-less JSF 2.0 web application?

查看:135
本文介绍了如何设计无会话的JSF 2.0 Web应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在JSF 2.0网站上工作.该网站有两种用户(公共用户和注册用户).现在,我想知道如何为两种用户创建会话?对于注册用户,当我的用户登录时,应该有一个会话,而当会话过期时,我会将其重定向到您的会话已过期的页面.对于公共用户,根本不应该进行任何会话.意味着我的公共用户没有会话超时,他们永远不会收到有关您的会话已过期的消息.如何在JSF 2.0中实现此行为.

I am working on a JSF 2.0 website. The website has two kind of users(public and registered). Now I want to know that how can I create session for both kind of users? For registered users, when my user is login then there should be session for it, and when session expires then I redirect it to page that your session has expired. For public users there should be no session at all. Means there is no session time out for my public users and they never have messages that your session has expired. How can I implement this behavior in JSF 2.0.

我可以使用过滤器还是有更好的方法?我还读到JSF使用托管bean自动创建会话.我可以将这些会话用于我的任务吗?

Can I use filter for it or there is better approach for it? I also read that JSF automatically creates session using managed beans. Can I use these sessions for my task?

我告诉你我做了什么,以便大家更好地在这个场景中引导我

I tell you what i did so you people better guide me in this scenerio

我所做的就是像这样在我的网络应用程序中放置一个过滤器

What i did i put a filter in my web app like this

<filter>
    <filter-name>SessionTimeoutFilter</filter-name>
    <filter-class>util.SessionTimeoutFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SessionTimeoutFilter</filter-name>
    <url-pattern>*.xhtml</url-pattern>
</filter-mapping>

这是我的过滤器代码

public class SessionTimeoutFilter implements Filter {

    // This should be your default Home or Login page
    // "login.seam" if you use Jboss Seam otherwise "login.jsf"   
    // "login.xhtml" or whatever
    private String timeoutPage = "faces/SessionExpire.xhtml";
    private String welcomePage = "faces/index.xhtml";
    public static Boolean expirePage = false;
    private FilterConfig fc;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        this.fc = filterConfig;

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,   FilterChain filterChain)
        throws IOException, ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        HttpSession session = httpServletRequest.getSession();

        /**
         * The session objects have a built-in data structure (a hash table) in which you can store
         * any number of keys and associated values. You use session.getAttribute("key") to look up
         * a previously stored value. The return type is Object, so you must do a typecast to
         * whatever more specific type of data was associated with that attribute name in the session.
         * The return value is null if there is no such attribute, so you need to check for null
         * before calling methods on objects associated with sessions.
         *
         * Note:
         *     JSF session scoped managed beans are under the covers stored as a HttpSession
         *     attribute with the managed bean name as key.
         */
        Login login = (Login)session.getAttribute("login");

        if (login == null) {  // No such object already in session

            filterChain.doFilter(request, response);

        } else {

            /**
             * If you use a RequestDispatcher, the target servlet/JSP receives the same
             * request/response objects as the original servlet/JSP. Therefore, you can pass
             * data between them using request.setAttribute(). With a sendRedirect(), it is a
             * new request from the client, and the only way to pass data is through the session or
             * with web parameters (url?name=value).
             */
            filterChain.doFilter(request, response);

        }

        System.out.println();

    } //end of doFilter()

    @Override
    public void destroy() {

    } //end of destroy()

现在,如果您第一次输入我的网站的网址,然后调用此过滤器,将会发生什么情况.它得到

Now what happen that if you first time enter url of my site then this filter invoke. It gets

Login login = (Login)session.getAttribute("login");

为空.因此,它只是移至我的index.xhtml页面.现在,我的index.html页面构造函数被调用.这是我的代码

null. So it simply move to my index.xhtml page. Now my index.html page constructor invokes. Here is my code

@ManagedBean
//////@RequestScoped
@SessionScoped
public class Login implements Serializable {

    //Constructor
    public Login() {

        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext externalContext = facesContext.getExternalContext();

        //getSession(false), which returns null if no session already exists for the current client.
        HttpSession session =(HttpSession)externalContext.getSession(false);

        if (session == null) {

            System.out.println();

        } else {

            session.setAttribute("logedin", 0);     //public user
            session.setMaxInactiveInterval(-1);     // no session time out

            Enumeration e = session.getAttributeNames();

            while (e.hasMoreElements()) {

                /**
                 * Here you also get "login" attr. Because when managed bean create the
                 * session, it sets you managedBean name in the session attribute.
                 */
                String attr = (String)e.nextElement();
                System.err.println("attr  = "+ attr);
                Object value = session.getAttribute(attr);
                System.err.println("value = "+ value);

            } //end of while

        }

    }//end of constructor

} //end of class Login

当第一次用户进入我的站点时,它没有登录,因此我将登录会话属性设置为0.现在假设用户输入凭据,然后按登录按钮.首先,我的过滤器被调用,但是这次它将获得登录属性,并进入我的doFilter(),否则进行检查,然后进入我的validUser()方法.这是我的代码

when first time user come to my site then it is not login so i set logedin session attribute 0. Now suppose user enter credentials and press log in button. First my filter is invoke but this time it will get login attribute and comes to my doFilter() else check and then come to My validUser() method. Here is my code

public String validUser() throws Exception {

    ArrayList2d<Object> mainarray = new ArrayList2d<Object>();
    mainarray.addRow();
    mainarray.add(userName);
    mainarray.add(password);

    busBeans.usermanagement.users um = new busBeans.usermanagement.users();
    ArrayList retrieveList = um.getValidUser(mainarray);    //database check of user existence

    if (Integer.parseInt(retrieveList.get(0).toString()) == 0) {

        ArrayList str = (ArrayList) retrieveList.get(1);

        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext externalContext = facesContext.getExternalContext();

        //getSession(false), which returns null if no session already exists for the current client.
        HttpSession session =(HttpSession)externalContext.getSession(false);

        if (session == null) {

            System.out.println();

        } else {

            Enumeration e = session.getAttributeNames();

            while (e.hasMoreElements()) {

                String attr = (String)e.nextElement();
                System.err.println("attr  = "+ attr);
                Object value = session.getAttribute(attr);
                System.err.println("value = "+ value);

            } //end of while

        }

        logedin=true;
        session.setAttribute("logedin", 1);
        session.setAttribute("firstLastName", str.get(7).toString());
        session.setAttribute("getusercredentials", str);
        session.setAttribute("sessionUserId", str.get(0).toString());
        session.setAttribute("sessionRoleId",str.get(1).toString());
        firstLastName = session.getAttribute("firstLastName").toString();
        session.setMaxInactiveInterval(60);  //1 min
        ConnectionUtil.setRgihts(Integer.parseInt(str.get(0).toString()) , Integer.parseInt(str.get(1).toString()) ,Integer.parseInt(str.get(5).toString()));
        checkRgihts();
    }

} //end of validUser()

现在我想问一件事.我使用setMaxInterval设置sessionTimeout.可以,还是最好在web.xml中执行?现在,如果timeOut过期,则不会调用过滤器.但是,假设我还附加了HttpSessionListener.然后在会话超时时调用其destroy方法.我可以在这里使会话无效.这样.

Now i want to ask one thing. I set sessionTimeout using setMaxInterval. Is it ok or it is better to do in web.xml? Now whne timeOut expires then filter doesn't invoke. But suppose that I also attach HttpSessionListener. Then on session time Out its destroy method invoke. I can invalidate session here. Like this.

public class MySessionListener implements HttpSessionListener {

    // Constructor
    public MySessionListener() {

    } //end of constructor

    @Override
    public void sessionCreated(HttpSessionEvent event) {

        System.out.println("Current Session created : " + event.getSession().getCreationTime());
        System.out.println();


    } //end of sessionCreated()

    @Override
    public void sessionDestroyed(HttpSessionEvent event) {

        // get the destroying session...
        HttpSession session = event.getSession();

        if (session != null) {

            session.invalidate();

        }

        System.out.println();

    } //end of sessionDestroyed()

} //end of class MySessionListener

但是在会话到期时,如果这是注册用户,我也想将用户重定向到redirecr Page.如果这是一个公共用户,尽管会话已过期,但我不想重定向它.我可以通过登录属性来确定它是公共用户还是注册用户,以检查destroy方法.但是,我该如何重定向注册用户或对公共用户不执行任何操作.

But on session expiration i also want to redirect user to redirecr Page if this is a registered user. IF this is a public user i don't want to redirect it although session has expired. I can check in the destroy method by getting attribute logedin that it is a public user or registered user. But then how can i redirect for registered user or do nothing for public user.

如果我的过滤器以某种方式在会话超时时调用,并且我如何通过获取登录属性1和会话超时来检查这是否是注册用户,因为我为公共用户设置了超时-1,则重定向该用户,使用RequestDispatcher进行filterChain.doFilter(request,response);.

If somehow my filter invoke on session time out and some how i check that if this is a registered user by getting logedin attribute 1 and session time out has expired, because for public user i set timeout -1, then redirect the user, using RequestDispatcher otherwoise do filterChain.doFilter(request, response);.

这就是我实现的场景.我不知道我的方法是否正确?我不知道这种方法将面临哪些安全问题.就是这样..现在您的人们指导我该怎么办.....

So this is the scenerio that i implemented. I don't know whether my approaches are right or not ? I don't know what security issues i will face by this approach. So that's it.. Now you people guide me what should i do.....

谢谢

推荐答案

我了解您的目标是什么,但是我认为没有针对未经身份验证的用户的Session并不是最好的方法.

I understand what your goal is, but I don't think that not having a Session for unauthenticated users is particularly the best approach.

考虑一个未经身份验证的用户浏览Primefaces向导,因为他提供了注册帐户的信息(例如,选择用户名,提供密码,选择安全问题等)

Consider an unauthenticated user navigating through a Primefaces wizard as he provides information to sign up for an account, (Eg. Pick Username, Provide Password, Choose Security Questions, etc...)

在收集和验证所有用户信息之前,您将不希望保留该用户信息,因为用户可能会改变主意并决定不注册?现在,您的数据库中有一条不完整的用户记录,需要清除.

You are not going to want to persist this user information until it all has been collected and validated, because perhaps the user has a change of heart and decides not to sign up? Now you have an incomplete user record in your database that needs to be cleaned.

答案是,您需要将此信息存储在ViewScoped bean中或会话中,直到未经身份验证的用户确认帐户创建为止,该帐户最终可以保存在该帐户中.

The answer is that you need to store this information in a ViewScoped bean or in session until the unauthenticated user confirms the account creation, where it can finally be persisted.

我认为最好的方法是让您为User提供一个唯一的Role,其中一个角色为Unauthenticated.使用Spring Security 3甚至Seam之类的组件,您应该能够通过Session中UserRole控制页面授权.

What I feel the best approach would be is for you to give a User a unique Role with one role being Unauthenticated. Using components like Spring Security 3 or even Seam you should be able to control page Authorization through the Role of the User in Session.

例如,您可以阻止未经身份验证的用户进入../app/*中的页面,或者阻止普通用户访问../admin/*

For instance, you can prevent unauthenticated users from entering pages in ../app/* or normal users from accessing pages in ../admin/*

这篇关于如何设计无会话的JSF 2.0 Web应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆