How to get client certificate inside web method at asp.net web forms c#? - static

I configure IIS to get certificates from client. And I can easily get client certificate inside event handler, for example Page_Load
HttpClientCertificate cert = Request.ClientCertificate;
Now I need to create web method what will get client name from certificate and return data for this client. But how can I get client certificate inside static web method where I don't have access to Request?

In any method, including in a static method, you can use HttpContext.Current. If this is non-null, then you can access the Request property. If that is non-null, then you can access the ClientCertificate property.
Of course, it may be null...

Related

How to hide data received via HTTP requests?

I am currently designing a web application using AngularJS. In this I am fetching and posting data via Rest API(s) with different methods. The data I retrieving is fetched in the form of JSON.
Problem:
Issue here is, while I am using https, the data sent and received via HTTP requests can still be seen in proxy tool or traffic monitors. All the JSON can be easily read from this.
Each of my request has a token attached in it's header which takes care of authentication. However, once authorized, there is some part I don't want to be displayed in/ caught in such monitoring tools.
Question:
This data is stored in an encrypted way in database and all, however while coming via HTTP request, it is first decrypted and then sent. How can I hide/protect this data?
You can't.
If you give it to the client, then the client has to be able to see it.
If the user has configured their browser to proxy requests, then the proxy is the client.
Once the data leaves your server in an HTTP response then anyone/anything thing the user of the client wants to trust with that data can access it. You don't have control at that point.
proxy tool or traffic monitors will see https data only if the client has accepted the man-in-the-middle (MITM) by installing the ssl certificate used by the MITM:
To see the content (other than the host name) of an https connection, someone who is neither the client or the server must do a MITM.
If someone do a MITM with a certificate not trusted by the client, the client will reject the connection.
WARNING: If the server do NOT use HSTS, the person doing the MITM can do an SSLSTRIP attack if the first connection is http. In that case, the MITM do not need a trusted certificate because the connection will stay in plain text (http)

How to secure client data in Angular JS?

I have developed a single page AngularJS application. For data retrieval/storage, it communicates with REST APIs over https. As per client requirement, i need to implement Client Authentication. i.e., As the application is based on REST APIs, how can we ensure that the request made to API is from a valid client and not from fiddler or a tempered client.
the current approach is:
1> configure a client secret and a key in the angular app.
2> authenticate the client by requesting a token from server using this client secret and key.
3> server checks this secret and key, if validates, responds with a newly generated token.
4> all further requests from angularjs app would carry this token in header, to ensure that the request is from a valid client.
But it is not good enough, as attacker can easily capture the requests using fiddler and also can easily read the client secret and key. or can debug using firebug.
Is there any secure way to authenticate the client app?
No security possible in the case if your REST API call is been shield by any User Authentication. I mean if User need to put Username/Password then they are able to call those API then you can implement some security.
But if your requirement like follows :
Any GUEST user with any browser open your application pages, which intern call your REST API.
Then there is no security. Since any attacker can intercept your Request/Response and call it further.
Note : From security prepective, Whatever a Browser can do, any good attacker can do the same.
But if you shield REST CALL Pages with username/password validation, then you can restrict the calls from server side with proper session validation.
JSON Web Tokens (JWT - pronounced jot) might be what you're looking for. Auth0 has a swell blog post that specifically addresses AngularJS + JWT.
You cannot trust the client to validate anything. If the user is using Firebug or Fiddler to "trick" your application then all you can do is verify the information server side to ensure it is valid.
You can trust the client to keep the user's session safe (to some extent), but if you can't trust the user then you can't trust anything the client sends to you.
If you need to ensure the integrity of a piece of data that is held client side you can use a MAC (Message Authentication Code) which is effectively a hash of the message appended to a server-side secret key that can be later verified. Sometimes this is (incorrectly) called signing. JWTs are the current standard to accomplish this.
It depends at the end of the day what threat you are trying to keep your application safe against - if it is a game with high scores that runs on the client, there's not much you can do to prevent the user from altering their score before it is sent to the server. If you need to trust such data, run it server side.

How to secure an AngularJS application that does not use authentication?

