Securing a Subscription WCF Webservice - c#

I'm working on a subscription data delivery webservice using C# and WCF. Customers will sign-up to use the service at different usage levels for a monthly fee. The project requirements call for the service to be accessible from a web app hosted on the same server, from a desktop app and Windows service distributed to customers and from a WordPress plugin. In the future, support may be added for other CMS systems and mobile (Apple/Android) apps.
The security requirements include a standard user ID and password authentication for each call to the service to verify subscription status and type and to track user activity. That's easy enough to do but there's more and that's what I'm looking for advice on.
First of all, there's the need to track IP addresses and use this information to control access. One part of this is to restrict the number of different IP addresses the service can be called from within a specific time period per ID and subscription type. The second part is to prevent access to the service from certain countries entirely. I've read some other answers here about how to implement IP address detection/tracking in general but I am more concerned about potential difficulties associated with this that others have encountered. What should we watch out for here?
The second major security requirement is to restrict access to the service to our provided desktop/service applications or from authorized domains using our CMS plugins. I'm not sure how this can be implemented other than using some sort of authentication token which of course could be easily hacked. Perhaps in combination with the login and IP address requirements this will be enough though. Are there any alternative methods that might be a better approach to take?

Related

How to organize communication in an asp.net web application using separate authorization server, web api, ui?

