我的webApp中有一项要求,我需要为使用有效凭据登录的用户生成内部密码。也就是说,这个内部密码生成功能将仅在用户的会话生命周期中发生一次。我需要将此内部密码放入用户的会话中。 使用postlogin hook可以在liferay中实现类似的功能,但我不知道如何仅使用Servlet和过滤器来实现相同的功能。 注意:我使用JAAS进行用户身份验证。
我做了类似的事情:在servlet-filter中,我检查会话中的内部密码,如果它不存在则生成。但是在用户登录并且同时向服务器发出多个请求之后,将不必要地创建多个密码。密码生成是一件昂贵的事情。
有人能告诉我别的什么吗? 提前谢谢。
答案 0 :(得分:1)
我不知道,JAAS身份验证的工作原理,我只是指那个部分:
我需要将此内部密码放入用户的会话中......
如果您想将任何内容存储到用户的会话中以供日后处理,您可以在serlvets代码中执行此操作
protected final void doGet(HttpServletRequest request,HttpServletResponse response) {
HttpSession session = request.getSession(true); //this returns an existing session, or creates new one
session.setAttribute(key,value);
...
}
这些存储的对象与会话一样长。
我做了类似的事情:在servlet-filter中,我检查会话中的内部密码,如果它不存在则生成。但是在用户登录并且同时向服务器发出多个请求之后,将不必要地创建多个密码。密码生成是一件昂贵的事情。
如果内部密码生成成本很高,则不应在servlet过滤类中创建它们,因为这些过滤器适用于客户端向服务器发出的任何请求。将pw生成的相关代码移动到例如servlet,执行用户凭据的实际验证。如果凭据正常,请创建一次密码并将其存储在上面提到的会话对象中。
<强>更新强> 所以假设你有某种形式的
<form method="post" action="AuthServlet">
<input type="text" name="username">
<input type="password" name="pwd">
<input type="submit" value="login">
</form>
AuthServlet(注意:当用户尝试登录时,此servlet仅被调用一次): 进一步的假设,你需要某种服务器端钩子功能,如你所说,你想生成内部密码
@WebServlet("/AuthServlet")
public class AuthServlet
extends HttpServlet {
// .. lines omitted ..
@Override
protected final void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException,IOException {
// ... lines omitted
// perform authentication with JAAS
try {
LoginContext loginContext = new LoginContext("SomeName", handler);
// starts the actual login
loginContext.login();
//at this point, user is authenticated..normally you would forward him to e.g. a jsp, welcoming the user
//request.getRequestDispatcher("anyJsp.jsp").forward(request, response);
//but you can also forward to another serlvet and perform business logic or else
request.getRequestDispatcher("/ServletName").forward(request, response);
} catch (LoginException e) {
//do sth., if auth fails
}
}
在用ServletName
表示的servlet中,您可以在密码生成doPost()
内执行,并将此密码附加到用户的会话中。
如果您有某种用户模型,并且用户有例如角色。您可以查询角色,并根据角色转发到servlet。
这更有帮助吗?