Jsp 使用servlet/glassfish的用户身份验证:安全问题
我正在使用jsp/servlets和glassfish v3开发一个用户登录身份验证。Jsp 使用servlet/glassfish的用户身份验证:安全问题,jsp,authentication,servlets,login,glassfish,Jsp,Authentication,Servlets,Login,Glassfish,我正在使用jsp/servlets和glassfish v3开发一个用户登录身份验证。 基本上,jsp页面有一个调用servlet的表单。然后servlet检查数据库中的用户名和密码,并基于此进行身份验证。 我对用户身份验证的安全问题毫无经验(第一次使用servlet构建一个),我有一些问题想与大家分享: -“表单”调用servlet:/auth。如果servlet处理信息后一切正常,它将转发到jsp页面。但是我注意到我可以在浏览器中放置指向servlet的url,例如:localhost:80
基本上,jsp页面有一个调用servlet的表单。然后servlet检查数据库中的用户名和密码,并基于此进行身份验证。
我对用户身份验证的安全问题毫无经验(第一次使用servlet构建一个),我有一些问题想与大家分享:
-“表单”调用servlet:/auth。
如果servlet处理信息后一切正常,它将转发到jsp页面。但是我注意到我可以在浏览器中放置指向servlet的url,例如:localhost:8080/myapp/auth,它将重定向到jsp页面,甚至没有经过登录机制的授权。
我在servlet中编写了一些if/else条件,以防止在用户名/密码无效的情况下发生这种情况。然而,我相信有一个更好的和专业的方法来做到这一点,有人可以帮助吗
-那么,是否可以在浏览器中禁止直接浏览servlet?例如,如果用户输入浏览器url字段:localhost:8080/myapp/auth,我希望他被拒绝访问。可以这样做吗?
-此外,使用时:
getServletConfig().getServletContext().getRequestDispatcher(“/WEB-INF/something.jsp”).forward(请求,响应)代码>
转发将在url路径中显示我的servlet名称,即如果我位于:localhost:8080/myapp/,那么在转发之后我将获得:localhost:8080/myapp/auth。转发后是否可以不在url中显示“auth”部分?
代码:
html表单
web.xml中我的“auth”servlet
认证
bridge.auth
认证
/认证
但是我注意到,我可以将指向servlet的url放在浏览器中,例如:localhost:8080/myapp/auth,它将重定向到jsp页面,甚至没有经过登录机制的授权
您的主要错误是您将doGet()
和doPost()
委托给同一个自定义方法processRequest()
。你不应该那样做
doGet()
应用于预处理GET请求(如在链接/书签后,在浏览器地址栏中输入URL等),而doPost()
应用于后处理POST请求(如提交的
)
您需要将processRequest()
更改为doPost()
方法的唯一作业,并让doGet()
执行其他操作,例如显示登录页面。这也将立即解决您的另一个“问题”(这实际上不是问题,但是一个重大的误解,我也不明白为什么这会是一个安全问题,除了糟糕的代码)能够通过URL直接访问servlet:只需在/WEB-INF
中隐藏所有JSP,包括登录页面,这样您只能通过servlet的doGet()
获取JSP。我只想将servlet的URL/auth
更改为对最终用户更敏感的URL,例如/login
另见:
- -包含Hello World示例
但是我注意到,我可以将指向servlet的url放在浏览器中,例如:localhost:8080/myapp/auth,它将重定向到jsp页面,甚至没有经过登录机制的授权
您的主要错误是您将doGet()
和doPost()
委托给同一个自定义方法processRequest()
。你不应该那样做
doGet()
应用于预处理GET请求(如在链接/书签后,在浏览器地址栏中输入URL等),而doPost()
应用于后处理POST请求(如提交的
)
您需要将processRequest()
更改为doPost()
方法的唯一作业,并让doGet()
执行其他操作,例如显示登录页面。这也将立即解决您的另一个“问题”(这实际上不是问题,但是一个重大的误解,我也不明白为什么这会是一个安全问题,除了糟糕的代码)能够通过URL直接访问servlet:只需在/WEB-INF
中隐藏所有JSP,包括登录页面,这样您只能通过servlet的doGet()
获取JSP。我只想将servlet的URL/auth
更改为对最终用户更敏感的URL,例如/login
另见:
- -包含Hello World示例
您似乎在复制JavaEE6中可用的功能。为什么不使用JDBC领域和JavaEE6?这是JDBC领域。看起来您在复制JavaEE6中可用的特性。为什么不使用JDBC领域和JavaEE6?这是JDBC领域。向我们展示您的代码。请求就是请求。服务器无法知道用户是键入了URL还是单击了链接。不管怎么说,通过默默无闻进行安全保护总是一个坏主意。我上传了代码。您建议我如何完成此任务?向我们展示您的代码。请求就是请求。服务器无法知道用户是键入了URL还是单击了链接。不管怎么说,通过默默无闻进行安全保护总是一个坏主意。我上传了代码。你建议我如何完成这项任务?非常感谢!你完全正确,没有考虑doGet()方法是一个很大的错误。是的,我把它命名为auth,而不是login,因为auth是一个servlet,它使用反射和工厂模式来调用名为“login”的命令,这是两个不同的类,因此我不想两次使用相同的类名,但我可能会将auth改成其他名称。感谢您提供的信息,我认为从中访问servlet可能是一个安全缺陷
<form action= "auth" method = "POST">
<tr>
<td>Enter your name :</td>
<td><input type = "text" name = "username"></td>
</tr><br>
<tr>
<td>Enter your password :</td>
<td><input type = "password" name = "password"></td>
</tr><br>
<tr>
<td><input type = "submit" name = "submit" "></td>
</tr>
</form>
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try {
//Instantiate login Command
String cmdPath = "DomainLogic.Commands.login";
user usr = (user) cmdFactory.getInstance().getCommand(cmdPath).execute();
if(usr!=null && usr.isLoggedIn())
{
request.getSession(false).setAttribute("ok", usr);
getServletConfig().getServletContext().getRequestDispatcher("/WEB-INF/main.jsp").forward(request, response);
}
else
response.sendRedirect("/index.jsp");
} finally {}
}
<servlet>
<servlet-name>auth</servlet-name>
<servlet-class>bridge.auth</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>auth</servlet-name>
<url-pattern>/auth</url-pattern>
</servlet-mapping>