The requirements
we have 3 modules ui, api, IdentityServer (IS) (client, resource, IS in terms of IdentityServer)
all the modules should be separated from each other (separate dbs for IS and api)
api is stateless (all the needed auth info got from tokens)
the api will have resources like \projects, \users, etc.
another entry point may be added in the future like another-ui which will communicate with the IS and api and will have its own claims
The problems
The main problem is that the resources of api like \projects\12345, \users\, \projects\123456\users, etc. may also be needed as claims in IS. For example, api module reads the access token of authorized user and see the claim projects that equals ["222", "12345"], so the resource \projects\12345 or \projects\123456\users are allowed for that user.
Users are identities in IS and resources in api at the same time. Projects are claims in IS and resources in api at the same time.
I thought of book-keeping these entities that are represented in both modules through the ids (guids). But ids won`t solve all the problems.
Some of them are:
creation of a new project with its id should grant that user the rights to use it in the future, so we need save the claim for that user in some way. The modules are separated, so should we call the IS api to create that claim for that user and then proceed with project creation. How the communication between the two (IS and api) should be organized? Do we need to register the api as another client in IS?
How should updates of users in IS like changing the email, phone (the values one may log in with) will update the api. I thought of showing warnings that the auth email (got from token) does not match the info email.
Could you, please, explain how modern systems coupe with the per resource access?
Thank you for your time.
First you need to make sure what a claim is.
Claim is not a permission or a role, it's what the user is. Based on what the user is, then you can assume the permissions.
https://learn.microsoft.com/en-us/aspnet/core/security/authorization/claims?view=aspnetcore-3.0
A claim is a name value pair that represents what the subject is, not what the subject can do.
So starting from that, you can get the claims and do the following.
Let's say that a user is the owner of a project. When the new project is created, the project api can update the identity server and add a claim to the user saying he is the owner.
In your apis the owner of a project has a set of permissions and based in those, access to specific resources
In the DDD Domain driven design world, a little bit of data duplication does not matter. So duplicating the possible claims that your application needs in terms of roles (again, not ids but a mapping of one or more claims to specific roles) is not a bad practice.
When you update some kind of claim from your api, you should do so in a transactional way. Think first if you need the email to be saved in both. You will get the user data from the claims anyway on every request. Is it even something you need as a claim? If not have it in your api only.
Communication between apis is organized in many ways. If you need transactions or eventual consistency is something you should also consider. Communicating with events or queues is the microservices way to go, with patterns like the SAGA being the coordinator.

Passwordless sign-in/sign-up with phone number

Good Evening.
I'm programming a backend containing an HTTP API that allows the client to login or register through a provided phone number. Because of this, this process is quite different from traditional authentication flow.
Because phone number oriented authentication is not secure (but extremely convenient), you can't allow a user to login into someone else account solely using phone number, which was a common case that can happen in phone number recycling cases (example is Lyft).
That's why i thought to emulate just a part of how Lyft currently handle with this, by requiring the user to specify his email during registration and account recovery (i guess login is made with an additional magic string from the smartphone).
In my Web API, for the sign in process, the user sends the following data: phone number, smartphone id, and sms verification id and code.
That's when the business rules for authentication take an important role:
If the smartphone id doesn't correspond with the phone number stored in the database (maybe the phone was changed or reset), the server assumes that the number is already owned by another user and responds with 409 (Conflict)
If the number is not owned by anyone, the server responds with 403 (Forbidden), that means that you're free to register a new account with that number.
The successful path is when the smartphone id corresponds with the phone number, two tokens are returned to the client (refresh and access tokens).
For registering (sign up) there's also a almost similar set of business rules, the registering process also requires the user email for later account confirmation (and invoices), this confirmation effectively associate the phone number and email with that client.
That same email can be later used to recover a account (if the user switched smartphone or number), thus preventing the common problem associated with phone number authentication.
I choose to decouple Identity from my domain model, which is named PhoneNumberAuth (i even created a bounded context).
I have a load of questions concerning this. ASP.NET Identity it's the common way to do authentication in standard ways (email, external, etc).
Should i extend Identity classes to cover my custom business rules? If so, what's the best path?
Should i instead create a façade classe to implement my business rules? Like i did here: https://gist.github.com/Henry-Keys/856bc84355b30c4095c88b8c28d547da
In one or another case, i will end up using Identity for Authorization (roles, claims, etc).
I just want help (or a guideline) to end up with the best solution.
[EDIT]
One thing that i want is to generate email confirmation token, Identity provides a easy way to generate and manage them. But it's difficult to integrate Identity with my custom authentication in order to achieve that.

OAuth 2 with JWT in Web API with 1-N callers from the same customer

Yes, the title of this question is horrible but after 5 minutes of trying to figure out how to word it I moved on!
I am starting the design phases of a stand-alone authorization server (C#, Web API, Azure) for a software platform that is receiving a significant overhaul. I read the always great articles by Taiseer Joudeh (http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity) on the subject and have the implementation mostly mapped out in my head. The external users of the authorization server (app developers who will be consuming the services from various end points) will have a portal that they can log into and manage their accounts, white list IP addresses, select their API version (similar to how Stripe does it) and other various administrative tasks.
What has me hung up are the two different real world (happens today) scenarios where a caller has more than one unit on their access access the API and processing transactions. Below is a summary of the current requirements (could change, nothing is set in stone if there is a good argument I have not considered) as well as the two scenarios I am struggling with.
Question: Do I allow my authorized customers (customers with access to an account on the auth server to define 1-N number of "apps" that will have their own refresh/auth tokens...
Facts:
Many of my clients run multiple servers which process transactions through the platform. These may be dedicated on prem servers or worker roles in Azure and everything in between.
The implementation must support long periods of time between API calls without the need to fully reauthenticate. Some clients make calls once a month.
I like Box's implementation: Refresh tokens are valid for 60 days, access tokens are valid for 1 hour. Each new access token provides a new refresh token.
The customers within the portal will have to "whitelist" their IP addresses and new access tokens (and with them new refresh tokens) will only be handed out to a request coming from one of their whitelisted IPs.
The token must contain the version number for the application for which the token is being requested for use in the destination app (controller selection). See SO for more details.
Every "refresh" of the access token issues a new refresh token.
The refresh tokens are not "burned" until the first successful call with the new access token (in case the new access token is lost in transit, the client can obtain a new access token with the previous refresh token).
I have not committed to this yet but it seems like a value add with little downside given the whitelisted IP addresss.
Access tokens will have a very short life (15 mins). This is both for security purposes as well as API version migrations since the version will be in the token.
Concerns:
Two different scenarios in a multiple caller scenario:
On Prem Servers: To me it makes complete sense in this scenario to allow the customer within the authorization server portal to define 1-n number of callers, each representing one of their servers which will be making requests. In this scenario there is no shared cache and it would be very difficult (if not impossible) to allow a shared refresh/access token. What would happen the first time multiple servers received a 401?
WorkerRole (Azure): In contrast to the On Prem Server config, it would be very difficult to support multiple refresh/access tokens without some config file wizardry where each scalable unit was aware of its place in line (i.e. what instance number it happened to be). In this scenario the customer would have access to shared cache and could implement a concurrent collection or the like to keep track of the current refresh and access token and the first caller to hit a 401 could block the others while the new access token was obtained.
* Update based on Brice's Answer *
With respect to client/application credentials there are in fact both but I wanted to clarify what my current plans are which now include Thanktecture. I used it back in the WS-Fed (v2 I believe) days and have not looked at it for OAuth2 but I will.
Each customer that has been granted access to the API (think of these as the parent accounts who then have many child accounts under them who do not have API access) will have a login to the API portal (likely Identity 2.0 based w/an MVC or Angular front end). In this portal they will be able to manage their account (set API version for a particular application amongst other things). Here is where they will be able to "create" application credentials assuming that dynamic registration is not implemented. They will not be using the Identity 2.0 portal account creds for their clientID. I will most likely be generating these credentials dynamically (clientId and secret) with some strong random password generation code.
The question heart of the my initial which you touched on was whether I should allow the creation of one and only one client ID/secret and not enforce a one active refresh/auth token per clientID constraint OR allow them to create 1-N and create a 1:1 between that particular client ID/secret.
It is very unlikely that I would ever need multiple different permissions/roles for specific customer against a specific application. In other words if CustomerA had the ability to call POST against a specific URI, that will always be true and if it changes it would change for that customer across the board. As a result my plan was to set application specific permissions at the customer level (that identity 2.0 portal account I referred to above) and that creates an abstraction of sorts if I go with the 1-N clientID/secrets under the account. Each of those clientID/secrets would inherit those permissions.
I am ashamed to admit as I had started crawling down the proverbial rabbit hole that I neglected to consider the possibility of allowing a 1:Many relationship between the clientID/secret and active refresh/auth tokens. I kind of had it in my head that they would be tied together and would only ever exist as a pair. In this scenario, if a user had 3 active agents running against the API, the third one to obtain an auth token (and as a result a new refresh token) would have broken the ability for the other two agents to obtain a new auth token without fully reauthenticating since agent 3's refresh token was the last one granted.
In the 1:Many scenario each and every authenticating agent coming from the white listed IP, using the clientID/secret would get a valid refresh/auth token for their own use. This really solves all of the problems I described but reduces the visibility a little on "who" the caller is or how many callers there really are if they are behind a load balancer.
Of course the balance I am trying to strike is that of solid security coupled with a relatively painless implementation for the end user who today is familiar with a key-value-pair in a json object implementation for authentication and authorization.
Having developed a similar architecture I can see you supporting one of two scenarios (or possibly both):
Allow customers to share application/client credentials across multiple instances (servers or worker roles) of the application.
Require customers to use a unique set of application/client credentials for each instance of an installed application.
You don't mention use of client or application level credentials, but I am assuming these are in use rather than supporting unregistered clients. In other words when a customer registers their application (or application instance) and supplies their IP addresses, you return a unique client ID (and often a client secret). This client ID and secret is then used by the customer's application to request an access token and refresh token combination.
An access token and refresh token combination should be unique for each application instance. It is also acceptable (and somewhat common) for a single application instance to request multiple active access/refresh tokens. An example is when you have two API endpoints that might require a different authorization level, the application could request two access/refresh tokens each with a different set of scope values (authorization) to be used with these endpoints. In your scenario each application instance (server or worker role) would request it's own access/refresh token combination and independently recycle these. The more interesting question in my opinion is whether these application instances share the same client credentials, or use a unique set.
The OAuth 2.0 Threat Model encourages use of installation specific client secrets (see https://www.rfc-editor.org/rfc/rfc6819#section-5.2.3.4). It uses the wording "An authorization server may issue separate client identifiers and corresponding secrets to the different installations of a particular client" (emphasis mine). However, I have found in practice that there is little to stop a client from reusing client credentials for multiple instances with native and mobile applications.
With the additional protection of white-listing customer IP addresses, I think you would be fine without using unique client credentials per application instance. That being said you should fully consider all threats unique to your system that may attempt to exploit this as a weakness. One possible way to address this would be to use a dynamic client registration process to automatically issue client credentials for each new application instance. See OpenID Connect Dynamic Client Registration 1.0 (http://openid.net/specs/openid-connect-registration-1_0.html) or the draft OAuth 2.0 Dynamic Client Registration Protocol (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-dyn-reg-21) as examples of this. Again this may be difficult to enforce that a customer uses dynamic client registration, rather than simply reuse a single set of application/client credentials.
In closing, may I suggest rather than designing an OAuth2 authorization server from scratch that you look at the excellent open source Thinktecture IdentityServer (https://github.com/thinktecture/Thinktecture.IdentityServer.v3) (no affiliation) platform as an extensible starting point.

designing secure intranet (ASP.NET) application

I am wondering if i need to add any other kind of security on this asp.net application - web forms (available only on network domain and through VPN connection)?
Application Environment: Asp.net 4.0, Vb.net, Oracle 10g, Web Services, Window server 2003 or 2008, Hosted on domain
User Authentication Mode: Window (Not using asp.net membership)
Authentication Scenario:
Application is accessible via intranet site and system authenticates user with his system user name. On the default page system will first get the current user name (HttpContext.Current.User.Identity.Name) and then match it in the user table (oracle DB), if it is matched then store procedure will return all the access permissions (menu details) relevant to this user group. There is a user group and permission table in the oracle DB.
In the store procedure, system will also check the user permissions before any DML transaction.
Main security concern
Major: restrict people to access the information depends on their permissions. Normal user shouldn’t get access to other’s data.
Minor: We don’t want anyone to get into our system outside office network.
As Joachim says, this arrangement only supports Windows systems running on the local network. Shifting to basic authentication will allow more clients to connect but exposes the passwords on the network (effectively in clear text) without HTTPS. Forms authentication is similar.
Without server authentication, users could be redirected to a similar server without their knowledge or suffer a main-in-the-middle attack. HTTPS gives you this with the server certificate. This may not be a concern on a local network but users' hosts (in c:\windows\system32\drivers\etc) files are often vulnerable.
Without encryption, any user can sniff the information sent back and forward over the network assuming they are on the same subnet. This may be an acceptable risk for most applications but not if the information is sensitive, e.g. contains sensitive or personal information.
Consider replay attacks (see How do I prevent replay attacks? for an example) if people are performing important operations like approvals.
Consider auditing access to the database, particularly the user group and permission tables. Someone could add themselves or move them into a group, perform an operation then remove themselves. Check your pages for SQL injection and similar attacks which could accomplish this.
In summary, how likely are people to compromise or interfere with the system and how much are you willing to invest to protect it? Assuming the server can handle the load, HTTPS is a hard to go past as a first step.
Unsure what kind of ASP.Net technology you are using (MVC/Razor/Web Forms).
If you are using Web Forms, then you can immediately take advantage of ASP.NET Login Controls like LoginView Control. They work with ASP.Net Forms Authentication (with or without using ASP.net Membership). You can also take advantage of Roles.
Your intranet server should be "protected" if it's not exposed in your network publicly (in any way). Of course that's a bold statement that depends entirely on your network implementation - e.g. subnetting, internal net/no nat/route/no port forwarding, no dns, etc. This makes VPN as your only point of exposure from the outside, then you must enforce proper security policies for your VPN infrastructure - e.g. one-time passwords, client inspection, etc.
Update:
If you are using Active Directory, you can create users/groups in AD to provide access accordingly (e.g. Finance AD group can only access "finance" folder). I haven't kept abreast with browser support for NTLM outside of Internet Explorer however.
You did mention user data is in an Oracle db however(?). I'm not familiar with solutions that allow no login screen access (to network resources) using a db/Oracle.....
Also, that would mean one-time passwords for VPN access may not be available. Look into token based VPNs so users can still use their AD credentials but need a new token each time - this will help mitigate the "passwords in yellow sticky notes" (because you can have tighter control over tokens).

What is phrase "URL reservation in HTTP.SYS" means?

Can't understand the meaning of this phrase. People on forums suggests each other to reserve url in HTTP.sys, but what does it mean? What is it for? How does it works?
All it comes from HttpWebRequest uac problems.
Several Win32 APIs and .NET framework components (such as WCF) utilize the HTTP Server API when they want to send or receive HTTP requests targeted at the local machine. The HTTP Server API basically provides such functionality in a manner managed by the OS without the need for deploying a standalone web server such as IIS on the machine.
At this point it's probably best to quote the Dev Center page linked above:
A reservation persistently allocates a portion of the URL namespace to
individual users allowing them to reserve or "own" that part of
namespace. Reservations give the user the right to register to service
requests for the namespace. The HTTP Server API ensures that users do
not register URLs from portions of the namespace that they do not own.
In order to ensure namespace security, ACLs (Access Control List) are
applied to the portion of the namespace reserved for each user.
Reserved namespaces are identified by URL prefix strings, formatted in
the same fashion as URL prefixes used for registrations. This means
that all the various host specifier categories are also available for
reservations.
Namespace reservations are persisted across reboots, and changes take
effect dynamically so there is no need to stop and restart the
machine.
What this means is that before the HTTP Server API allows you to listen to incoming requests to a particular URL namespace (think of that as a "URL path"), you have to register for them. Registration is performed on a user account basis as stated above, so what matters here is the user account under which the process that wants to listen to the request runs, which may be different than the account of the currently logged in user.

Categories