2015-12-23 18 views
9

我想让我的webapp许可证受到保护。当请求webapp的任何页面/资源时,我想首先检查许可证。如果没有找到许可证,我想重定向到许可证上传页面。Java:授权webapp。在登录前检查许可证

我已经创建了一个映射到所有请求的过滤器,我可以检查许可证并在必要时重定向。 问题是我的web应用程序有登录验证的安全限制。 请参阅最后的web.xml以获取更多信息。

由于安全约束,所有的请求首先被登录验证拦截,然后转发到我的过滤器。但是,我想在登录发生之前检查许可证。

这是我问的一个相关问题。

Java : Intercept all requests before they go to login authentication

在安全性约束优先处理过滤器似乎是不可能的。所以,我想问一下,有没有其他方法可以处理这个用例?

的web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    id="WebApp_ID" version="2.5"> 
    <display-name>Tango</display-name> 

    <filter> 
     <filter-name>SalsaValidationFilter</filter-name> 
     <filter-class>net.semandex.salsa.validationFilters.SalsaValidationFilter</filter-class> 
    </filter> 

    <filter-mapping> 
     <filter-name>SalsaValidationFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
     <!-- <servlet-name>SalsaValidationServlet</servlet-name> --> 
     <dispatcher>REQUEST</dispatcher> 
    </filter-mapping> 

    <session-config> 
     <session-timeout>20</session-timeout> 
    </session-config> 

    <security-constraint> 
     <web-resource-collection> 
      <web-resource-name>Login page images</web-resource-name> 
      <url-pattern>/images/salsadb-logo2.png</url-pattern> 
      <url-pattern>/images/salsa-icon.png</url-pattern> 
      <url-pattern>/images/shadow_box.png</url-pattern> 
      <url-pattern>/images/header.png</url-pattern> 
      <url-pattern>/images/bg.png</url-pattern> 
      <url-pattern>/css/splash.css</url-pattern> 
      <url-pattern>/WEB-INF/licenseValidation.html</url-pattern> 
      <url-pattern>/auth/licenseValidation.html</url-pattern> 
     </web-resource-collection> 
    </security-constraint> 

    <security-constraint> 
     <web-resource-collection> 
      <web-resource-name>The entire webapp</web-resource-name> 
      <url-pattern>/*</url-pattern> 
     </web-resource-collection> 
     <auth-constraint> 
      <role-name>SalsaUser</role-name> 
     </auth-constraint> 
    </security-constraint> 

    <security-role> 
     <role-name>SalsaUser</role-name> 
    </security-role> 

    <login-config> 
     <auth-method>FORM</auth-method> 
     <form-login-config> 
      <form-login-page>/auth/login.jsp</form-login-page> 
      <form-error-page>/auth/loginError.jsp</form-error-page> 
     </form-login-config> 

     <realm-name>mongo_login</realm-name> 
    </login-config> 
</web-app> 
+1

这不是我用过的东西,但我想知道JACC是否是解决您的问题的方法?我相信它是安全约束过程的钩子。我发现它在[this SO question]中引用(http://stackoverflow.com/questions/17654020/precedence-of-security-constraint-over-filters-in-servlets),它向你提出了类似的问题,并且它链接到[此博客文章](http://arjan-tijms.omnifaces.org/2014/03/implementing-container-authorization-in.html)。 – DaveyDaveDave

回答

1

如果您必须验证身份验证之前的许可证,只有这样,将使用程序的安全性和包括许可证的验证作为过程的一部分。

仅当声明式安全性为 不足以表示应用程序的安全模型时,程序安全性非常有用。编程安全性的 API由接口和HttpServletRequest接口的方法组成。这些方法允许 组件根据调用者或远程用户的安全角色 做出业务逻辑决策。

https://docs.oracle.com/javaee/7/tutorial/security-intro003.htm#BNBXH

这里有几个短的例子:https://docs.oracle.com/javaee/7/tutorial/security-webtier003.htm#GJIIE

我没有做过编程安全自己不过从外观上来看,你可以做这样的事情:

  1. 从你的web.xml中删除容器的安全性 - 通过设计它将在所有其他的东西之前,从而得到你的方式。理想情况下,您可以将auth-method设置为NONE并保持安全约束 - 当尝试访问时,您可能会直接显示错误页面,然后您可以在尝试再次尝试2)和3)(下面) 。如果您也必须删除安全约束,请按如下所示使用过滤器。
  2. 添加一个将验证许可证的过滤器。它失败了,它会重定向到一个页面上传许可证,然后重试。如果没有,你会做链中的下一个过滤器。
  3. 链中的下一个过滤器知道许可证是有效的。如果用户没有登录,它会尝试获取用户名和密码作为请求参数。如果它们存在,它将尝试用它们进行编程验证 - 在这一点上,您正在执行上一个链接中的一个示例。如果用户登录,继续。如果凭证不匹配或者没有凭据可以尝试,请重定向到自定义登录页面以让用户填写凭据并重试。
  4. 如果您必须从web.xml中删除安全约束,请使用另一个筛选器来检查此处的角色以及您可能需要的任何其他内容。

请确保您重定向到不同的路径,以便这些页面不会再次调用过滤器并循环。 (过滤器可以配置为在转发/重定向时跳过,我认为这是默认设置,但是如果您不得不放弃安全限制,那么您要确保它们被称为无论如何。)

您可能会全部这在一个单一的过滤器和/或而不是重写失败时写出适当的响应(有点模拟一个servlet自己发几次)。过滤器比servlet更好,因为你可以确定它被调用来进行任何访问尝试。

另一种方法是将所有内容写入2)和3)作为一个单独的servlet,而不是“真正的”应用程序,并且如果会话未通过身份验证并且没有正确的“有效许可“属性集(您在servlet中设置它)。这可能会更快,维护起来可能更简单,但并不那么紧密。

+0

+1这很有趣!现在我已经解决了以下解决方案,因为我即将发布。我已经从表单认证中排除了我的webapp主页,并创建了一个拦截主页请求的过滤器。由于首页的请求已被排除在表单身份验证之外,因此首先会被过滤器拦截。如果需要,可以从我的过滤器重定向到uploadLicense页面。 我知道这只适用于主页,但我现在可以解决它。但是当我抽出时间时,我肯定会尝试这种方法。 –

+0

“它将先于其他所有事情”否,它不会,它将首先调用ServerAuthModule(SAM)。在那里,您应该执行验证许可证检查,而不是在过滤器中! –

0

这是无关JACC。正常的Web应用程序许可证检查在用户授权完成后完成。你如何验证这取决于你的应用程序的设计。

1. You can add a filter to the filter chain that intercepts to after 
    the user authorization. In this approach you need to properly 
    communicate user that license is failed. 


2. Redirect the user to license verification page after user 
     authorization is done. Ask user to verify the license. If the verification fails then redirect user again login page. In this approach you have advantage of displaying the web apps he is licensed in the suite of web apps. 

Thank in advance 
-Bharat 
+0

根据我的使用情况,我不能允许在许可证验证之前进行用户验证。 –

+0

在这种情况下,我们需要配置过滤器链来首先在JACC中检查许可证验证。请确保您在用户界面上表示确切的错误以通知用户。 – BValluri