4

我需要限制特定用户的角色以在从特定位置访问应用程序时使用应用程序让我们说“具有员工角色的用户只能从办公室或其分支机构访问应用程序”

  • IP检查?它是可变的
  • 如果我遵循私钥/公钥呢?这样做的缺点是,如果我将密钥放在 cookie 中,他们可以读取它或者可能会清除他们的 cookie。
  • 基于mac地址?它是可变的
4

7 回答 7

7

你不能相信 IP 和 MAC 地址更没用,你唯一的朋友就是密码学。假设您的用户将使用他的凭据进行身份验证,您还需要以某种方式对机器进行身份验证。这是通过在每台机器上放置不同的证书并让客户端使用他的证书向服务器证明他的“身份”来完成的。

如果您的客户端-服务器通信基于 SSL,您可能需要客户端身份验证 - 查看Java HTTPS 客户端证书身份验证http ://rap.ucar.edu/staff/paddy/cacerts/或http://docs。 oracle.com/cd/E11035_01/wls100/security/SSL_client.html

如果您的通信不是基于 SSL,或者您希望在应用程序级别进行身份验证 - 您仍然可以使用证书。从信任库加载它并通过证明您可以访问私钥来证明您的身份(通常服务器发送一个质询,用公钥随机加密的东西,您通过用私钥解密并将其发回来回答。这样您无需出示即可证明您拥有私钥)。

如果您不想存储证书,您可以在每台机器上放置一个不同的加密文件。客户端将能够解密它(使用硬编码密钥)并将类似于密码的内容发送到服务器。

您如何保护这些证书?对文件的用户的只读权限...

几个注意事项 -

  1. 您永远无法真正信任客户端计算机。一个足智多谋的敌对用户会破坏任何东西。你“敌人”的资源越多,你需要投入的防御就越多。

  2. 您没有指定有关您的环境的详细信息。我确定有一些我不知道的系统级解决方案。例如 - 您的服务器可能会连接到 Active Directory 并监控特定机器上的用户登录。

  3. 有时最好的解决方案可能并非来自软件层面。例如,如果您的服务器使用指定端口进行通信。您可以在防火墙\路由器\个人防火墙上允许\阻止此流量 - 在比您的服务器更足以解决此问题的地方。如果您有应用程序控制强制实施,您可以允许客户端本身仅在特定机器上运行。

  4. 您还可以寻找方法来创建一些独特的 PC 指纹(主板 ID、cpu id、Active Directory 中的 SID、HDD id、MAC 地址...) - 然后您的服务器可以存储允许的指纹列表,您的客户端将发送当前计算的指纹。这仍然回到 - 您对客户的信任程度如何?

于 2013-08-08T18:02:22.337 回答
3

仅当人们来自具有静态 IP 的地方时,IP 限制才有效。像在家里这样有动态的任何地方都行不通。

如果您不能使用静态并且仍想通过 IP 进行限制,您可以使用http://dyn.com/dns/ 之类的服务为您的 IP 分配 FQDN。然后您可以通过 FQDN 进行查找以查看它是否返回与请求中的 IP 匹配的 IP。这个查找可以被缓存,所以你每隔几个小时才做一次。棘手的部分是每个位置都必须设置一个动态 DNS 客户端。现在有些路由器内置了这个。

您无法通过 HttpServlet 类获取 MAC 地址。如果您能从与您的服务器通信的设备获取 MAC 地址,这很可能是路由器、负载平衡、交换机之类的东西。MAC 地址不可路由。

回复:密钥,您可以使用 x509 证书 - http://static.springsource.org/spring-security/site/docs/3.0.x/reference/x509.html

于 2013-08-06T01:31:07.123 回答
2

我只想解决您问题的这一部分:

我正在尝试实现 IP 方法,但它遇到了以下错误。

  java.lang.IncompatibleClassChangeError: com.project.Default and
      com.project.Default$IpCheckService disagree on InnerClasses attribute

