Java : 许可网络应用程序。登录前检查许可证

Java : Licensing a webapp. Check for license before login happens

我想让我的 webapp 许可证受到保护。当请求任何 page/resource 的 webapp 时,我想首先检查许可证。如果找不到许可证,那么我想重定向到许可证上传页面。

我创建了一个过滤器,它映射到所有请求,我可以在其中检查许可证并在必要时重定向。 问题是我的 webapp 具有登录身份验证的安全约束。 有关更多信息,请参阅最后的 web.xml。

由于安全限制,所有的请求都是先通过登录认证拦截,然后转发到我的过滤器。但是,我想在登录之前检查许可证。

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

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

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>

这与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

如果您必须在身份验证之前验证许可证,唯一的方法是使用编程安全并将许可证验证作为过程的一部分。

Programmatic security is useful when declarative security alone is not sufficient to express the security model of an application. The API for programmatic security consists of methods of the EJBContext interface and the HttpServletRequest interface. These methods allow components to make business-logic decisions based on the security role of the caller or remote user.

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)(如下)在重试之前在 servlet 中。如果您也必须删除安全约束,请按如下方式使用过滤器。
  2. 添加一个过滤器来验证许可证。如果失败,它将重定向到一个页面以上传许可证并重试。如果没有,您将执行链中的下一个过滤器。
  3. 链中的下一个过滤器知道许可证有效。如果用户未登录,它将尝试获取用户和密码作为请求参数。如果它们存在,它将尝试以编程方式对它们进行身份验证 - 此时您正在执行前面 link 中的示例之一。如果用户已登录,请继续。如果凭据不匹配或没有可尝试的凭据,请重定向到自定义登录页面以让用户填写其凭据并重试。
  4. 如果您不得不从 web.xml 中删除安全约束,请使用另一个过滤器来检查此处的角色以及您可能需要的任何其他内容。

确保重定向到不同的路径,这样这些页面就不会再次调用过滤器并循环。 (可以将过滤器配置为在 forwarding/redirecting 时跳过,我认为这是默认设置,但如果您不得不放弃安全约束,那么您希望确保它们无论如何都会被调用。)

您可以在单个过滤器中完成所有这些操作 and/or,而不是在写出适当的响应失败时进行重定向(有点像模拟 servlet 向自己发送多次)。在这方面,过滤器比 servlet 更好,因为您可以确定它被调用以进行任何访问尝试。

另一种方法是将 2) 和 3) 中的所有内容都编写为 "real" 应用程序之外的单个 servlet,如果会话未经过身份验证且没有,则将过滤器重定向到它正确的 "valid-license" 属性集(您在 servlet 中设置)。这可能会更快,维护起来可能更简单,但耦合度不会那么高。