Securing communication between mobile app and RESTful service WITHOUT a username and password - asp.net

I've been trying to work out if it is possible to authorize communication between a mobile app and my ASP.NET web api service without the user having to authenticate with a username and password. This is important because users of my app don't login at all and never will. All traffic will of course be sent over HTTPS.
This means I can't use OAUTH or BASIC authentication to authenticate the traffic as these require credentials.
So I need some method to securely store some kind of authentication token that is packaged in the app that is only accessed when it needs to communicate to the server and can't be "discovered" by a determined hacker.
This may of course not be possible.
Thanks.

In general it is not possible. Your server should never trust it's clients. Hackers can examine your client app and create equivalent one.
But you can make life of hackers significantly harder, if you:
Use custom cliest sertificat for HTTPS, look here.
Use temporary access keys in http request. Application should request for new temporary access key your server. Part of the key server will send in response and another part will be sent via Cloud Messaging. Combine parts of the key in some non-trivial way.
Obfuscate your app.

Related

How to secure an API using OAuth Certificate Based Authentication

I have an web application made using servlet and I have an seperate API for the web application. I want to secure the API with OAuth so that when we use OAuth, a client certificate is sent instead of credentials to the authorization server for verification and after verification the access should be allowed to the API. Is there any ways to implement this authentication. If possible what are the steps should I do to achieve this?
Client certificate credentials can be used for confidential clients, in either the code flow or the client credentials flow. This type of solution is often used in financial grade setups, where high worth data is involved.
Access tokens issued then contain a cnf claim, so that every API call is bound to the strong credential used at the time of authentication. See the RFC8705 standard for further details.
For a worked end-to-end example that you can run locally, and which covers both the
backend and client behaviours, see this Curity code example. Not all authorization servers support these flows, so check for your provider.

OIDC: Keep access tokens valid during long-running server operations

