We have an application which features different levels of users. This is not a "security feature", this is more to prevent that users change anything that is not related to their role.
Also, the server is not public and only available on local connection(network not accessible from internet).
We would like to use credentials, but we would like that no encryption and ssl is required(because the service has sometimes a lot of data to transfer and we don't want to "loose" time to encrypt/decrypt each time).
Is this possible? What should be used as Security Mode?(we do configure our services in the code, not through XAML).
Thanks
I would want to know more about the use case you are looking for.
But assuming that you are just trying to prevent anonymous access of an application, you may go for a windows authentication if you are using AD based workstations. If not then you may need to rely on custom authentication which just pops up a challenge before allowing you through.
EDIT: Based on your comment, I understand that you are using CustomUserNameValidator in WCF for auth. Understand that it is not a mandate to use certificate when you are using this. However, certificate improves the security. If you are absolutely sure that your network is protected and snoop-free, you can use self signed certificate using makecert. However, i will always advise to purchase a certificate.
A sample is found here https://blogs.msdn.microsoft.com/pedram/2007/10/05/wcf-authentication-custom-username-and-password-validator/
You can also choose to use HTTP custom binding with plain username / password without any certificate involved
Related
My organization has a Win32 application that is written in the "fat client" style. I am writing a C# Client / Server solution that will replace this Win32 application. I am using ASP.NET MVC for the server and the client is a WPF application. I did my own custom implementation of the OAuth 2 spec. I am planning on creating a Restful API, and I want for not only my client to use it, but also allow 3rd parties to use it as well.
Every app will have an api key issued to it including the official client, but the official client's api key should be allowed additional api scopes (permissions) that 3rd party users aren't allowed to use. It is pretty obvious how to solve this but if you consider not everyone plays nicely, you have to ask "What would stop someone from just pretending like they are the official client and using it's api key?" Communication will be encrypted, but the server is not in the cloud or anything like that where we could control it. Our customers install the servers on their own machines and they will more than likely have access to the server application's SSL cert. Once you have that you can easily write an app that would run on our customer's machine that could glean the API key and secret from the official client app and use that info to request tokens from the server as if you were the official client.
I am planning on self signing the default key that the server uses and I could try and hide it in the application, but that really is just obfuscation. Besides, I wanted to allow users to provide their own SSL certs so browser based 3rd party applications wouldn't have issues with the browsers complaining that they are trying to communicate with on a self-signed SSL channel.
Is there anything I can do? Here are my choices as I see it:
1) I can set it up so that only SSL certs provided by us can be used and we hide them on disk encrypted using a secret that is obfuscated in the application code. We then just hope no one bothers to take the time to dig through our .net assemblies to find the secret used to encrypt/decrypt the certs on disk.
2) We allow them to provide certs so that we don't need to be involved with that process at all when they want to use a signed cert (we don't want to be in the cert business). Now we can't even hide behind obfuscation so if someone wants it, then the official client's API key and secret is easily obtainable.
Neither seems very desirable to me. Option 1 makes us have to request addition funds from them and manage SSL certs when self-signed doesn't work for them and in the end if someone really wants them they can still take the time to get them. Option 2 just makes it super easy to steal the official client's secret.
Reasons to want to limit unofficial Apps:
1. Discourage clones
A. Tell people not do it. Have a lawyer send cease and desist letters to authors of popular apps (and to anyone helping distribute them). Intermittently download them and alter the client/server code so that the popular apps will break. For added discouragement, temporarily ban any users who used the popular app. Authors will mostly give up on cloning your app; temporarily banning users will kill their install base. This is not great for your reputation.
2. Prevent unauthorized behavior.
A. Any behavior allowed by the official app should be allowed by the custom app. Whatever scenario you are worried about, block it server-side so that neither app can do it.
You can try to hide credentials (code obfuscation, hidden credentials, etc.), but this is only raises the cost/difficulty. This is often enough to discourage code theft (no need to make code theft impossible; it is sufficient to make it more difficult than copying it by hand). However, users who want to use your api in unsupported ways can work around this.
The answer is simple. each instance of you app should have its own unique key effectively a user sign up. You then ban users who infringe your rules. in this case signing in with a non authorised client. should be pretty easy to detect by pushing updates more frequently than it would be cost effective to reverse engineer them. Much like punk buster or other anti cheating tech
I'm building an application that syncs data between users' Exchange Server accounts (version 2007-2013 supported) and the application.
The application can't use impersonation (at least not in the typical case) as users could be on any number of domains and exchange servers.
I know I'm going to have to ask for their username/email-address and password initially. However, I really don't want to be responsible for storing these credentials if I don't have to (even if they are encrypted, I'd rather not).
I'm not sure what questions to ask, so I'm going with these:
How does Exchange Server authenticate? Do the user's credentials get sent directly to the server as they are, or are the hashed together before being sent across the wire? If they are hashed, how can I get/generate this hash for re-use on successive authentications?
Does Exchange Server send some sort of authentication token that can be re-used later (and forever, until password change or invalidation)?
If you know of a solution to the problem, that the answers to these questions won't address, please do provide it instead.
Active directory federation services is exactly for such tasks. You can read about it there.
As mentioned by Kirill, ADFS 2.0 is one of the best solution for your task. You can also look into other SSO implementations as well. Though the main goal of SSO implementation is to maintain single Login state for multiple application (thereby reducing multiple Login prompt for each application), some of your application goals seems relevant. Please do a thorough research on all the tradeoffs before heading to the sso implementation since there is a small degree of complexity involved during implementation. SSO suits best if you are considering integration of multiple application in the future with the exchange server.
To answer some of your questions (in the same order - considering an SSO scenario with ADFS 2.0):
The authentication to exchange server will be done via ADFS 2.0 (Which provides security tokens (STS service) - to your application after authenticating with AD/ main Directory service). All the communication is encrypted and token signing certificates are used for Integrity and confidentiality.
The lifetime of Security tokens sent by ADFS 2.0 can be configured and reused as required. Please see this blog post for more details.
Also you can configure the ADFS 2.0 (Federation Service) to send only the relevant claim values (like username and email address) to the application, thereby improving the data security.
The System.Net.CredentialCache should work to suite your needs. The WebCredentials is a wrapper for the System.Net.NetworkCredential. Depending on the connection type/domain ect you should be able to utilize System.Net.CredentialCache.DefaultNetworkCredentials or System.Net.CredentialCache.DefaultCredentials
perhaps you should take a look at this Links Connecting to EWS by using the EWS Managed API , Connect to Exchange - Getting Started Tutorial? hopfully it will give you a new idea how to solve your problem :)
because if i understand the information correctly you maybe over think problem but i haven't any experiences so i could also absolute wrong
Bottom Line
If you can't configure anything on the server, there's no automatically generated token to use. It's unfortunate, but you're facing the same general problem that web browsers have--saving the password.
It's worth noting that any authentication needs to be over SSL (an https connection) to prevent a third party listening in on the authentication.
Password storage thoughts:
My suggestion is then to be somewhat creative when storing the password. You can use a keyed encryption algorithm, and then use a hash to generate the key, letting you arbitrarily choose what goes into the key. You would want at least 3 pieces of information going into this: something unique to the device, something unique to the app, and something unique to the exchange server.
For example:
a unique id given by the device (it doesn't matter whether or not this value is app-specific or not, merely that it is consistent)
a (long) string of information compiled into the app, possibly keyed to installation specific values, say the time when the app was first used
something unique to the destination, like the DNS name and perhaps some more specific server info
If you're willing to provide the option to the user, you could have an authorization PIN of some kind that would also be added to the data.
All this data gets put together in one byte array and hashed. The hash (or part of it, or it twice, depending on the hash size vs. the key length) is then used as the key for the encryption of the password.
You could also include some check information along with the password to be able to check client side whether or not the password was decrypted correctly. (If the wrong data is hashed, the wrong key is generated, and the wrong result comes from the decryption).
It's worth noting that all the information to be used for putting into the hash needs to be stored on the device, which is why I would suggest a Pin to authorize the usage of the account.
I know that their are questions and articles about WCF deployment, but i don't find one that actually solves my issue.
So i have a WCF service that is going to be used over tcp. If i set the security to transport, then i am obligated to use for usercredentials certificate or Windows. I don't want to use a certificate but i can't be sure that the service will always be hosted in a windows domain. So it leaves me with certificate security. I know that i can create a certificate with makecert, but what must i do when i want to deploy the service onto a server? Do i only need a certificate for the service or also the client that connects needs one?
Also if use message security, i need to have a certificate for the service.
EDIT,
In intranet scenarios, is it ok to use self signed certificates?
I didn't know myself, was just looking here:
WCF easiest security mode to implement
one of the best comments I think, in regards do just checking user/pass on both sides of the wire:
Such solution will not be secure. You talking about symmetric encryption where all clients and server has to share same key. Once any client get compromissed (and key is stolen or shared with anybody else) the security is gone. User name and password has nothing to do with encryption. – Ladislav Mrnka
You may be able to do it, but it might overlook the bigger question: why choose this route in the first place?
Here's some code for plaintext passwords if you really want to go down that route....
http://webservices20.blogspot.com/2008/11/how-to-use-clear-usernamepassword-with.html
I have made a WCF REST service which consumes data from an OLAP database and it is not Microsoft technology, ultimately, I would like to connect many other OLAP database to a single platform.
And after a lot of reading, the security for WCF REST is very discouraging, in summary, I have 2 choices, one is to use the Basic Authentication which expose username and password over the wire, or maybe a bit better, using Basic Authentication with SSL, now I need to get different certificates from the webserver. Or using Digest Authentication, which use an encrypted password and authenticate against the database, that's the best option, but in my case, it is not possible as I am not using Microsoft technology, the security is on different platform and I cannot encrypt my password using MD5 because the database cannot read the encrypted password.
That concludes me only be able to use Basic Authentication with SSL, but is this the correct way of doing? I see many products out there doing something similar to what I do, when they login, I do not see https, but only http, are they not secure and easy to hack?
I am not trying to make a bullet proof website, but a simple website, using Basic Authentication is too simple, or in fact it's almost like giving away the password, but using https, is that overkill?
So, after REST being that discouraging, let's not use REST, use the normal WCF, from what I have read, they shares the same problem.
Please give me some guidance. I think I have lost.
Many Thanks
PlayKid
Often, basic authentication is used for regular websites and yes, the username and password often go over the line readable if used with http. Https is already better, because the information is send encrypted over the line. But in practice, you only see this in place for commercial or banking applications. You cannot use MD5, which is a pitty, because that would be sort of middle-of-the-road approach.
So, depending on the application you will expose, use http for simplicity or https with a bit more complexity and safety.
By the way, big safety problems often have to do with SQL injection or a hacker being able to get some admin level privileges on your site. That way they get acess to a lot of info, while sniffing your line and getting a single user password combination is relatively harmless, if you take the needed precautions and counter measures.
Basically, Basic authentication with SSL is really very secure and shoul be used if its going to be exposed to outside world.
One easiest hack approach I have seen before and if you just want to authenticate (not authorize a endpoint) clients which are known set of clients use:
OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name
This will provide username accessing the service, Authenticate this usern with your DB or AD using LDAP if a valid user is accessing the service and with every request add a encrypted key that user needs to send as part of request. This way you know the username and encrypted key from the request.
You can also use this along with Basic authentication to be sure its not insecure.
I am developing an Android project where I need to connect to the backend C# service to get data.
I am thinking of using JSON to avoid the SOAP message overhead. What is the best way to implement the security for the JSON request to make it not accessible to public and only accessible from the dedicated users.
I am think of getting a token (or SessionID) from server after login using SSL and for all the service calls after login will be using this token to authenticate.
But how should I use the token after login -
1).through HTTP (can it be easily intercepted?)
2).through HTTPs (will there be performance issue if every call is made through HTTPs?)
Could you give some guidance on how to implement it to be secure without effecting performance?
UPDATE!
The Android application is in Hybrid mode which is consisting of webviews and native activities.
How should I maintain the session if the token is base on session? The user can just login and inactive for long period. Should I just increase the session timeout?
I would suggest using SSL even after you acquire the token. Our company deals with projects with banks and health related secure data and we are mandated to use SSL even after the token implementation. We found that the performance is still within reasonable limit even after using https.
Using Https would not be a huge performance hit especially considering the implication of someone could be sniffing your packet and get the token (given we don't know the access point that the user might be connecting to).
The overhead associated with SSL will happen during the initial handshake since it needs to basically exchange key and encryption algorithm via RSA. However once you pass that initial handshake, the cost is related only to encryption/decryption of the packet and that will not be a huge impact to your app.
As a side note you could also implement security using client certificate on your app to make sure that only the app can make the call to the webservice. This would further secure the call since the hacker would need access to the certificate in order to gain access to the server. Even if they know the login, they cannot access the endpoint without the certificate.
SSL will affect performance some but not too much (from what I've experienced). I would use a semi-secure hash based on something like this:
MD5SUM or SHA1 the following: today's date + some punctuation + something unique about the user (perhaps email, etc…). This would give you a long string looking like ajadfh28dfj2yadsfh28… As long as your Android side sent it in the same way that the server side is expecting it and it's unique between users, to me it would be pretty secure.
To do it the WCF / Microsoft recommended way, you implement WCF authorization using a Role provider.
That includes an IPrincipal, and injecting your custom principal, which will have the roles loaded from a database, LDAP, etc.
Then, any WCF methods can simply be decorated like so, for authorization:
[PrincipalPermission(SecurityAction.Demand, Role = "ADMIN")]
[PrincipalPermission(SecurityAction.Demand, Role = "OPERATOR")]
public void SomeServiceCall(string foo)
{
// In your case this would be an AJAX endpoint, not a void method
}
That will protect the service calls; they won't even appear to exist to the caller.
Starting points: http://msdn.microsoft.com/en-us/library/ff647040.aspx
Microsoft provides sourcecode to a sample role provider.
Keep in mind, too, it is not required to implement a full Membership provider, though many people think so. You only need a custom validator and Role provider for this. Much of the membership provider can be left unimplemented.