I have an asp.net application that accepts User Name as Form Post value, and authenticates based on the posted value.
in Page_Init of my Login.aspx, I have below code
if (!String.IsNullOrEmpty(HttpContext.Current.Request.Form["username"].ToString()))
{
//my logic to authenticate, authorize, redirect to page
}
It works fine so far. I had to add this because I have an external authentication system in my company which does all authentication part and send user name to the Application accessed to auto-login within the application.
Though it works fine, I want to add an additional layer of security on top of this Posted user name. I want to identify if this Post request came from our Gateway website. My questions are
Is there a way to identify the URL posted to my Login.aspx?
If not, is there a way to identify any other client information to validate the post?
I don't want anyone who creates a simple HTML with post variable "username" get access to my application. Thanks for your insights on this.
Is looking at one or both the values in Request.UserHostAddress and Request.UserHostName fine?
Is there a way to identify the URL posted to my Login.aspx?
No.
If not, is there a way to identify any other client information to
validate the post?
Well, the only reliable information is the client IP. So if you know the address of the application that will be sending this HTTP request you could use HttpContext.Current.Request.UserHostAddress to compare against.
As an alternative you could share some common secret between the client application and your server. And then in addition to posting the username, you could require the client to POST some additional message that will be signed with this secret. Now the the server can verify the signature and guarantee that it is coming from the client (because it is the only one who knows how to sign the message). This process is called Digital Signature and guarantees that a message hasn't been tampered between a sender and a receiver.
Related
I have to start a new project to be developed in MVC 4 and Web API. I have prior experience with MVC 4 but with Web API this will be my first project. I understand that web api is there to be consumed by different platforms.
I have a few concerns related to web api. I am presenting them to you guys as following:
1) My first concern is related to user authentication. I looked into this SO question and followed the link1 and link2 given in the selected answer. I still have a couple of questions:
a) When we do user authentication through Form Authentication we create a cookie, that track if the user is authenticated or not, but with web api we do not store cookie, instead user credentials are passed in content header. I didn't get how user's logged in status is tracked in this case ?
b) My another concern is related to restrict unauthorized access, which I think I can find find out in link 1 and link2 provided above, if I am not wrong.
c) I looked at the Edward Brey answer (in the same SO question) as well for authentication but I didn't get the idea completely.
2) My second doubt is about mixing Form authentication and Basic Http authentication. Is it possible that for login I use forms authentication and then for consuming web api I use basic http authentication? If yes then please guide me.
My questions may sound inappropriate but please bear with me
1.a) Restful APIs are stateless, so you are not keeping track of user's logged in status, rather you are sending credentials which are verified for each of the requests
1.b) Yes, if not there are number of articles on web for that. Authorization Filters can help you in achieving this.
1.c) In short, he has mentioned simple logic to authorize user before executing any of the methods in your API. Call EnsureAuthenticated before executing any of the methods in a controller, or put that logic in you Authorize filter.
2) Yes you can do it. In Restful API's each call can be a new instance and you can pass in credentials with api requests whichever you are making.
If you go in discussion of Link 1 that you have provided, you will see:
In our specific case, the server generates the auth token by encoding
the concatenated username and password as Base64 (the reverse of what
is described in the article) and sending it back to the client via a
HTTP header when it performs their ‘log in’ action. The clients then
store this auth token and send it with each subsequent request that
requires it.
If the format of the auth token is well known (as it is in my case),
you could also just generate this yourself on the client and send that
without having the server do this work.
You can use your login to generate an authentication token for client, which you can use to send attached to your web api requests.
I have just started to learn C# and Asp.Net and I have a specific project in mind but I need to be able to manipulate cookies client side and I can't find good documentation for this so I decided to ask for help to get a starting point.
I want to make a desktop application that is a little to complex for my actual knowledge but I need a starting point: I need to be able to load a list of usernames and passwords and proxies and proxyuser and proxy pass. This little part of the application will use the accounts and proxies to login to a webpage using httpclient. When I send a GET request to the login page I get back a response that contain some hidden parameters that I must assign to some variables and a cookie. I don't know how to save that cookie in a location that I choose (the application folder under the "cookies" folder) with the name that I choose (the username used for login should be the name of that cookie). After I sort thru the response I have to send a POST request to the server with all the hidden parameters and the user and pass parameters and the cookie. The server will send back a response with another cookie that I want to save in the same location as the first one with the same name (overwritten ). This cookie will be used later in the program to do other actions on that server under that login. All this requests must use a certain proxy with its credentials, proxy that will change every time I use a new login.
I managed to find out how to use the HTTP Client from Asp.Net Web API to send the get req or to post but I have no idea how to get such a control over cookies that the site want to store on my computer and how to use different private proxies for each login... I did all the above using PHP and CURL and is very easy to control the cookies using cURL but I need to do it in C# and make a desktop app so ... Asp.Net Web API and HTTP Client is the key I think...
Please give me a hand to start my project and don't dismiss my question just because I'm to noob with .net or c# :)
Thank You!
Get this library http://nuget.org/packages/Microsoft.Net.Http/
Create an instance of HttpClientHandler. It has a CookieContainer property. You can set all the cookies you want in there.
Create an instances of HttpClient as pass the HttpClientHandler instance into the constructor.
All HTTP requests you make with HttpClient will now have the cookies attached.
I found a strange thing when i'm coding a net-spider to a specific website.
I used fiddler and chrome(as well as other web-browsers) to log-in a website(HTTP, not https) and get all package(as well as the cookie) that sent and received:(
first package 'Get' to request the log-in page and the cookie, then use the cookie received to request verification code and some other pics. and then send login request with userid, password and verification code to server and server response with correct info)
Then I log-out and Clear all Cache and Cookie and use Fiddler to Relay(Simulate) the whole process (Since I know all packages' format that i should send): request the log-in page to get cookie, use the cookie to request all pics( auth code image included), and then use the cookie and auth code to request login(userid and password are correct)...but failed.
I'm sure the failure is not caused by invalid userid or password or auth code, and i believe there is nothing special on the front-end(html,script are checked), but it puzzled me a lot how can the server tell i used browser or not in back-end..
I'm not request anybody to solve the specific problem. i'm just wanna know DOES ANYONE HAS HAD SIMILAR PROBLEM i described?
the specific website is not important and i must say the whole practice is completely harmless! i'm not doing any hacking stuff, on the contrary it will help some people.
======================================================
I've finally figured out the reason: the log-in page has a hidden input() and i carelessly overlooked that since its value looks almost the same every time. Web server can not detect replayed log-in attempts if we simulated all necessary HTTP request packages.
Thank you guys~
Servers cannot magically tell whether they're talking to Fiddler or not.
If Fiddler and your client are sending the exact same requests, that means that the server in question is using a "one time token" (sometimes called a nonce) in its login form. If the server ever sees the same token again, it rejects the logon. Sometimes the nonce isn't sent directly, and is instead used in the computation of a "challenge-response" as occurs in authentication protocols like NTLM. In other cases, the nonce is a CAPTCHA, which helps prevent you from using a bot to automatically log in to a site like this.
Unless you can share more details of the target site (or a SAZ file of the login process), it's unlikely that folks will be able to help you.
I want to create a authorization mechanism for an application based on WebAPI and AngularJs.
I've seen some articles, which use BasicHttpAuthentication, but i really don't like the whole idea of sending username, and password on every request. The more it doesn't fit for me is because i want to use OpenId authentication, where you don't have username/password pair.
I'm thinking about a solution, but I don't really know how to implement it. The concept is that user is authenticated as in an usual Web application - posts a form with user / password or selects an OpenId provider. If the user is authenticated succesfully, it is placed in a static object, which stores the User object for a certain ammount of time. Next a usertoken is generated and passed to the Client Application. The client passes the token on each request to the server, if the user exists in the above mentioned static object with the appropriate authentication token it is authorized to get the data.
Firstly - Do you think this is a good approach to the problem?
Secondly - How should I pass the authentication token, WITHOUT using cookies? I guess it should sit in the request headers, like in BasicHttpAuthentication but, I really dont' know how to handle it.
BasicHttpAuthentication
I'm with you on feeling dirty about caching the username and password on the client and forever transferring it with every request. Another aspect of Basic authentication that might work against you is the lack of sign-off. Other than changing the password, you can't "invalidate" a basic authentication session. Tokens on the other hand, will typically offer an expiration date, and if you want server-side invalidation you can check the issue date and say "any tokens older than issue date xyz are invalid".
Server State
You mention "If the user is authenticated successfully, it is placed in a static object". But this is independent of the token? This sounds like you're wanting to implement server state management of authentication sessions, but this isn't strictly necessary. The token itself should be sufficient for user authentication, managing server state is another potential obstacle. Server state can become difficult to manage when you factor app-pool recycles or web-farm environments (what if you want two services to share the same authentication token, but not require communication with a central "authentication server" for storing the state / session?)
Passing Authentication Token
Headers is definitely a good place for it. Really, where else is there? Cookies, Headers, Message. Other than a browser client, cookies don't make a lot of sense, and including it in the message can muddy your message formatting a bit, so headers is the only remaining option that makes much sense in my view.
Client Implementation
You've not specified, but I suspect you're interested in calling the service from .NET? In which case System.Net.Http.HttpClient could be your friend. In particular, the DefaultRequestHeaders collection. You can use this to add a custom header to store your authentication token.
Server Implementation
When researching ASP.NET authentication recently, I learned a lot about customisation by examining the Mixed Authentication Disposition ASP.NET Module (MADAM). I wasn't interested in using MADAM as-is, but learning about it from that article and examining the source code gave me a lot of ideas of how I could insert my own authentication module into the web stack.
I have an asp.net application in which I have used forms authentication.
Now, there is a need that user authentication is done outside of my application.
There will be an intro page which will do needed authentication.
Then, after authentication is successful user should be redirected to my app.
Of course, if user is not authenticated via that external page and tries to access my app directly, I need to redirect him back to this external log in page.
What's the best way to implement such a functionality? One way which I think is feasible is that I transfer some particular encrypted string in cookie from external login page and verify it in my application. So, based on that, I can see if user is authenticated via this external page or not.
Your own suggestion of validating the external site's cookie is how I would implement this functionality as well.
I would simply go with adding a Webservice in the first application that you in your stage can connect to a check if the user is logged in, the only problem with this is that you need to know which user whants access to your site and also to confirm that this is truly that user (So a user cant use other users who are logged in). This info could probably be sent via a cookie.
You probably should no be rolling your own single sign on solution in 2011. Rather, you should look at some emerging standards -- particularly OAuth and OpenID. Getting rolling with them is easy -- check out the OpenID website template on MSDN.
At the end we decided to use SAML 2.0 protocol.
External login page posts SAML complient XML digitally signed with certificate to other application. In this XML authenticated username is transferred. Application which receives this XML verifies digital signature with certificate's public key, and if validation is OK, reads username from XML, applies internal application authorization logic and at the end creates auth. cookie. We will probably add encryption so data protection would be complete.