IncompatibleClassChangeError意味着在编译时的类型与运行时的类型之间存在冲突。在这种情况下,您似乎拥有(拥有)一个嵌套IpCheckService类,该类已从static更改为非static(或反之亦然!),并且您设法加载了其中一个类的旧版本。

这是一个构建或部署问题。如果你能弄清楚这里出了什么问题,那么你的代码很有可能会起作用。(至少,您不会再遇到异常。)

于 2013-08-02T02:10:25.697 回答
2

更新:

在某个地方限制用户的唯一方法是:

  • 您必须在 Office 中定义固定 IP!
  • 或者,至少是办公室及其分支机构的子网掩码。
  • 在您的应用程序中,检查请求中的子网掩码并将其与固定的预配置办公室子网掩码进行比较。
  • 因此,要么将这些固定 IP 放入 webconf.xml,要么将 IP 的子网掩码放入;

无论如何,该解决方案将始终连接到网络解决方案。

您可以尝试这样的方法来检查固定 IP:

public class TestFilter implements Filter{ 

     public void destroy() {}  
     public void init(FilterConfig arg0) throws ServletException {} 

     public void doFilter(ServletRequest request, ServletResponse response, FilterChain        filter) throws IOException, ServletException 
     {  
        HttpServletRequest req = (HttpServletRequest) request;  
        HttpServletResponse res = (HttpServletResponse) response;  

        IpAddressMatcher matcher = new IpAddressMatcher("192.168.1.0/24");

        try {
            if(!matcher.matches(req.getHeader("X-Forwarded-For"))){
               res.sendRedirect("AnotherPage.jsp");  
            }
        } catch (UnsupportedOperationException e) {
            //Handle IT
        }
     }     

}

此外,您可能需要检查以下内容以了解每种情况:

    request.getHeader("Proxy-Client-IP");
    request.getHeader("WL-Proxy-Client-IP");
    request.getHeader("HTTP_CLIENT_IP");
    request.getHeader("HTTP_X_FORWARDED_FOR");
    request.getRemoteAddr();
于 2013-08-02T01:30:24.437 回答
0

要设置这样的授权规则,首先需要定义的是:

  • 就计算机识别而言,“办公室或其分支机构”的定义是什么?通常它是来自某些子网的计算机,如上面的答案中所写 - 在这种情况下,解决方案是显而易见的。
  • 第二种可能性 - 有人带着他的个人电脑或笔记本电脑或触摸板等来到办公室。如果安全策略允许这样做,我们唯一可以验证的实体是用户。我们可能仍然希望从办公室(作为物理位置,例如建筑物)/从家中访问不同的访问权限。在这种情况下,我建议查看一次性密码生成设备,这些设备应该在办公室中可供用户使用。
于 2013-08-09T12:47:30.183 回答
0

“具有员工角色的用户只能从办公室或其分支机构访问应用程序”

使用站点到站点 VPN。这有效地将问题转化为内网登录问题,解决起来很简单。

通过使用站点到站点 VPN,您可以确保远程站点的身份,因为连接设置和身份验证通常由站点上的路由器执行,站点上的哪些用户不需要知道的配置(或有在他们的电脑上,所以不能带走)。

一旦转化为 Intranet 问题,只需将应用程序绑定到 Intranet 地址并像保护任何其他 Intranet 资源一样保护它。

于 2013-08-11T21:27:27.240 回答
0

我从这里找到了以下代码,您可以根据它们的 mac 地址识别它们。

这个也很有帮助

package com.mkyong;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;

public class App{

   public static void main(String[] args){

    InetAddress ip;
    try {

        ip = InetAddress.getLocalHost();
        System.out.println("Current IP address : " + ip.getHostAddress());

        NetworkInterface network = NetworkInterface.getByInetAddress(ip);

        byte[] mac = network.getHardwareAddress();

        System.out.print("Current MAC address : ");

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < mac.length; i++) {
            sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));        
        }
        System.out.println(sb.toString());

    } catch (UnknownHostException e) {

        e.printStackTrace();

    } catch (SocketException e){

        e.printStackTrace();

    }

   }

}
于 2013-08-02T01:34:09.817 回答