如何高度限制具有“特定角色”的用户从“某个地方”访问应用程序?

时间:2013-08-02 01:15:17

标签: java security java-ee spring-security

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

  • IP检查?它是可以改变的
  • 如果我关注私钥/公钥怎么样?这样做的缺点是,如果我把密钥放在cookie中,他们就可以读取它或者清除它们的cookie。
  • 基于mac地址?它是可以改变的

7 个答案:

答案 0 :(得分:7)

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

如果您的客户端 - 服务器通信基于SSL,则可以要求客户端身份验证 - 查看Java HTTPS client certificate authenticationhttp://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,主机ID,CPU ID,Active Directory中的SID,HDD ID,MAC地址......) - 您的服务器可以存储允许的指纹列表并且您的客户将发送当前计算的指纹。这仍然会回归 - 您对客户的信任程度如何?

答案 1 :(得分:3)

仅当人们来自具有静态IP的地方时,才能通过IP限制。在家里,你有动态的地方,它不起作用。

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

您无法通过HttpServlet类获取MAC地址。如果你能从正在与服务器通信的设备上获得MAC地址,那很可能就像路由器,负载平衡,交换机一样。 MAC地址不是无法路由的。

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

答案 2 :(得分: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();

答案 3 :(得分:2)

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

  

我正在尝试实施IP方法但遇到以下错误。

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

IncompatibleClassChangeError表示编译时类型与运行时类型之间存在冲突。在这种情况下,您似乎已经(有)嵌套IpCheckService类已从static更改为非 - static(或反之亦然!),不知怎的,你已经设法加载其中一个类的旧版本。

这是构建或部署问题。如果你能弄清楚这里出了什么问题,你的代码很可能会有效。 (至少,你不会再获得例外。)

答案 4 :(得分:0)

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

one也很有帮助。

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();

    }

   }

}

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

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

使用站点到站点VPN。这有效地将问题转换为内部网登录问题,这很容易解决。

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

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