简体   繁体   English

Java Web应用程序可以访问远程工作站上的智能卡读取器吗?

[英]Can a Java Web Application access a Smart card reader on a remote work station?

I am working on some new functionality for one of our existing Java based web applications. 我正在为我们现有的基于Java的Web应用程序开发一些新功能。 The web app itself is hosted on one of our internal servers and can be accessed via the browser at several computer terminals throughout our facility. 该Web应用程序本身托管在我们的一台内部服务器上,并且可以通过我们整个机构中几台计算机终端上的浏览器进行访问。 The application is for conducting quality checks at various stages of our production process. 该应用程序用于在我们生产过程的各个阶段进行质量检查。 Currently, users are required to manually login by selecting their userName from a drop down and entering their password before conducting each quality check. 当前,要求用户在执行每次质量检查之前,通过从下拉列表中选择用户名并输入密码来手动登录。 In order to speed up the process, I have been asked to implement the reading of a smart card for login. 为了加快此过程,已要求我实现智能卡的读取以进行登录。

I have written a utility class using javax.smartcardio and I am able to access the USB card reader terminal plugged into my laptop, read the ATR from the card and use the info to login to the application when I am running the application on my local tomcat7 server. 我已经使用javax.smartcardio编写了一个实用程序类,并且能够访问本地计算机上运行的USB读卡器终端,从卡中读取ATR并使用信息登录到该应用程序tomcat7服务器。 So, on my local machine, everything works great. 因此,在我的本地计算机上,一切正常。

Unfortunately, once I deploy the application to our web server, I can no longer detect the card reader terminal as I believe that the Java web application is actually looking for the reader on the machine that it is deployed to. 不幸的是,一旦我将应用程序部署到我们的Web服务器上,我就再也无法检测到读卡器终端,因为我相信Java Web应用程序实际上是在其部署到的机器上寻找读卡器。

Is there any way that I can have my java code access a card reader plugged into a remote work station through interaction with the browser? 有什么方法可以让我的Java代码通过与浏览器的交互来访问插入远程工作站的读卡器?

The web app is written in GWT, and I am using RPC calls to access the back end server side code. 该Web应用程序是用GWT编写的,我正在使用RPC调用来访问后端服务器端代码。 Any help is greatly appreciated. 任何帮助是极大的赞赏。 The card reader code is quite simple, so I'll post it if that helps: 读卡器代码非常简单,因此如果有帮助,我将其发布:

import java.util.List;

import javax.smartcardio.Card;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.TerminalFactory;

public class SwipeCardUtil 
{

    private static org.apache.log4j.Logger LOGGER  = org.apache.log4j.Logger.getLogger("hwslqc");

    /**
     * @return ATR
     */
    public static String readCardATR()
    {
        String ATR = "";
        try 
        {
            // Show the list of available terminals
            TerminalFactory factory = TerminalFactory.getDefault();

            List<CardTerminal> terminals = factory.terminals().list();
            if (terminals.size() == 0) 
            {
                LOGGER.error("No Swipe Card Terminals Found");
                return null;
            }

            //System.out.println("Terminal: " + terminals.get(0).getName());
            // Get the first terminal in the list
            CardTerminal terminal = terminals.get(0);

            if(terminal.isCardPresent())
            {
                // Establish a connection with the card using
                // "T=0", "T=1", "T=CL" or "*"
                Card theCard = terminal.connect("*");

                // Get ATR
                byte[] baATR = theCard.getATR().getBytes();
                ATR = SwipeCardUtil.byteArrayToHexString(baATR);
                //System.out.println("ATR: " + ATR);
                // Disconnect
                // true: reset the card after disconnecting card.
                theCard.disconnect(true);
             }
            else{
                 return null;
             }

        } 
        catch (Exception ex) {
            LOGGER.error("No Card Reader Connected. Please connect a Card Reader and try again. "+ex.toString());
            ex.printStackTrace();
        }
        return ATR;
    }

    /**
     * @param theBytes
     * @return theByteArray as a hex string
     */
    public static String byteArrayToHexString(byte[] theBytes)          
    {             
        StringBuffer sb = new StringBuffer(theBytes.length * 2);             

        for (int i = 0; i < theBytes.length; i++) 
        {               
            int byteToRead = theBytes[i] & 0xff;               
            if (byteToRead < 16) 
            {                 
                sb.append('0');               
            }               
            sb.append(Integer.toHexString(byteToRead));          
        }             
        return sb.toString().toUpperCase();          
     }
}

Your client is a web browser, and your web app is deployed on a remote server. 您的客户端是一个Web浏览器,并且您的Web应用程序已部署在远程服务器上。 The only way to get the reader's data from the client is to implement a piece of software running on the client side. 从客户端获取读取器数据的唯一方法是实现在客户端上运行的软件。 There are several ways to do this but many will not run on the client's web browser. 有几种方法可以执行此操作,但是许多方法无法在客户端的Web浏览器上运行。

You can try to implement an applet, but chances are high that the applet will not have sufficient rights to access the client's hardware. 您可以尝试实现一个applet,但是很有可能该applet没有足够的权限来访问客户端的硬件。 To elevate the applets privileges it must be signed by a browser trusted CA. 要提升小程序特权,必须由受浏览器信任的CA对其进行签名。 That's quite an endeavour. 那是相当的努力。

Another way would be to not use a web browser at all but to implement a rich client software. 另一种方法是根本不使用Web浏览器,而是实现富客户端软件。 But that is as much pain as the previous suggestion since the whole productbis based on a thin client/web browser concept. 但这与以前的建议一样痛苦,因为整个产品基于瘦客户机/ Web浏览器概念。

Maybe you could use a single sign on approach. 也许您可以使用单一登录方法。 If the users are on a windows machine and logged on with their account, you could use waffle. 如果用户在Windows计算机上并使用其帐户登录,则可以使用waffle。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM