Authentication Tomcat-根据用户到达登录页面的方式使登录页面内容不同

Authentication Tomcat-根据用户到达登录页面的方式使登录页面内容不同,authentication,tomcat,servlets,login,Authentication,Tomcat,Servlets,Login,我在Tomcat中实现了一个基于web的服务,并使用基于Tomcat容器的身份验证。我试图实现的是让登录页面根据用户如何到达那里而显示不同。具体而言: 如果用户单击“登录”按钮,我希望登录页面只要求输入用户名和密码。我实现了登录按钮,只需将用户带到“登录”页面,并将该页面设置为安全页面,以便触发容器登录 如果未经身份验证的用户访问需要身份验证的页面,我希望登录页面也显示“您必须登录才能执行此操作”或类似的内容 因此,问题是使登录表单的控制器或JSP知道浏览器在重定向到此处时所请求的内容。我已

我在Tomcat中实现了一个基于web的服务,并使用基于Tomcat容器的身份验证。我试图实现的是让登录页面根据用户如何到达那里而显示不同。具体而言:

  • 如果用户单击“登录”按钮,我希望登录页面只要求输入用户名和密码。我实现了登录按钮,只需将用户带到“登录”页面,并将该页面设置为安全页面,以便触发容器登录

  • 如果未经身份验证的用户访问需要身份验证的页面,我希望登录页面也显示“您必须登录才能执行此操作”或类似的内容

因此,问题是使登录表单的控制器或JSP知道浏览器在重定向到此处时所请求的内容。我已经查看了请求对象中的头和其他属性,但没有看到任何有用的内容


有人能提出解决办法吗?或者可以采用另一种方式实现“登录”按钮以避免出现问题?

您可以使用此按钮确定原始请求的目标:

<%
String value0 = (String)request.
                getAttribute("javax.servlet.forward.request_uri");
if(value0.contains("login_success.jsp")) {
    out.print("USER, LOG IN!");
} else {
    out.print("USER, you have to LOG IN to go there!");
}
%>

其他选择包括:

您可以使用登录按钮重定向到
登录成功页面
,并在URL中添加一个
?MyKey=value
,该属性可以在
登录页面
中看到,您可以对其作出反应


我会修改我的代码,把所有我能找到的东西都画出来,让它更可读,然后把它贴在这里。我确信用户下一步得到的值在你的
请求中的某个地方存在,你只需找出位置。

你有几个选项,1是标题“Referer”。该字段将包含浏览器最后所在的URL。。。所以你可以在登录页面上看到,最后一个页面是我的页面链接到这里,还是其他地方

这会起作用,但它不是完全可靠的,一些人/公司会过滤掉推荐人等,一些浏览器可能允许用户打开它,因此你无法获得他们最后访问的页面的推荐


最好的办法是在用户登录时分配一个cookie值,然后如果用户请求一个需要登录的页面,您的代码只需检查cookie值是否存在。如果在那里,用户已经登录,您可以显示页面。。。如果不是您发送的,您必须登录才能完成此页面。

我赞成@Angelo关于可移植性的回答,但如果您愿意将应用程序绑定到Tomcat,您可以从触发请求中获取目标目的地(用户登录后想要去的地方),该请求保存在会话中。我还没有尝试过这个,但我认为它会起作用:

import org.apache.catalina.authenticator.Constants
import org.apache.catalina.authenticator.SavedRequest
import org.apache.catalina.session.StandardSession

...

StandardSession standardSession = 
    (StandardSession) httpServletRequest.getSession();

// Retrieve the SavedRequest object from our session
SavedRequest saved = (SavedRequest)
        standardSession.getNote(Constants.FORM_REQUEST_NOTE);
if ((saved == null) || 
    httpServletRequest.getRequestURI().equals(saved.getRequestURI())) {
    // user came directly to login page
} else {
    // "You must login to do this"
}

在我看来,上述解决方案似乎是倒退的。身份验证控制器不应该查看请求来自何处来决定要做什么。。。应该说出来。重定向控制器/规则应该知道他们想要做什么,并且应该将其发送到适当的操作

登录可以直接转到servlet的登录操作

我不知道您的servlet是如何设置的,但是servlet应该在需要进行某些操作的情况下寻找身份验证。如果未进行身份验证,请重定向到身份验证操作。登录/验证操作将略有不同(设置参数或文本),但可以转到同一视图


话虽如此,从头开始进行身份验证是一项艰巨的工作,而且通常很容易引入其他框架。例如:Spring Security。

您使用的前端语言是什么?嗯。。。JAVA我使用的是Tomcat和JSP。最简单的方法是在登录按钮上创建一个会话,然后检查是否存在错误。您也可以在tomcat中随意实现任何JAAS身份验证(不仅仅是内置的标准),这里的图片部分是我使用的是自定义域和组合域,我在tomcat 6和tomcat 7上都实现了它。@Angelo:Replace by
request.getAttribute(“javax.servlet.forward.request\u uri”)
在JSP中,您会看到它只是返回相同的结果。我想我尝试过这个。IIRC,问题是,当我显式重定向到登录表单时,随后发送到j_security_check的帖子没有被认证阀接收,导致404。不过我会再试一次。@StephenC本周我会尝试设置一个基本系统来测试这个案例。让我们看看我能做些什么。@StephenC请尝试我对答案提出的新方法。OP提到他在请求属性中找不到任何证据。但这也可能是一种误解。我只是不想用老式的脚本来检查…:/@巴卢斯:是的,这种方法并不漂亮,它只是想表明我的意思。你需要把它作为一个阀门来部署。会话在一个门面后面,所以它不会这样工作。或者,你可以更换会话管理器,或者像我一样-如果你需要对代码进行任何修改。看起来很复杂。我发现原始url仍然存在于页面上下文中(请参阅我的更新答案)。我认为,在这种情况下,这会更容易。有更简单、更可靠的方法。请求头(包括cookie!)是可操作的。