I have an AngularJS application (using ASP.NET Web API as the backend) that does not require the user to authenticate (the application has no login). I want to make sure that the REST API methods the AngularJS application invokes can only be invoked from the application. I obviously cannot use token based authentication for that.
If doing nothing special the REST API methods can be invoked freely using the browsers address bar or by writing a desktop application that invokes them. The same-origin policy is only regarded if a browser invokes an API method by a HTML page coming from a site having another origin. The REST API is therefore open to the public and easily hackable.
I wonder what I could do to securely restrict the access to the REST API. Any ideas or experience?
Edit 1:
I found an easy solution for my problem: I just check if the host of the URL referrer is the same as the host of the requested URL. Using ASP.NET Web API the code the REST API actions use is:
private bool ApiCallIsAllowed()
{
var request = HttpContext.Current.Request;
return (request.UrlReferrer != null &&
request.UrlReferrer.Host == request.Url.Host);
}
I am just not 100% sure if I always get the URL referrer.
Edit 2: According to this question the URL referrer ist not reliable. Bummer.
use ssh - that's obvious :)
login process should generate token - write it as a cooke - every http request will use it in header
prepare rest interceptor that will read your token and authorize every request
use some Javascript Obfuscator
Don't forget to invalidate session ;).
you can use spring-security or other framework to simplify this process

How to generate OAuth2.0 Bearer when calling App Engine Endpoints API?

I am providing a REST API via App Engine. I used Cloud Endpoints to generate it, although the client will not be mobile Android/iPhone but rather a known web server. Since I am familiar with this server (it is part of my application), I decided to use Service Account authorization in order to authorize the API calls (In addition, I will do IP validation, but that's beside the point).
I made all the necessary arrangement, created a Google developer project, generated a service account id (and email), with a p12 file, and added all the annotations needed on the server side (including a User object in the implementing function).
Now I want to implement a call to this API, and in order for it to work, I need to include a proper authorization header in my request.
When working with Google APIs, the client libraries generate some Credential object which you later need to pass in building some Service object, which represents a Google API you wish to call. For example, if you want to access Drive API in Java, you will do:
Drive drive = new Drive.Builder(Globals.httpTransport, Globals.jsonFactory, credential).build();
Where credential object is the object I previously build as follows:
credential = new GoogleCredential.Builder().setTransport(Globals.httpTransport)
.setJsonFactory(Globals.jsonFactory)
.setServiceAccountId(serviceAccountEmail)
.setServiceAccountScopes(scopes)
.setServiceAccountUser(serviceAccountUser)
.setServiceAccountPrivateKeyFromP12File(file(serviceAccountPrivateKeyP12File))
.build();
However, in my case, the client is not calling a Google API, but rather my App Engine REST API. How do I go about generating (or using the credential object I created to obtain) a proper Authorization header?
You can find some documentation in the readme.html file that is generated alongside the bindings, and here.
You can get the following account information in the console, "Apis & Auth", "Credentials". Here you need to paste "Email Address" of the service account. Your #Api annotation should include the account's "Client Id" in the "clientIds" parameter.
String accountEmail = "your-service-account#developer.gserviceaccount.com";
String keyFilePath = "your-key-file.p12";
This is the minimum authorization scope that is required for Cloud Endpoints API. It only allows the app to access the user's e-mail address. Your #Api annotation should list it in the "scopes" parameter.
String emailScope = "https://www.googleapis.com/auth/userinfo.email";
Then you need to create some support objects and the credential. GsonFactory can be replaced with JsonFactory if you prefer.
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
GsonFactory gsonFactory = new GsonFactory();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(gsonFactory)
.setServiceAccountId(accountEmail)
.setServiceAccountScopes(Collections.singleton(emailScope))
.setServiceAccountPrivateKeyFromP12File(new File(keyFilePath))
.build();
And finally create your API client. Replace YourApi with the client from the generated bindings. If you want to test against the dev AppServer, you can call .setRootUrl(yourDevServerUrl + "/_ah/api") on the builder.
YourApi client = new YourApi.Builder(httpTransport, gsonFactory, credential)
.setApplicationName("YourClientName")
.build();

Ria service not accessible to client (RequiresAuthentication service)

I have 2 Domain Service in my Silverlight solution, both of them has RequiresAuthentication attribute. When user go to application and they login, they can call service A and it working properly but when user call service B it throw exception Load operation failed for query 'X'. Access to operation 'X' was denied.
How to fix this problem?
You need an authentication service as mentioned in the comment that likely does not have RequiresAuthentication set, unless you wish to do your authentication in ASP.NET first and then why bother with that service?
I implemented my services as defined here: http://www.codeproject.com/KB/silverlight/IssueVisionSilverlightPt3.aspx#AuthenticationService
but what wasn't apparent is in ValidateUser(userName, password, out userData), userData can not be null here or FormsAuthentication.Encrypt(ticket) will always return null and therefor not set your auth cookie for Silverlight to send to your domain service requests. You can determine if the cookie is being sent by using Fiddler and you absolutely need this for the auth and domain services to "talk to each other".
The more quirky part is [EnableClientAccess(RequiresSecureEndpoint = true)] as this seems to want requiresSSL=true in your web.config forms section and all traffic has to pass through https. For me this means detecting this on the client and redirecting before any auth is triggered.

Resources