我在上一篇文章中介绍了Application类,您可以在其中设置后端服务。 我添加的一个示例服务是UserService 。 该服务将加载包含用户名和密码集的Java用户属性文件; 稍后将用于对用户进行身份验证以登录到Web应用程序。 现在,我将展示如何使用标准Servlet API以及此后端服务完成登录部分。

从高层次上讲,我们希望将某些Web资源(这意味着Servlet提供的某些URL,例如“ / sysprops”或“ / user”)限制为仅在我们的用户属性文件中已知的客户端用户。 用户可以使用匹配的密码来标识自己。 通常使用用户登录表单来完成此操作,对其进行身份验证,然后将登录令牌插入Http Session范围空间。 然后可以使用该登录令牌来验证是否允许用户访问受限资源。 我们只对单一授权感兴趣(未定义任何角色,任何登录的用户都可以访问任何受保护的URL。)

SysPropsServlet提供的我以前的SysPropsServlet ,您已经看到了一个映射到“ / sysprops” URL的示例,该示例仅生成系统信息HTML表。 这些是敏感信息,因此我们要保护此URL。 我们将需要创建一个实现javax.servlet.Filter接口的类,然后使用此过滤器添加“ / sysprops” URL,以便它可以在实际的Servlet之前对请求进行预处理。 此过滤器使我们可以检查HTTP请求对象并在需要时中止请求,从而限制了访问。

package zemian.servlet3example.web;import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import zemian.service.logging.Logger;@WebFilter(urlPatterns={"/sys-props", "/user"})
public class LoginRequiredFilter implements Filter {private static final Logger LOGGER = new Logger(LoginRequiredFilter.class);public static final String LOGIN_REDIRECT = "LOGIN_REDIRECT";@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {if (request instanceof HttpServletRequest) {HttpServletRequest req = (HttpServletRequest) request;LOGGER.trace("Checking LoginSession token for uri=%s", req.getRequestURI());LoginSession loginSession = LoginServlet.getOptionalLoginSession(req);if (loginSession == null) {LOGGER.debug("No LoginSession token found; forwarding request to login page.");// We need to save the old URI so we can auto redirect after login.req.setAttribute(LOGIN_REDIRECT, req.getRequestURI());req.getRequestDispatcher("/login").forward(request, response);return;} else {LOGGER.debug("Request allowed using LoginSession token=%s", loginSession.getId());}}chain.doFilter(request, response);}@Overridepublic void destroy() {}}

请注意,您可以配置此过滤器以匹配要保护的多个URL。 您甚至可以使用通配符模式,例如“ / *”,它将保护您应用程序中的每个URL! 过滤器只是在Http Session空间中LoginSession我们稍后将创建的LoginSession对象。 如果找到它,则它使请求通过,否则它将重定向到LoginServlet页面,该页面由LoginServlet类提供服务(请注意RETURN语句将提前退出filter方法,而无需调用filter链!)。

LoginServlet类是一种表单处理Servlet,它将提示用户输入用户名和密码。 如果成功,那么我们将LoginSession令牌对象插入到HttpSession空间中,这就是上面的过滤器正在寻找的内容。 这是处理Servlet代码。

package zemian.servlet3example.web;import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import zemian.service.logging.Logger;
import zemian.servlet3example.service.Application;
import zemian.servlet3example.service.UserService;@WebServlet("/login")
public class LoginServlet  extends HtmlWriterServlet {private static final Logger LOGGER = new Logger(LoginServlet.class);@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {HtmlWriter html = createHtmlWriter(req, resp);String message;// Check to see if we are doing logout or not.LoginSession loginSession = getOptionalLoginSession(req);if (loginSession != null && req.getParameter("logout") != null) {logout(req);message = "Your have successfully logged out.";} else {   message = (String)req.getAttribute("message");if (message == null)message = "";}  // Show a login formString redirectUri = (String)req.getAttribute(LoginRequiredFilter.LOGIN_REDIRECT);String redirectHtmlTag = "";if (redirectUri != null) {redirectHtmlTag = "<input type='hidden' name='redirectUri' value='" + redirectUri + "'/>";}html.header().h(1, "Please Login").p(message).println("<form method='post' action='login'>").println(redirectHtmlTag).println("<p/>Username: <input type='text' name='username'/>").println("<p/>Password: <input type='password' name='password'/>").println("<p/><input type='submit' value='Submit'/>").println("</form>").footer();}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {LOGGER.debug("Processing login form.");if (login(req)) {// Login succeed, we should auto redirect user if exists.String redirectUri = req.getParameter("redirectUri");if (redirectUri != null) {LOGGER.debug("Redirect after login to: %s", redirectUri);resp.sendRedirect(redirectUri);return;}}// Show the form again in case login failed or user didn't provide a redirectdoGet(req, resp);}   protected LoginSession createLoginSession(HttpServletRequest req, String username) {LoginSession result = new LoginSession(username);req.getSession(true).setAttribute(LoginSession.LOGIN_SESSION_KEY, result);return result;}protected void removeLoginSession(HttpServletRequest req) {HttpSession session = req.getSession(false);if (session != null) {session.removeAttribute(LoginSession.LOGIN_SESSION_KEY);}}private boolean login(HttpServletRequest req) throws IOException {String username = req.getParameter("username");String password = req.getParameter("password");UserService userService = Application.getInstance().getUserService();if (userService.validate(username, password)) {LOGGER.info("User %s logged in successfully.", username);// Create Session Data here after successful authenticated.LoginSession loginsession = getOptionalLoginSession(req);if (loginsession == null) {createLoginSession(req, username);req.setAttribute("message", "You have successfully logged in.");} else {req.setAttribute("message", "You already have logged in.");            }} else {LOGGER.info("User %s failed to login.", username);req.setAttribute("message", "Invalid login.");}return true;}/** Return LoginSession if found in HttpSession scope, else return NULL value. */public static LoginSession getOptionalLoginSession(HttpServletRequest req) {LoginSession result = null;HttpSession session = req.getSession(false);if (session != null)result = (LoginSession)session.getAttribute(LoginSession.LOGIN_SESSION_KEY);return result;}
}

LoginServlet类中,我们使用UserService服务来验证用户名和密码。 我们显示带有GET请求的登录表单,然后使用POST操作处理登录。 检查用户名和密码后,我们将创建LoginSession对象。 这只是表示会话令牌的简单POJO。 您可以保留所需的任何用户信息。 我不会在这里列出,但是您可以在GitHub上浏览它。 请注意,但是您应该使其可序列化,因为HttpSession中存储的任何数据都可能会被应用程序服务器序列化/反序列化。

还要注意,我也已经将Logout功能实现到LoginServlet类中。 您只需传递“注销”查询参数,它将被检测到并从会话中删除登录令牌。 这样做时,请确保使HttpSession本身无效,只是为了保证安全。 我还公开了一个静态帮助器getOptionalLoginSessiongetOptionalLoginSession在少数几个类之间使用,以检查用户是否已登录。

这几个类很简单,但是在如何管理Session数据上展示了Servlet过滤器和Servlet的用法。 这种编程模式允许用户通过应用程序拥有自己的浏览会话和隐私。

如果要在GlassFish服务器中运行我的servlet3-example ,则可以使用here中列出的任何用户登录。

翻译自: https://www.javacodegeeks.com/2015/01/ee-servlet-3-developing-user-login-with-session-and-filter.html

EE Servlet 3:使用会话和过滤器开发用户登录相关推荐

  1. java ee用户登录_EE Servlet 3:使用会话和过滤器开发用户登录

    java ee用户登录 我在上一篇文章中介绍了Application类,您可以在其中设置后端服务. 我添加的一个示例服务是UserService . 该服务将加载包含用户名和密码集的Java用户属性文 ...

  2. android studio 微信登录界面,如何使用Android Studio开发用户登录界面

    满意答案 zhou9081 2016.05.21 采纳率:51%    等级:7 已帮助:411人 如何使用Android Studio开发用户登录界面,具体解决方案如下: 解决方案1: <:t ...

