What to do to make webapi's action secure? - asp.net-mvc

I have made a webapi which has few actions and one is AddManualDate which accepts a parameter of the object type. It is consumed by Android devices. It works. But the problem is that the link is now exposed to the public and anyone can use it in a bad way. How to control it ?
my link for example:
http://www.testing.com/api/AndroidOperations/AddManualAppointment
now, this can be accessed by anyone. So what to do?

A common way to do this is using a token based authentication. Your client has to call the token api first, to get a token and pass it to every request against your api.
This is normally done by OWIN and OAuth. The following link describes the matter:
https://blogs.perficient.com/2017/06/11/token-based-authentication-in-web-api-2-via-owin/
Since this is a very general question, I can't give you a simple example.
Feel free to ask again if you get stuck in a detail. Happy coding!

Related

Unable to Access Reddit Api Implicit Grant Flow Due To Fragment Identifier Before Query String

I've searched pretty hard for an existing answer to this question because I have a feeling that I've made a stupid mistake, so please let me know if this has been asked already and I haven't found it.
I'm trying to make a little installed app that needs to access the OAuth Reddit API, and since it's installed it has to be by the implicit grant flow.
Here is the process I'm trying to use:
I'm having the user open this URL (private info removed):
https://www.reddit.com/api/v1/authorize?client_id=[client_id]&response_type=token&state=[random_state_data]&redirect_uri=http://localhost:3000&scope=read
But when the user gets redirected after authorizing it goes to a URL that looks like this:
http://localhost:3000/#access_token=[token]&token_type=bearer&state=[random_state_data]&expires_in=3600&scope=read
The problem is that the access token is in a query? string after the fragment identifier (the #), so I can't access it from a server hosted on port 3000. Have I made a mistake with how I handled the authentication? Or is it something more subtle?
Thanks in advance for your help, and let me know if you need more information or I made a mistake in asking this question.
It turns out this is a classic case of missing something in the manual.
In the information about Reddit's Implicit grant flow:
he response from this request, if successful, will be form encoded into the fragment with the following values:
So it was totally intended behavior that I just didn't pick up on. I guess I'll just have to do some Javascript magic to get the token from the fragment to my server.
Sorry if I wasted anyone's time.

Hiding parameters (sensitive information) from URL of an MVC 5 application

I am working on Asp.Net MVC 5. When i click a link (placed in another website) I navigate to UserDetails.cshtml page. Basically that 3rd party site is passing the UserName & Password to my site & using that I authorize & display further user info.
It's fine but the Url is looking like this
localhost:8080//Admin/UserDetails/UserName/PWD.
I don't want to show the UserName & Password in URL i.e URL should look something like :
localhost:8080//Admin/UserDetails/
One possible solution could be rewrite the URL in IIS (http://www.hanselman.com/blog/ASPNETMVCAndTheNewIIS7RewriteModule.aspx)
But I believe there is an easier way to handle this by using the routing mechanism of MVC.
Please help me to figure out the same.
EDIT :
As many of you are confused why I am not doing a Form Post here, let me re-frame my question. I have no control over the third party application, so I cant request them to do a form Post to my MVC application. Again the 3rd party application is a Oracle Reporting application (OBI), so doing a POST from that application might not be feasible too...
Let me reverse engineer your requirements from your question:
I want to have an URI that when invoked will give access to a secured section of my website. This URI must be clicked by visitors of a third-party site, whom I give that URI to. I want to hide the credentials from the URI.
You cannot do this, the requirements are conflicting. You cannot hand out URIs that will authenticate anyone who fires a request to that URI.
You could do something with a token (like http://your-site/auth/$token), but then still, anyone with access to that URI can use it to authenticate themselves, or simply put it up on their own website.
If you have data you want to expose to a third-party site, let that site perform an HTTP request (with tokens, usernames, headers or whatever you want to use to authenticate) in the background to your site, and display the response in their site. Then the visitor won't see that traffic, can't share the URI and all will be secure.
No. No. NO. Like seriously, NO. Any sensitive information should be sent via a post body over a secure connection (HTTPS). You can't "hide" information in a GET request, because it's all part of the URI, or the location of a particular resource. If you remove a portion, it's an entirely different location.
UPDATE
I find it extremely hard to believe that any third-party application that needs to authenticate via HTTP and isn't designed by a chimp with a typewriter, wouldn't support a secure method to do so, especially if it's an Oracle application. I'm not familiar with this particular app, but, and no offense meant here, but I would more easily believe that you've missed something in the documentation or simply haven't found the right way to do it yet before I'd believe you have to send clear-text credentials over GET.
Regardless, as I said previously, there's no way to hide information in a GET request. All data in a GET is part of the URL, and therefore is plainly visible in the browser location bar or whatever. Unfortunately, I have no advice for you other than to look closer at the documentation, even reach out to Oracle if you have to. Whether by post or something like OAuth, there almost has to be another way.

How should I secure my SPA and Web.API?

I have to implement a web site (MVC4/Single Page Application + knockout + Web.API) and I've been reading tons of articles and forums but I still can't figure out about some points in security/authentication and the way to go forward when securing the login page and the Web.API.
The site will run totally under SSL. Once the user logs on the first time, he/she will get an email with a link to confirm the register process. Password and a “salt” value will be stored encrypted in database, with no possibility to get password decrypted back. The API will be used just for this application.
I have some questions that I need to answer before to go any further:
Which method will be the best for my application in terms of security: Basic/ SimpleMembership? Any other possibilities?
The object Principal/IPrincipal is to be used just with Basic Authentication?
As far as I know, if I use SimpleMembership, because of the use of cookies, is this not breaking the RESTful paradigm? So if I build a REST Web.API, shouldn't I avoid to use SimpleMembership?
I was checking ThinkTecture.IdentityModel, with tokens. Is this a type of authentication like Basic, or Forms, or Auth, or it's something that can be added to the other authentication types?
Thank you.
Most likely this question will be closed as too localized. Even then, I will put in a few pointers. This is not an answer, but the comments section would be too small for this.
What method and how you authenticate is totally up to your subsystem. There is no one way that will work the best for everyone. A SPA is no different that any other application. You still will be giving access to certain resources based on authentication. That could be APIs, with a custom Authorization attribute, could be a header value, token based, who knows! Whatever you think is best.
I suggest you read more on this to understand how this works.
Use of cookies in no way states that it breaks REST. You will find ton of articles on this specific item itself. Cookies will be passed with your request, just the way you pass any specific information that the server needs in order for it to give you data. If sending cookies breaks REST, then sending parameters to your API should break REST too!
Now, a very common approach (and by no means the ONE AND ALL approach), is the use of a token based system for SPA. The reason though many, the easiest to explain would be that, your services (Web API or whatever) could be hosted separately and your client is working as CORS client. In which case, you authenticate in whatever form you choose, create a secure token and send it back to the client and every resource that needs an authenticated user, is checked against the token. The token will be sent as part of your header with every request. No token would result in a simple 401 (Unauthorized) or a invalid token could result in a 403 (Forbidden).
No one says an SPA needs to be all static HTML, with data binding, it could as well be your MVC site returning partials being loaded (something I have done in the past). As far as working with just HTML and JS (Durandal specifically), there are ways to secure even the client app. Ultimately, lock down the data from the server and route the client to the login screen the moment you receive a 401/403.
If your concern is more in the terms of XSS or request forging, there are ways to prevent that even with just HTML and JS (though not as easy as dropping anti-forgery token with MVC).
My two cents.
If you do "direct" authentication - meaning you can validate the passwords directly - you can use Basic Authentication.
I wrote about it here:
http://leastprivilege.com/2013/04/22/web-api-security-basic-authentication-with-thinktecture-identitymodel-authenticationhandler/
In addition you can consider using session tokens to get rid of the password on the client:
http://leastprivilege.com/2012/06/19/session-token-support-for-asp-net-web-api/

RESTful web services with complex actions (verbs)

I am attempting to construct a web app in which the back end is a complete RESTful web service. I.e. the models (business logic) would be completely accessible via HTTP. For example:
GET /api/users/
GET /api/users/1
POST /api/users
PUT /api/users/1
DELETE /api/users/1
Whats the proper way to provide more methods that aren't CRUD (verbs/actions)? Is this considered more of a RPC-api domain? How would one properly design the RPC api to run on top of the RESTful api?
For example, how would I elegantly implement a forgot password method for a user.
POST (?) /api/users/1/forgot
The application (Controllers/View) would then use a https requests (HMVC like) to access the models and methods. What would be the best for authentication? OAuth, Basic Auth over HTTPs?
Although this is "best practice" for scalability later on, am I over engineering this task? Is it best to just follow the typical MVC model and provide a very basic API?
This question has been mostly inspired by ASP.NET's MVC 4 (WebAPI) and a NodeJS module https://github.com/marak/webservice.js
Thanks in advance
I recently started learning REST, and when developing a new web service I think you're doing the right thing to consider it.
You are correct in your assumptions about the custom verbs. REST acknowledges that some actions need to be handled in a different way, and custom verbs don't violate the requirements. You should use POST when communicating with the server, but the verbs are normally written in imperative. Instead of forgot, I'd probably use remind or something similar. I.e., you should give instructions on what to do, rather than describe what happened without clearly indicating what you expect as a result.
Furthermore, the preferred way to construct the service is to include api into the domain name, and drop it from the path. I'd write your particular example like this:
POST /users/1/remind HTTP/1.1
Host: api.myservice.example.com
Session handling in REST is a bit tricky. The cleanest way of doing it would probably be to authenticate with username and password on every single request, using Basic access authentication. However, I believe that it's rarely done like that. You should read this question (and its accepted answer): OAuth's tokens and sessions in REST
EDIT: I'd also drop the trailing forward slash in the GET request in your example. If the service is truly RESTful, then the resource is not supposed to be accessibly from both /users/ and /users. A particular resource should have one and only one URL pointing to it. A URL with a trailing slash is actually distinct from one without. REST promotes dropping it, and a RESTful web service should not accept both (which in the case of GET means responding with 200 OK), although it may redirect from one to the other. Otherwise, it might lead to confusion about the proper URL, duplicate caching, weeping and gnashing of teeth. :)
EDIT 2: In RESTful Web Services by Richardson & Ruby you're discouraged from putting the new verb in the path. Instead, you could append something like ?_method=remind. It's up to you which one you choose, but please remember that you're not supposed to handle these requests with GET, regardless of what you choose. A GET must not change the resource, and should not cause side effects if the user browses back and forth in the history. Otherwise, you might end up resending the password several times. Use POST instead.

Pylons authentication?

Is there a one and true way to add authentication in Pylons? I've seen so many different ways, but most of them are either outdated or too complex. Is there a tutorial somewhere that explains how to add authentication in a good and solid way?
Pylon's official stance appears to be: We don't do authentication, you can plug in whatever authentication system you want.
Authkit works. It is very basic, but, does a relatively simple job rather well.
Repoze.who/Repoze.what works fairly well and is maintained/developed a bit more actively.
You could use RPX along with openid as mentioned on Tony Landis' blog
Or, you could use BlastOff which contains a bit more than just authentication. It comes with registration, user management, forgot my password functionality, etc.
Think about using repoze.who and repoze.what. They provide a strong pattern for authentication and can be customized easily because its customizable in places that matter.
If you don't get why "what" and "who" are two parts of an authentication scheme all one really needs to know is that "who" authenticates (perhaps with a username and password) and provides an identity of your users and "what" is for checking the authorization the user has in a request. If one wanted they could use "what" or "who" alone. But, IMHO it works best if you use just "who" or "who" and "what" together
Basically it works like this; On each request that requires authentication the "who" will be processed (applying its plugins) when the controller gets called - giving you an identity to work with. That is.. If a "what" is required or abort( 401 ) is called then a login page (a challenge) might be shown if the user needs credentials else a 403 Forbidden is displayed. It works well
Here is a tutorial on getting just "who" to work Authentication and Authorization with repoze.who. It outlines a very simple way to get started.
nope, you are free to choose whatever is appropriate for your application. Now, if you consider that turbogears 2.0 is built on pylons and uses repoze.who for authentication, it would seem in that light that repoze.who is pretty popular and could conceivably be the generally accepted way of doing things according to turbogears. If you are looking for guidance.
AuthKit
http://pylonsbook.com/en/1.1/authentication-and-authorization.html#authkit
I tried repoze.who and repoze.what but I didn't like them. Now, I use a variation of the solution described at http://wiki.pylonshq.com/display/pylonscookbook/Simple+Homegrown+Authentication
The decorator based approach works well also: http://wiki.pylonshq.com/display/pylonscookbook/Another+approach+for+authorization+in+pylons+%28decorator+based%2C+repoze.what+like%29

Resources