Java Web应用程序可以访问远程工作站上的智能卡读卡器吗? [英] Can a Java Web Application access a Smart card reader on a remote work station?

查看:220
本文介绍了Java Web应用程序可以访问远程工作站上的智能卡读卡器吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我们现有的一个基于Java的Web应用程序开发一些新功能。 Web应用程序本身托管在我们的一个内部服务器上,可通过浏览器在整个工厂的多个计算机终端访问。该应用程序用于在我们生产过程的各个阶段进行质量检查。目前,用户需要手动登录,方法是在进行每项质量检查之前,从下拉列表中选择其用户名并输入密码。为了加快这一过程,我被要求实施读取智能卡登录。



我用javax.smartcardio编写了一个实用程序类,我可以访问插入笔记本电脑的USB读卡器终端,从卡中读取ATR并使用info在我的本地tomcat7服务器上运行应用程序时登录到应用程序。因此,在我的本地机器上,一切都很好。



不幸的是,一旦我将应用程序部署到我们的Web服务器,我就不能再检测到读卡器终端,因为我相信Java Web应用程序实际上是在它所部署到的机器上寻找读者。

有什么方法可以让我的java代码通过与浏览器的交互访问插入远程工作站的读卡器?

Web应用程序是用GWT编写的,而且我使用RPC调用来访问后端服务器端代码。任何帮助是极大的赞赏。读卡器的代码非常简单,所以我会发布它,如果有帮助:

  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);
$ b / **
* @return ATR
* /
public static String readCardATR()
{
String ATR =;
尝试
{
//显示可用终端的列表
TerminalFactory factory = TerminalFactory.getDefault();

列表< CardTerminal>终端= factory.terminals()。list();
if(terminals.size()== 0)
{
LOGGER.error(找不到刷卡终端);
返回null;
}

//System.out.println(\"Terminal:+ terminals.get(0).getName());
//获取列表中的第一个终端
CardTerminal terminal = terminals.get(0);

if(terminal.isCardPresent())
{
//使用
//T = 0,T = 1与卡建立连接,T = CL或*
Card theCard = terminal.connect(*);

//获取ATR
byte [] baATR = theCard.getATR()。getBytes();
ATR = SwipeCardUtil.byteArrayToHexString(baATR);
//System.out.println(\"ATR:+ ATR);
//断开
// true:断开卡后重置卡。
theCard.disconnect(true);
}
else {
return null;


$ b catch(Exception ex){
LOGGER.error(没有读卡器连接,请连接读卡器并重试。+ ex的ToString());
ex.printStackTrace();
}
返回ATR;

$ b $ **
* @param theBytes
* @返回该字节数组作为十六进制字符串
* /
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));
}
返回sb.toString()。toUpperCase();


$ / code $ / pre

解决方案

客户端是一个Web浏览器,并且您的Web应用程序部署在远程服务器上。从客户端获取读者数据的唯一方法是实现在客户端运行的一个软件。
有几种方法可以做到这一点,但许多方法不会在客户端的Web浏览器上运行。

您可以尝试实现一个小程序,但小程序没有足够权限访问客户端硬件的可能性很高。为了提升applet特权,它必须由浏览器信任的CA签名。这是一项非常努力的工作。

另一种方法是根本不使用网络浏览器,而是实施富客户端软件。但是,由于整个产品基于瘦客户机/网络浏览器概念,这与以前的建议一样痛苦。可能您可以使用单点登录方式。如果用户在Windows计算机上并使用他们的帐户登录,则可以使用华夫饼。


I am working on some new functionality for one of our existing Java based web applications. 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. 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. 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.

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?

The web app is written in GWT, and I am using RPC calls to access the back end server side code. 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. 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.

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. To elevate the applets privileges it must be signed by a browser trusted 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. But that is as much pain as the previous suggestion since the whole productbis based on a thin client/web browser concept.

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.

这篇关于Java Web应用程序可以访问远程工作站上的智能卡读卡器吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