java ee用户登录_EE Servlet 3:使用会话和过滤器开发用户登录
java ee用户登录
我在上一篇文章中介绍了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本身无效,只是为了保证安全。 我还公开了一个静态帮助器getOptionalLoginSession
, getOptionalLoginSession
在少数几个类之间使用,以检查用户是否已登录。
这几个类很简单,但是展示了如何使用Servlet Filter和Servlet来管理Session数据。 这种编程模式允许用户通过应用程序拥有自己的浏览会话和隐私。
如果要在GlassFish服务器中运行我的servlet3-example ,则可以使用here中列出的任何用户登录。
翻译自: https://www.javacodegeeks.com/2015/01/ee-servlet-3-developing-user-login-with-session-and-filter.html
java ee用户登录
java ee用户登录_EE Servlet 3:使用会话和过滤器开发用户登录相关推荐
- EE Servlet 3:使用会话和过滤器开发用户登录
我在上一篇文章中介绍了Application类,您可以在其中设置后端服务. 我添加的一个示例服务是UserService . 该服务将加载包含用户名和密码集的Java用户属性文件: 稍后将用于对用户进 ...
- java ee jsp_EE JSP:Servlet的反向外套
java ee jsp 仅当页面数量少或需要对生成的内容(二进制PDF等)进行精细控制时,才可以从Servlet生成HTML. 对于大多数应用程序,输出将是HTML,我们需要一种更好的方法来完成此操作 ...
- java ee 程序_第一个 JavaEE 应用程序 - JavaWeb 入门开发教程
第一个 JavaEE 应用程序 JavaEE 是 Java Web 开发当中事实上的标准,诸多框架也都是建立在 JavaEE 的 API 基础之上的.为了从头理解 Java Web 开发,我们将从一个 ...
- Java Web学习总结(34)——拦截器和过滤器的差异总结
过滤器和拦截器的区别: ①拦截器是基于Java的反射机制的,而过滤器是基于函数回调. ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器. ③拦截器只能对action请求起作用,而过滤 ...
- Java+MyEclipse+Tomcat (二)配置Servlet及简单实现表单提交
在Java EE应用编程中Servlet是基础,JSP是建立在Servlet基础之上的,其他Web框架如Struts.WebWork和Spring MVC都是基于Servlet的.本文主要讲述MyEc ...
- oidc_使用Java EE和OIDC构建Java REST API
oidc "我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证. ...
- 使用Java EE和OIDC构建Java REST API
"我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证. Java ...
- Java EE 8发生了什么?
Java EE 8的工作进展顺利. 是时候赶上了! 无需费力就可以潜入- 不要忘记Java EE 7-.. 围绕三个重要主题 HTML 5对齐–用于WebSocket的Java API(JSR 356 ...
- Java EE:更名实属无奈,未来路在何方?
点击关注 InfoQ,置顶公众号 接收程序员的 8 点技术早餐 作者|Jean-François James 编辑|薛命灯.郭蕾 1999 年,Sun 公司正式发布了 J2EE 的第一个版本.到现在, ...
最新文章
- BZOJ 2326: [HNOI2011]数学作业( 矩阵快速幂 )
- 033-Unit 12 Introduction to String Processiong
- 通用无线设备对码软件_珞光全新发布国产通用软件无线电平台 :USRP-LW N310!珞光品牌已实现国产替代...
- SpringMVC报错The request sent by the client was syntactically incorrect ()
- C#注册类方法到Lua
- JDBC插入百万数据,不到5秒!
- 游戏开发:Html5 虚拟摇杆控制人物移动
- FCKeditor使用
- EOVA的下拉级联实现过程
- PowerDesign安装教程
- python网络测速_Linux下3种常用的网络测速工具
- ruby语言学习-开启篇
- pow函数php,PHP pow( )用法及代码示例
- wpf初学者-wpf控件简单介绍
- NFS服务器配置与管理笔记
- 客户端与服务器交互的功能,如何进行测试?
- 聊天机器人chatbot搭建及思考(TensorFlow)(附代码)
- Mysql的避坑---- The error may involve defaultParameterMap #The error occurred while setting parameters
- IE8和IE9发送跨域请求
- 计算机网络access code,access code
热门文章
- P2495-[SDOI2011]消耗战【虚树,dp】
- 洛谷P3845-球赛【离散化,贪心】
- codeforces1451 D. Circle Game
- 【费用流】【线性规划】志愿者招募(luogu 3980)
- 【Trie】阅读理解(luogu 3879/ybtoj Trie-4)
- 费用流-Wannafly Day2 TwoGraph-神题
- codeforces E. Game with String 概率
- 动态规划训练20 [Treats for the Cows POJ - 3186 ]
- 第三章用sql语句操作数据
- 快速排序+时间测试(yyds)