I have created a Labor/Time Keeping application that is used for the Construction industry, and it consists of a WinForms Client where employees actually clock in and out, a WCF web service that fields the clock in and out events and provides data to the clients, and a back-end WinForms piece for Configuration, Administration and Reporting. This is all .NET with C#.
I'm looking to also write an ASP.NET Web Client to make it more flexible, with the intent that this will be used from tablets and/or cell phones from the field.
So, now that the background is out of the way, here's a requirement that I'm trying to figure out the best way to accomplish.
I don't want employees to be able to just clock in and out from their house, or from their personal phones; they should be clocking in/out with a company owned device that the Foreman keeps in his truck for that specific purpose. At the same time, I want logging in to the web app to be as simple as entering a 4 digit pin number and clicking either Clock IN or Clock OUT (no offense to the construction industy's employees, but there are some who literally have trouble trying to type in a username and password on a mobile device).
What is the best way to limit access to this web client to some specific set authorized of devices? I've considered trying to MAC Address filter, and I read about using client certificates to limit which devices could access the web service, but is there any better way? I mean, couldn't a client certificate just be copied to someone's personal phone if you get that rare concrete finisher who happens to be a nerd and know how to get it off of the company's device?
Is there any other way from a web app that you can uniquely identify a device and match it up with a list of authorized devices?
In ASP.net you can't take the MAC address of client's network adapter. Because of that, you can not count on defining a white list of MAC addresses for 'valid' devices. But you can use some other tricks alternatively:
1- You can find out the IP address of your client devices and limit them if they are not authorized from your side.
2- You can Also detect OS, computer name and browser name and screen resolution and you may utilize them in this case.
3- You can keep a flag of how many cookies have you been set for a specific user and control in this way.
4- You may use Windows authentication to prevent your users from a form-based authentication (of course if your network is active directory based)
Related
I've been asked to write a C# application to run on a Windows 7 machine to display the time of day, weather, etc.. That I can do. What I'm looking for is guidance to run the application on a Windows7 machine without logging as a user. In essence the machine would simply be a CPU with a screen. No keyboard or mouse. I've seen deployments done on MS-PixelSense (use to be MS-Surface) using a service ID.
If I need to signin, user policies kick in, screen savers enable, etc.. I'm assuming if I use an automatic Service ID, I can let the application override most of the settings keeping the screen on and needed privileges assigned / locked down to the service ID.
Any information / suggestions are appreciated....
First, some background informations:
Accessing a network share
If a process running on your client wants to access a (CIFS) share, it has to be run under a user account (or "Service ID") which has access rights to this share. There is a way (if the client is a member of Active Directory) that the machine name appended with $ (which is in fact the machine account’s name in AD) has to be entered in the ACL (Share / NTFS), but this is not a very "usual" way.
See also https://serverfault.com/questions/41130/network-service-account-accessing-a-folder-share
Windows Service running under a user account (aka technical account or Service ID)
A service running under a user account cannot access the GUI. There are some tricks, and some years ago I wrote a tool which allows a service to start another GUI program, where the GUI is displayed above the Ctrl-Alt-Del dialog. But this does not work under Windows 7 anymore.
But even a service which runs under local system cannot display a GUI on the logon screen.
You would have to write a Credential Provider.
See
Windows service showing a GUI when no user is logged in
https://stackoverflow.com/a/3074040/4547223
Another very deep technically article. It says it is possible to display a GUI on the secure desktop / logon screen. I have not yet tested this myself:
http://calebdelnay.com/blog/2012/01/displaying-a-program-on-the-windows-secure-desktop
Autologon
The most well known way is still the "classic" autologin.
See https://security.stackexchange.com/questions/10170/how-secure-is-windows-auto-logon for some explanations and links.
The medium secure way is to store the password as LSA secret (can be done in C# with P/Invoke or with some tools).
If I need to signin, user policies kick in, screen savers enable, etc.
Yes, but this can be handled, you probably have to create an own AD OU with an own policy for that.
I'm assuming if I use an automatic Service ID, I can let the application override most of the settings keeping the screen on and needed privileges assigned / locked down to the service ID.
A service ID /technical account is basically the same as a normal personal user account.
In some Active Directory enterprise environments a technical account has restrictions that it cannot log on interactively and other restrictions. But it still IS a "user account"
Logonexpert (http://www.logonexpert.com/)
I tested this (trial version). It is a nice, small tool which does it’s job. It is more safe than "normal autologon", however in the end, it is not much different from normal classic autologon. One benefit: it stores the password more recurely, but in theory, some hacker may still decompile the program and find out a way to decrypt it. And more important for you: Beside the more safe password store, it does not gain you much. You still have a user login same as normal autologon.
A few suggestions
Probably you can use a local user account on the client system and use normal autologon mechanism. And then you should consider that the client system does not poll for new data on a network share, but instead another server program (implemented as a service, running under a technical domain account) pushes data on a network share on the client.
Doing it this way, the client code does not need to access network shares, with the benefit, that a malicious attacker also has no access to network shares.
If you really need to access a network share from the local user context, you can probably logon to the server, as explained in my answer here:
https://stackoverflow.com/a/28749093/4547223
You have to to change the registry code part with the access to the CIFS share.
But doing it this way, you again have a password, which you have to encrypt and store. I do not recommend this.
In the end...
Windows does not make it easy what you want to do. If you are not strictly bound to Windows, you can consider using a Raspberry Pi with Raspbian (a Debian derived Linux). You can install Chromium browser, which displays a web page on the server and updates automatically. We use this with great success for some time.
May be it is dublicate of get Unique info for a machine in asp.net. But I need your other ideas for this.
Firstly let me try to explain my opinion:
I want to bind my system's user to his machine. When Admin creates a user in user role, he takes user's machine details (mac address, hardware information etc.) and when user tries to login, we check he is on valid machine or not.
With ASP.NET we can get only client values like Machine name, IP Address. But this values are changable.
How can I solve this issue? Or is there any way to get client's hardware information with ASP.NET?
For what it's worth, I would suggest not using MAC address as it can be easily spoofed and only ties you to the network interface, if you're user switches between wifi and wired, they would be dropped. Also, some devices - such as iPhone - are not rotating MAC addresses behind the scenes.
Can the same be achieved using a cookie - admittedly the user can delete these and will need to be reassigned, so depends how much of an issue that would be for you.
Otherwise, the only solution I have seen relies on a plugin for the user, such as Flash.
I am working on a application in WP7 in which if the application is running on one WP7 device, it should search for another WP7 device having the same application installed in close proximity, or lets say if they are in the same network.
How it can be done ?
Thanks in advance
I can think of two solutions to this problem. Either build a backend service which saves the location of the users, and use this data to show if a user is nearby. This would then not require the users to be on the same network, but requires you to have backend service. (And store user location data, which not all users are comfortable with).
The other solution, which might be better in your case is to use broadcasting in a UDP Unicast group. This would limit it to users on the same network though. There is a nice tutorial of this over at MSDN.
I have different types of access machines like fingerprint scanner, card scanner, etc. These machines generate a data when used like card_no:punch_time.
I am developing an app in C#.NET to manage these access. Employees scan their cards while in and out. They have 3 or more different working shifts. But I have a problem with how do I detect if they are entering or leaving without using any hardware?
Can anybody help me?
For your Without using any hardware situation, one way is to develop a web-based Attendance management application, make it accessible from a LAN enabled PC, it will just provide GUI for entering their credentials and will store the information in a database present at some other PC, employees will have to Sign-in at the start of their shifts and will have to Sign-out while leaving the office.
So in the past I have always developed windows forms client software while inside the work network, we went on the lazy rule that no external hardware is allowed on site, nobody can tamper with the hardware so software was always going to be run within the network which were all joined, this allowed me to lazily set the context as follows:
WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
Thread.CurrentPrincipal = wp;
So now I have been asked to write an application which is going to be running on sales-rep laptops. I can't 100% guarantee that they don't take that software and run on their home PC and have it "pretend joined" to a network. I know I can detect what network name they might be joined to, but what is the correct approach for guaranteeing that the network IS in fact OUR network? Is there some sort of fingerprint I can embed inside the application itself for determining if the network is our work network?
Gosh, that's what you meant. Head meets table in my place.
What you need is a License-Server. You're obviously describing a company license situation! Do you have an MSSQL-Server in your network?
Create a User like your_program_nameLCU (license check user)
Create a database where the user has read access
Create a Try-Catch for the situation when the database is not accessable
Obviously he's not in your network so shut down the program!
Addition to that:
It work's very well with VPN! And I guess that's what needed too!
If it is just a basic network name check you want you can just use the identity name (WindowsIdentity.GetCurrent().Name) which should contain DOMAIN\username. Once you have that plenty of ways to split the strnig and retrieve the DOMAIN name (see Built-in helper to parse User.Identity.Name into Domain\Username).
As wegginho mentioned in the comments though someone could theoretically set their network name to the same network.