JSF HTTP 会话登录 [英] JSF HTTP Session Login

查看:25
本文介绍了JSF HTTP 会话登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试在 Web 应用程序中创建登录表单.在 JSP 页面中我可以使用

I try to create login form in web application. in JSP page I can use

<%
   String name = request.getParameter( "username" );
   session.setAttribute( "theName", name );
%>

但现在我正在使用 JSF/Facelets 进行 Web 应用程序我不知道如何在 JSF Backing bean 中为客户端创建会话并检查用户是否登录,以便它重定向到登录页面.谁能帮我给我这些问题的链接教程?先谢谢了

but now I am using JSF /Facelets for web application I don't know how to create session in JSF Backing bean for client and check if user is logged in or not so it will redirect into login page. who can help me give me link tutorial for these problem ? thank you before

现在映射到 web.xml 没有什么问题类过滤器的代码剪断

Now I have little problem with mapping into web.xml code snipped of class Filter

@Override
public void init(FilterConfig filterConfig) throws ServletException {
    this.config = filterConfig;
}

@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;
    LoginController controller = (LoginController) req.getSession()
            .getAttribute("loginController");
    if (controller == null || !controller.isLoggedIn()) {
        res.sendRedirect("../admin/login.xhtml");
    } else {
        chain.doFilter(request, response);
    }
}

web.xml 中,我用 标签进行映射

and in web.xml I map with <fitler> tag

<filter>
    <filter-name>userLoginFilter</filter-name>
    <filter-class>com.mcgraw.controller.UserLoginFilter</filter-class>
    <init-param>
        <param-name>loginPage</param-name>
        <param-value>/login.xhtml</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>userLoginFilter</filter-name>
    <url-pattern>/admin/*</url-pattern>
</filter-mapping>

我在 web 项目中有一个文件夹 admin,我检查用户是否没有以管理员权限登录,无法访问页面(我可以进行权限检查)但是当我使用过滤器时,浏览器不理解 url ??当浏览器不理解 url 时没有 StackTrace 显示

I have one folder admin in web project and I check if the user is not logged in with admin permission to not access page (I can do the permission check) but when I use the filter the browser doesn't understand url ?? no StackTrace show when the browser doesn't understand url

Firefox 上显示的错误

Error shown on Firefox

The page isn't redirecting properly

在 IE 上它正在加载...正在加载... 不停

on IE it loading ... loading . .. non-stop

现在我改变条件,检查 req.getPathInfo.startsWith("/login.xhtml") 是否会执行链

now I change condition which check if req.getPathInfo.startsWith("/login.xhtml") it will do chain

我有 2 个想法,但它响应 500 HTTP STATUS

I have 2 idea but it response 500 HTTP STATUS

 if (controller == null || !controller.isLoggedIn()) {
     res.sendRedirect("../admin/login.xhtml");
     if(req.getPathInfo().startsWith("/login.xhtml")){
     chain.doFilter(request, response);
}

} else {
     chain.doFilter(request, response);
}

================

===============

if (controller == null || !controller.isLoggedIn()) {
    if (!req.getPathInfo().startsWith("/login.xhtml")) {
        res.sendRedirect("../admin/login.xhtml");
    } else {
        chain.doFilter(request, response);
    }
} else {
    chain.doFilter(request, response);
}

======================更新类 loginController

====================== update Class loginController

package com.mcgraw.controller;

import com.DAO.UserBean;
import com.entity.IUser;
import java.io.Serializable;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

/**
 * @author Kency
 */
@ManagedBean
@SessionScoped
public class LoginController implements Serializable {

    @EJB
    private UserBean userBean;
    private IUser user;
    private boolean admin;
    private boolean mod;
    private PasswordService md5;

    /** Creates a new instance of LoginController */
    public LoginController() {
        user = new IUser();
        md5 = new PasswordService();
    }

    // getter / setter
    public boolean isMod() {
        return mod;
    }

    public void setMod(boolean mod) {
        this.mod = mod;
    }

    public IUser getUser() {
        return user;
    }

    public void setUser(IUser user) {
        this.user = user;
    }

    public boolean isAdmin() {
        return admin;
    }

