3

In the application I am currently developing we are using ASP.Net forms authentication to grant the user further access to the site. This site is targeted towards mobile users and as such we are attempting to be as hands off from the server as possible and make use of KnockoutJS to make the web service call and load the data so that the user can view it.

Right now the webservice (REST service using GET method) requires the username in order to load the data specific to that user. I have this information on the server side (ASP.net) and I can easily access either User.Identity.Name or access the forms authentication cookie directly and pull the information.

My problem is that I need to get the username from the server to the client so that the service call can be made. I have looked into doing this securely but so far have come up blank. Currently I am passing the username as a url parameter and parsing it out using JavaScript, with a check on the Page_Load method to verify the username in the url matches the logged in user.

I need a way to secure pass a username from ASP.Net that has authenticated the user using form to the client side JavaScript so I can make a REST webservice call.

EDIT: So after googling and meeting with my team lead I think we will be using an OAuth implementation similar to this example:

http://www.c-sharpcorner.com/UploadFile/surya_bg2000/secure-wcf-restful-service-using-oauth/

Also for anything else looking for the same answer I found this question very helpful in understanding OAuth:

What's the point of a timestamp in OAuth if a Nonce can only be used one time?

Assuming everything is implemented correctly would it be more secure (totally secure, secure, or more insecure?) to instead pass the generated signature via an ASP tag as mentioned below?

EDIT 2: After some more review and some more searching we finally decided on a framework and method of making this work. As it turns out OAuth isn't necessarily the answer here, this questions:

But Seriously.... Example of ASP.NET WebAPI implementation including OAuth

was a lot of help as well in figuring out how to make this work. What we are going to end up doing is generating the signature and putting in on the javascript and making the call like that. The signatures are going to be time sensitive and regenerated each time the user loads the page so very OAuth like but we arent implementing the full spec.

TL:DR Final solution was to generate a hash signature and put it on the page via ASP server tag <% aspvar_here %> and use it to validate the service call

Community
  • 1
  • 1
Pseudonym
  • 2,052
  • 2
  • 17
  • 38

3 Answers3

2

Simplest way would be to render this javascript in your page:

<script type="text/javascript">
   window.UserID = '<%=HttpUtility.JavaScriptStringEncode(this.User.Identity.Name)%>';
</script>

Now you can reference it in your JS.

But, more importantly, if this user id is not used just as a default parameter but instead to authenticate the user, this is a security hole. Normally the REST service should also be able to look at User.Identity.Name instead of receiving it as a argument.

Knaģis
  • 20,827
  • 7
  • 66
  • 80
  • What about encrypting on the server, passing it to JS like you stated above, and then decrypting in the web service? Could you maybe elaborate on the security of doing something like that? – Pseudonym Nov 13 '12 at 18:44
  • Yes, you could do something like that with the encryption. But - you should then make sure that the encrypted data is safe from being reused - for example, encrypt a timestamp as well and when decrypting, check that the timestamp is within last X minutes. Otherwise someone might steal the encrypted username once and then keep using that to fake authentication. – Knaģis Nov 14 '12 at 08:22
  • Thanks for your help, this is solution we are going to end up using – Pseudonym Nov 14 '12 at 16:53
1

Normally the username is provided by the client to begin with. It is then verified on the server-side (using whatever authentication is necessary, such as a password).

If it has been verified on the server side (in your case, this must be from a WCF web service as ASMX does not cope well with REST), then you can be sure that it is correct - plus you already have the username on the client-side.

EDIT: As Knaģis pointed out, you can get it using an ASPX tag, presuming the page is an ASPX page and not HTML.

Dan Ware
  • 396
  • 2
  • 9
0

If you just want to have the username in the client side, the other answers explain how to do this.
But as you stated, this IS a security risk. Someone can modify the data on the client and impersonate another user.

The correct way to do this:

  1. After a user successfully logs in, a Guid is issued which uniquely identifies this user.
  2. The Guid is the token which is saved on the client and passed to the server not the username.
  3. All webservices receive the Guid not the username.
  4. Server has a dictionary which converts the Guid to the original username.

Another option can be to encrypt the username and pass the encrypted value to the webservice. The webservice will need to decrypt the value in order to get the username .

Community
  • 1
  • 1
Blachshma
  • 17,097
  • 4
  • 58
  • 72
  • Definitely a good suggestion, my counter question to this would be: is there a way to do this without modifying the existing web service as is? – Pseudonym Nov 13 '12 at 18:12
  • Well, if your webservice receives **ONLY** a username, and returns info based only on that - then you probably have no choice since there is a serious security/design flaw here. On the up side, whether you choose to use a Guid OR an Encrypted username - It's still a string value so it won't break the WSDL, all you have to do is change the inner logic of the Webservice – Blachshma Nov 13 '12 at 18:15