If a user authenticates via OpenID Connect on a client and triggers a long-running server-side request, how can the server keep the access token valid if the operation takes longer than the access token's expiration time?
We have an application suite consisting of several server-side backend applications (typically accessed via REST, HTTP, and/or WebDAV), several web frontend applications and several client-side (i.e. desktop) applications. We already support the Basic and Kerberos/Negotiate authentication schemes and are currently adding support for OpenID Connect.
Our backend applications are typically accessed by the web frontend and client applications, other server-side backend applications, and 3rd party customer applications when our software is integrated into their system. We currently pass OpenID access tokens via the Bearer scheme to the backend applications.
In a typical scenario, a user (authenticated on a local client or in a web frontend) triggers a server-side operation which may possibly run for several minutes, hours, days, or even weeks. This operation accesses other backends on the user's behalf, e.g. a Web-DAV based server-side file system, to access additional data. All backend applications need the user's authentication information to grant access and access further user details for authorisation (e.g. to only grant access to the user's own files).
Obviously, this means that the access token provided with the original backend call may expire before the operation is completed. The server therefore needs a way to refresh the access token without user interaction. Our code can already do this if it knows the user's refresh token (using the refresh token and the application's client ID and secret to access the OIDC Token endpoint).
But how can we "correctly" pass the refresh token to the server?
The client has (potentially) the full set of ID, access, and refresh tokens. But from what I understand, the Bearer scheme expects that the passed token is the access token. Compatibility is important here, since our backend applications may also be accessed by 3rd party client applications. Assuming that getting the refresh token into the server application is the correct approach at all, we therefore still have to support situations where the caller can only provide an access token (with the obvious implications that in these cases, long-running operations will not be able to access other backend services on the user's behalf).
I could imagine the server accepting either an access token or a refresh token via Bearer. But from what I understand, the only "argument" a client may pass with a correct Bearer authentication header is a single Base64 encoded string, i.e. the (access) token. The client could pass an access or refresh token here, but I don't see how the server could then tell which it is, as to my knowledge both token types are opaque.
I understand that the original idea is for server operations to be short lived, so that keeping the access token up to date is the client's responsibility. But surely we cannot be the first who do need to combine OIDC with long-running server-side operations. Is there an accepted way to pass a refresh token to a server, or, alternatively, a completely different approach that I'm missing?

How do i pass authorized user from one application to another running in same server?

Architecture of my application is something like this.I have a application which is hub for many other applications which allows user to pass credentials. After credentials are checked, Hub application presents one or more applications which the user is allowed to use. If user has only one application it redirects directly to the application. How do i maintain the authorized state of the user passed in hub application and access them again in the children application?
There is no "one way" to do this. But one way to do this is to provide a Javascript Web Token (JWT) back to the client if they log in successfully. The server can then know, authentically, who the user is that made the request if the client provides the JWT as a request header (typically "Authorization: Bearer JWT- goes-here). You can keep the JWT in some kind of local storage like IndexDB to share between applications (assuming same domain URL) and delete it if the user logs out.
Also, in case it's not obvious, definitely use HTTPS. There is no excuse not to in 2019, with the existence of LetsEncrypt.
if you are using Express.js use express-jwt and jsonwebtoken packages to accomplish this scheme.

Membership / Authorization over a REST service

I'm investigating creating a WCF REST service for an existing asp.net application to be consumed by various clients including Windows Phone 7, Android, iPhone apps etc.
Creating a simple WCF REST service and consuming it from the above platforms is not a problem and works really well. What I am struggling to get my head around is authorization.
The asp.net application uses the Membership provider to provide authentication and authorization and I'm comfortable in using that API from the REST service.
How do I secure my REST service so that the first call has to be to authenticate (passing the username and password) and following calls know who is 'logged in'. I'm guessing the authenticate method will have to pass back some sort of token to be used in subsequent calls identifying the caller. Is this secure enough as the whole site / service is over SSL?
Any suggestions welcome.
The more restful authentication scheme is to use HTTP Authentication, e.g. Basic or Digest. Since your service is over SSL, Basic should be sufficient. The authentification tokens (login/password) are sent with every request, so that the service can be stateless. Every client library that I'm aware of can deal with basic authentication.
In general the token approach is better then just sending username+password (Basic Authentication) in each request. The problem is to implement it correctly: while Basic Authentication is very easy to implement, and actually it's already implemented by most application and web servers, the token is something you'll need to implement yourself - it must be encrypted, so clients won't understand it, so you'll need some keys management, it also must have some expiration date and may be you'll want some revoke functionality.
In addition, it will make client's life harder: instead of just attaching basic authentication header to each request, client must first go to some authentication point, receive a valid taken and then use the token on the requests. If the token expires, the client will need to go to the authentication point again.
So if you have time and knowledge, and your clients are smart, it's better to use the token approach. Otherwise with SSL, basic authentication should be sufficient.
I've seen an example in the latest Windows Azure toolkit for WP7 that might be helpful for you. It basically uses the Membership Provider, logs in a person (the first time the person installs the app) and then generates a Ticket. It then Encrypts this ticket and sends it back as a TOKEN which is then stored on the phone in the isolated storage. The expiration of the ticket is set to int.MaxValue so that the token remains good for a long period of time.
Now, this token is passed over to the Web Services in the Authorization Header where it is decrypted, the identity of the user is verified and then the web service call is made.
Hoping this helps. I am trying to solve a similar scenario and trust me, there isn't much out there that points us in the right direction...which is a pretty sad state of affairs if you ask me.

How do I tighten security of my hybrid ASP.NET 1.1 / Ajax solution?

Scenario
I have an HTML/javascript website that uses javascriptSOAPClient communicate with an ASP.NET 1.1 web service in order to read/write to a SQL database. (http://www.codeproject.com/KB/ajax/JavaScriptSOAPClient.aspx). The database contains anonymous demographic information--no names, no credit cards, no addresses. Essentially the data collected is for data mining purposes.
The site is live, but we want to introduce a more secure communication between the javascript/ajax client and the wbe service for both this and future projects. Working as contractors in the financial industry, at some point we're going to get nailed with the question: is this website hackable? If we don't have a solution we could be out on our ears.
I am already following best practices such as communicating with the database via command parameters and stored procedures). However, currently anyone could browse to our web service description and figure out how to consume our exposed services.
Questions
With my hybrid solution (i.e. not end-to-end Microsoft) how should I go about authenticating client requests on the web service?
If I start passing a username/password or some other identifiable element into the web service as authentication, should I be concerned about how that key is generated/stored on the client side?
A few suggestions to consider:
List the threats, and compare each to your current setup.
Use SSL / HTTPS. This alleviates a whole class of vulnerabilities.
Use username/password, generated on the server side and sent out of band (in the post or by phone) to the user. (Hope this answers question 2).
Use 2-factor authentication. To do this, you can look at security tokens such as RSA's keyfob-type gizmos or look at Steve Gibson's Perfect Paper Passwords
The easiest solution from a programming standpoint is to use two way HTTPS. That is, the server presents a certificate to the client, and the client presents a certificate to the server. Then only clients with proper certs (issued by you) can connect.
That helps reassure clients that your site is not generally accessible, yet the security is transparent to the application and, once they've signed up and received a cert, to them. The downside is that you have admin overhead in issuing and tracking the user certs -- but that's probably less than you'd have dealing with username/password combos.
There are a few simple options:
SSL + Cookie
If the web app is also ASP.NET and hosted along with your web service, then you should have access to the User/Membership/Session of the web app inside your web service (essentially #1, but you get it without doing any work).
If the web app and web service are not on the same domain, then cookies are out due to cross-domain issues - so you can have the web app embed a GUID into a hidden form field, and use that GUID as a sort of cookie (and it will need to be passed as a parameter on all web service requests).
Can you incorporate a certificate authentication mechanism? So that only clients that have keys you can verify can communicate? That's how the product I work with has its managed devices communicate back to the core.

Resources