    public void setAdmin(boolean admin) {
        this.admin = admin;
    }

    public String cplogin() {
        String md5Password = md5.md5Password(user.getPassword());
        if (userBean.userLogin(user.getUsername(), md5Password) != null) {
            if (user.getUsername() != null || md5Password != null) {
                user = userBean.userLogin(user.getUsername(), md5Password);
                if (user.getGroups().getAdmin() != null) {
                    setAdmin(user.getGroups().getAdmin());
                }
                if (user.getGroups().getMods() != null) {
                    setMod(user.getGroups().getMods());
                }
                if (isAdmin() == true || isMod() == true) {
                    return "home";
                } else {
                    return "login";
                }
            } else {
                return "login";
            }
        } else {
            return "login";
        }
    }

    public String logout() {
        user = null;
        return "login";
    }

    public boolean isLoggedIn() {
        return user != null;
    }
}

如果使用方法loggedIn呈现JSF taglib,我有新问题,在索引页面(不在管理文件夹中)用户没有登录可以看到我呈现的示例,<==这就像如果用户没有登录用户可以看不到,但他为什么能看到?

I have new problem if render JSF taglib with method loggedIn, in index page (not in admin folder) user doesn't login can see what I render example, <== this like if user doesn't login user can't see but why can he see it?

推荐答案

您可以在 JSF 中通过 ExternalContext#getSessionMap() 基本上是 HttpSession#get/setAttribute().

You can in JSF get/set HTTP session attributes via ExternalContext#getSessionMap() which is basically a wrapper around HttpSession#get/setAttribute().

@Named
@RequestScoped
public class LoginController {

    private String username;
    private String password;

    @EJB
    private UserService userService;

    public String login() {
        User user = userService.find(username, password);
        FacesContext context = FacesContext.getCurrentInstance();

        if (user == null) {
            context.addMessage(null, new FacesMessage("Unknown login, try again"));
            username = null;
            password = null;
            return null;
        } else {
            context.getExternalContext().getSessionMap().put("user", user);
            return "userhome?faces-redirect=true";
        }
    }

    public String logout() {
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
        return "index?faces-redirect=true";
    }

    // ...
}

在 Facelets 页面中,只需将 usernamepassword 输入字段绑定到此 bean 并相应地调用 login() 操作.

In the Facelets page, just bind the username and password input fields to this bean and invoke login() action accordingly.

<h:form>
    <h:inputText value="#{loginController.username}" />
    <h:inputSecret value="#{loginController.password}" />
    <h:commandButton value="login" action="#{loginController.login}" />
</h:form>

会话属性可在 EL 中直接访问.名为 user 的会话属性在 EL 中可用作 #{user}.在测试用户是否登录了某个 rendered 属性时,只需检查它是否为 empty.

Session attributes are directly accessible in EL. A session attribute with name user is in EL available as #{user}. When testing if the user is logged in some rendered attribute, just check if it's empty or not.

<h:panelGroup rendered="#{not empty user}">
    <p>Welcome, #{user.fullName}</p>
    <h:form>
        <h:commandButton value="logout" action="#{loginController.logout}" />
    </h:form>
</h:panelGroup>

注销操作基本上只会破坏会话.

The logout action basically just trashes the session.

至于检查传入请求是否有用户登录,只需创建一个 Filter 大致在 doFilter() 方法:

As to checking an incoming request if an user is logged in or not, just create a Filter which does roughly the following in doFilter() method:

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {    
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;
    HttpSession session = request.getSession(false);
    String loginURI = request.getContextPath() + "/login.xhtml";

    boolean loggedIn = session != null && session.getAttribute("user") != null;
    boolean loginRequest = request.getRequestURI().equals(loginURI);
    boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER);

    if (loggedIn || loginRequest || resourceRequest) {
        chain.doFilter(request, response);
    } else {
        response.sendRedirect(loginURI);
    }
}

将其映射到覆盖受限页面的 url-pattern,例如/secured/*/app/*

Map it on an url-pattern covering the restricted pages, e.g. /secured/*, /app/*, etc.

这篇关于JSF HTTP 会话登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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