I can trying to set an authentication value just for testing purposes.
I am not using basic authentication but just a String
VC.Request.Headers.Authorization = new AuthenticationHeaderValue("Secret Password");
It gives me this error that is making me pulling my hair off:
The format of value 'Secret Password' is invalid.
Again I don't want to use basic authentication and I don't know whats wrong, help?
The class is "documented" as:
Represents authentication information in Authorization, ProxyAuthorization, WWW-Authneticate[sic], and Proxy-Authenticate header values.
By calling the constructor with one parameter, you're using "Secret Password" as scheme, which can only contain tokens (i.e. no spaces). See RFC 2617 for specification.
You might want to call the other constructor overload:
new AuthenticationHeaderValue("MySuperAuthScheme", "Secret Password");
I think basic authentication generally uses a username:password syntax, so the client-side code might be pre-validating it to stop you sending "bad" data mistakenly to the server, even though that's what you're intentionally trying to do. Try adding a : and see if that helps.
Related
How about this system. I need some comments and maybe critical security part for this.
System which I use is maybe little bit complicated but 100% custom and should be good. This is a system for custom authentication in sending request to Asp.NET
WebApi
System works with sending 2 request
Everything what you need is 2 pairs of data. 1st one is public and 2nd one is secret.
Second pair of data be must be known to both sides (sender and receiver)
public: ApiKey and RequstID where ApiKey is "normal" and requstID have to be unique always;
secret: UserName and Password (both side have to know these data)
Sender:
Send 1st request with 3 parameters: 1st= ApiKey, 2nd=RequstID, 3rd=Hash(ApiKey+RequestID+USerName+Pass)
Server:
Read RequstID
Read ApiKey and get data about users UserName and Pass for this ApiKey
From the own side: Hash(ApiKey+RequestID+USerName+Pass)
Check is Hash from Sender same us from Server
If is False:
BadRequest - or whatever...
if is True
Before all - Create on database on table for collect data about request.
This is table with columns (e.g.):
ID(autoincrement), RequstID, Token, TokenValidateDateTime
Before create new row, check is there already this RequestID and if there is return BadRequest.
If there is not - make new row.
RequstID is RequstID from request;
Token - Generate token (e.g. Guid.NewGuid().ToString());
TokenValidateDateTime= DateTime.Now.AddMinutes(2) - or some other value ...
In response for the first request send back this this Token (from item 2)
In the second request, Sender have to use AGAIN same RequstID and Token (from response before)
Server will check
Combination RequstID and Token
Token validation (depend on current date time);
Is everything is OK, user is validated
if is not - BadRequest, or whatever
Any suggestions or comments are welcome :)
It sounds similar to traditional website username / password authentication which returns a session cookie.
But you're also including a api key & request id and a hash. The hash won't add to much value unless there's a shared salt, as once someone works out your hashing technique it will be vulnerable to dictionary attacks.
Also generating a Guid token isn't "cryptographically secure", it is designed to be unique but it's often based upon the system clock meaning it is predictable.
Building bespoke security mechanisms are generally unadvised; doing bespoke encryption is defiantly a "no no" (which you aren't doing as far as I'm aware). Bespoke authentication is probably less risky, but seeing as there are many frameworks already existing that have been critiqued by security experts I'd suggest researching if any of those suit first.
I'd recommend looking at asp.net core's security options: https://learn.microsoft.com/en-us/aspnet/core/security/?view=aspnetcore-2.1
After seeing the AntiForgery.Validate() method error (which it is supposed to do, when the form token does not validate), and visiting this site: http://msdn.microsoft.com/en-us/library/system.web.helpers.antiforgery(v=vs.111).aspx
for more information, it appears that I may have misused this in the past.
I have used the combination of AntiForgery.GetHTML(); and AntiForgery.Validate(); on a login page, but not sure if it makes sense to put it there. Without being logged in, the user is always "" (empty string), so I guess I originally thought that using the AntiForgery class did more than it really does. And, thus, is my question:
Am I right to assume that the only security check that the above practice performs is simply to make sure (by putting AntiForgery.Validate(); in an if(IsPost) branch) that the user who submitted the form is the same user who was logged in when the page was loaded?
If so, then, Am I also right in assuming that utilizing this class in this way has no place in a login page?
If you look at the source code on codeplex, AntiForgery uses AntiForgeryWorker which uses TokenValidator, the ValidateTokens method does do some identity and username checking. If you aren't getting an exception thrown, it might be doing some level of validation but using "" as username.
if (!String.Equals(fieldToken.Username, currentUsername, (useCaseSensitiveUsernameComparison) ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase))
{
throw HttpAntiForgeryException.CreateUsernameMismatchException(fieldToken.Username, currentUsername);
}
However, what is the use case for "forging" a login page? If the forger know the credentials to submit, they could just login themselves. It might not matter if AntiForgery doesn't work to its full potential here.
I am getting an invalid username or password error when trying to upload to twitpic. I am positive these are correct.
I am using Twitpic.net
Twitpic tp = new Twitpic(data, ConfigurationManager.AppSettings["TwitterUsername"], ConfigurationManager.AppSettings["TwitterPassword"]);
TwitpicResponse resp = tp.UploadAndPost("The Message");
Any help would be greatly appreciated.
Have you verified that you can actually read the settings from the application configuration? I.e. for example assign the values read from ConfigurationManager to temporary variables and debug/display/print them instead? If the read fails, the returned value will be null.
Then, when you can verify that you are indeed sending correct credentials - verify that you have authorized the Twitpic application on your Twitter account?
Additionally, hard-coding the configuration keys is not best practice - use constants or similar approach instead.
I have tried migrating my app to the OAuth 2.0 routine. I am having trouble getting the access_token from the cookie set by the JavaScript API. I decode the information in the cookie, but instead of an access_token and the user information I get a code. This seems like a rather weird change.
Is there any workaround for this, because it seems that you can't get your code exchanged to an access_token when you haven't specified a redirect_uri when you acquired the code.
I have considered just taking the access_token from the response in the JavaScript API and storing it in a cookie, but that kinda defeats the whole purpose of the extended security and I wanted to ask if there was a proper way to do it.
Could be that I am doing something wrong though, and if that is the case please tell me :)
EDIT
I am aware that the cookie holds a signed request, but according to the docs that signed request should hold the information I require like access_token and uid, but in my instance it only holds the code. That is basically the part I don't understand.
Turns out that (even though it is not documented) we need to exchange the code for an access_token ourselves. I think this is a total waste since that was the nice thing about the old cookie. It was fast and easy to get the access_token.
Anyway. To get the access_token from the new cookie you need to do the following:
public string ReturnAccessToken()
{
HttpCookie cookie = htc.Request.Cookies[string.Format("fbsr_{0}", facebookAppID)];
string jsoncode = System.Text.ASCIIEncoding.ASCII.GetString(FromBase64ForUrlString(cookie.Value.Split(new char[] { '.' })[1]));
JsonData data = JsonMapper.ToObject(jsoncode);
getAccessToken(data["code"].ToJson()
}
private string getAccessToken(string code)
{
//Notice the empty redirect_uri! And the replace on the code we get from the cookie.
string url = string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&client_secret={2}&code={3}", "YOUR_APP_ID", "", "YOUR_APP_SECRET", code.Replace("\"", ""));
System.Net.HttpWebRequest request = System.Net.WebRequest.Create(url) as System.Net.HttpWebRequest;
System.Net.HttpWebResponse response = null;
using (response = request.GetResponse() as System.Net.HttpWebResponse)
{
System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream());
string retVal = reader.ReadToEnd();
return retVal;
}
}
public byte[] FromBase64ForUrlString(string base64ForUrlInput)
{
int padChars = (base64ForUrlInput.Length % 4) == 0 ? 0 : (4 - (base64ForUrlInput.Length % 4));
StringBuilder result = new StringBuilder(base64ForUrlInput, base64ForUrlInput.Length + padChars);
result.Append(String.Empty.PadRight(padChars, '='));
result.Replace('-', '+');
result.Replace('_', '/');
return Convert.FromBase64String(result.ToString());
}
This may seem a bit redundant, but I suppose you can store the access_token in a session variable. If you do this and iFrame the your app on Facebook you need to know that it will not work in IE 6, 7 and 8 if the user have set his browser privacy settings to medium. There is a workaround for this, but as it is not a part of this question I will not write it. If people really want it, write a comment and I will show it :)
-----------------------------------EDIT------------------------------------------
When using any of the old IE browsers you can't use cookies or session variables in pages that are Iframed in, like your pages on Facebook. This is a problem that can't really be solved sufficiently in coding. By sufficiently I mean that the solution is not nice. You need to set the p3p-header in your response. You can of course do this in coding for all the pages that you service, but the easiest solution (if you are using a .NET server to host your pages) is to set up a p3p policy for the IIS. A guide for this can be seen in http://support.microsoft.com/kb/324013. It shouldn't matter what you write in the p3p policy (if you check Facebooks own you can see that they use "We don't have a p3p policy), the important part is that there stands something. I have had troubles just using random text though, but if you use the text in the example there shouldn't be a problem :)
This took me forever to find out, so I hope someone can use it :D
Unfortunately I don't have the answer directly, but I do have a documentation bug that I filed against facebook in order to try to get the documentation there: http://bugs.developers.facebook.net/show_bug.cgi?id=20363
I have a similar problem that when I try to decode the signedRequest from the authResponse of FB.login, they payload contains something like:
{"algorithm":"HMAC-SHA256","code":"THE_CODE_HERE","issued_at":1315433244,"user_id":"THE_USER_ID"}
As you stated, the docs do talk about how to turn that code into an access_token. That appears to be in the "Server Side" documentation here: http://developers.facebook.com/docs/authentication/
If you grab the accessToken from FB.login you can get it from the js and cache it, but as you said, that isn't actually signed, and could relatively easily be faked.
And you're right, this doesn't appear to have any of the useful information that's described here: developers.facebook.com/docs/authentication/signed_request/ (http removed since I don't have enough reputation points yet to post more than 2 links - sorry)
Perhaps you can vote up my bug? I'll post this link on that bug too.
fbsr_APP_ID cookie is actually a signed_request, check out facebook official docs how do you decode signed request verify signature and get the user information. You can look also at official php SDK source how they get access token from there.
You have to use the code to get the actual access_token.
I'm trying to build a login link for facebook and I'm I'm getting errors only in some cases. I'm trying to specify a a querystring parameter in redirect_uri token so that I can redirect them back to a specific area of my site after logging in. Here's what works and what doesn't work.
&redirect_uri=http://mydomain.com/login?returnUrl=returnUrl - works
&redirect_uri=http://mydomain.com/login?returnurl=/return/url -doesn't work
&redirect_uri=http%3a%2f%2fmyagentcheckin.com%2flogin%3freturnUrl%3d%2freturn%2furl -doesn't work
It seems that the / in the querystring are causing it to fail. Facebook returns an error when I try it. Anyone know of a way around this?
Instead of including the returnUrl parameter as part of your redirect_uri value, use the state parameter to store this data.
For instance,
https://graph.facebook.com/oauth/authorize?type=web_server&client_id={appid}&redirect_uri=http://www.yoursite.com/oauth/handshake&state=/requested/page
I have experienced something similar, especially with multiple redirects as above.
My solution is to put the returnUrl into the user's session (or perhaps a cookie), so I don't have to wrestle with double-encoding. For the redirect_url, just omit the querystring.
Try using this API that put together. It will remove the hassle of this for you.
No url encoding necessary.
Sample Authentication
Imports Branches.FBAPI
...
Dim SI As New SessionInfo("[application_id]","applicaiton_secret")
SI.AuthenticateUser("http://[my url]", New SessionInfo.PermissionsEnum(){SessionInfo.PermissionsEnum.email, SessionInfo.PermissionsEnum.read_stream}))
Read the response from the URL you provided above from that page.
Dim FSR = FS.ReadFacebooAuthResponse
When I tried what you do, I got a redirect callback something like this.
http://mydomain.com/login?returnurl=%2Freturn%2Furl&code=...
And I decode the "returnurl" value.
Then it worked fine for me.