  3. Bootstrap4+MySQL前后端综合实训-Day06-AM【eclipse详细配置Tomcat、开发web项目、servlet、连接MySQL8.0数据库、用户登录界面的编写与验证、分页查询】

    [Bootstrap4前端框架+MySQL数据库]前后端综合实训[10天课程 博客汇总表 详细笔记][附:实训所有代码] 目   录 eclipse重置视图 MySQL数据库--建数据库.建数据库 s ...

  4. php开发用户登录模块,使用CodeIgniter开发用户登录注册模块

    本文介绍使用CodeIgniter来开发一个用户登录和注册的小模块,有详细的数据库表和ci代码. 1.数据库设计 字段 类型 空 额外 索引 id int(10) 否 auto_increment p ...

  5. 小程序短视频项目———开发用户登录注册(一)

    二. 新建小程序注册模块,配置好注册页面. regist.wxml <view><view class="login-icon"><image cla ...

  6. Servlet+MySQL使用DBCP数据库连接池实现用户登录

    首先准备数据库数据和登录页面 创建user数据表并且插入几条数据 DROP TABLE IF EXISTS `user`; CREATE TABLE `user` (`id` int(11) NOT ...

  7. 菜鸟级springmvc+spring+mybatis整合开发用户登录功能(下)

    昨天介绍了mybatis与spring的整合,今天我们完成剩下的springmvc的整合工作. 要整合springmvc首先得在web.xml中配置springmvc的前端控制器DispatcherS ...

  8. 网站用户登录验证:Servlet+JSP VS Struts书剑恩仇录

    ? 什么是Struts框架 –从不同的角度看待Struts框架 –Struts框架的优点 ? 下载安装Struts框架 –下载配置Struts框架 –测试Struts框架 –安装Struts应用程序 ...

  9. java 拦截器和过滤器的区别

    介绍 在 Java Web 应用程序中,拦截器和过滤器是两种不同的机制,用于在请求/响应处理过程中进行拦截和过滤.两者都可以用来在请求到达目标资源之前对其进行预处理.修改或拦截. 但是,拦截器和过滤器 ...

最新文章

  1. TensorBoard logging requires TensorBoard version 1.15 or above
  2. facebook工具xhprof的安装与使用-分析php执行性能
  3. 被高中生物骗了这么多年,原来人体内细胞的DNA是有不同的?
  4. S5PV210体系结构与接口09:SD卡启动详解
  5. networkx edge 属性_python图算法库Networkx笔记-第一章
  6. [转]centos7.2 下 nginx 开机启动
  7. 学习笔记: yield迭代器
  8. JavaWeb之分页代码
  9. 计算机应用研究英文稿,英文文摘要编写要求
  10. 13/18V系列中频切换开关原理及应用方式
  11. 金蝶K/3 ERP 基于Citrix Access Gateway 的SSL ××× 部署方案
  12. Parrot OS 4.6渗透测试系统安装与基础环境搭建
  13. 手机应用游戏开发死机现场之一
  14. ffmpeg在低版本VS中的编译
  15. FineBI与FineReport对比 1
  16. 论文笔记:Show, Edit and Tell : A Framework for Editing Image Captions
  17. 微软官方给出无法安装WIN10更新的终极解决办法:覆盖安装
  18. 服装管理系统大一c语言
  19. 使用声网的RTM SDK轻松给angular应用加上实时聊天功能
  20. android与华为窄带物联网,中国移动联合华为在成都布局窄带物联网

热门文章

  1. SpringBoot整合Shiro实现登录认证和授权CHCache
  2. idea初始化git 初始化git仓库
  3. jsp连接mysql数据库 例子_JSP 连接 MySQL 数据库的例子
  4. 对应node版本_安装Node.js教程
  5. 会话技术Cookie
  6. react提交数据到数据库_React型关系数据库事务
  7. spring框架三层架构_Spring框架架构
  8. 设计模式适配器模式_适配器设计模式示例
  9. spring配置jndi_在Spring Framework中通过JNDI进行配置
  10. gradle排除依赖_如何从Gradle中的所有依赖项中排除库