Controller.HttpContext.Request.Browser.IsMobileDevice is false on Production server - asp.net-mvc

I have a MVC3 web application, I followed the instruction is below link to make my site mobile friendly,
http://www.hanselman.com/blog/ABetterASPNETMVCMobileDeviceCapabilitiesViewEngine.aspx
everything is fine on my local IIS and it works when I connect to my local site via Mobile device,
I uploaded the site to the production server but it doesn't work, I traced the site and I figured out that on production server someController.HttpContext.Request.Browser.IsMobileDevice return false when I brows even with the mobile device. The mobile device is the same as in local tests.
Can everyone give me a clue?
Edit 1
someController.HttpContext.Request.UserAgent is User-Agent:Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; GT-N7000 Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
Edit 2
I am using .net4 and I can access to production server via WebSitePanel I don't have direct access to server.

I found the solution which doesn't need to change the server
var isMobile= false;
string u = Request.UserAgent;//ServerVariables["HTTP_USER_AGENT"];
Regex b = new Regex(#"(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino", RegexOptions.IgnoreCase | RegexOptions.Multiline);
Regex v = new Regex(#"1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-", RegexOptions.IgnoreCase | RegexOptions.Multiline);
if ((b.IsMatch(u) || v.IsMatch(u.Substring(0, 4)))) {
isMobile = true;
}
This solution is described here

Related

Open URL using Groovy receives status 403

I am trying to read the contents of a web page using a Groovy script. The page contains the readings from one of my temperature sensors that I want to save regularly. I have tried the simplest variant:
def url = "https://measurements.mobile-alerts.eu/Home/MeasurementDetails?deviceid=021B5594EAB5&vendorid=60122a8b-b343-49cb-918b-ad2cdd6dff16&appbundle=eu.mobile_alerts.mobilealerts&fromepoch=1674432000&toepoch=1674518400&from=23.01.2023%2000:00&to=24.01.2023%2000:00&command=refresh"
def res = url.toURL().getText()
println( res)
The result is:
Caught: java.io.IOException: Server returned HTTP response code: 403 for URL: (my url)
In any browser, this URL works without problems.
I would be very grateful for any tips on how to solve this problem.
HTTP code 403 means that a client is forbidden from accessing a valid URL. In other words, the server knows that you are not making a request via a web browser. To bypass this restriction, you need to specify a User-Agent in the request header.
For example:
def url = 'https://measurements.mobile-alerts.eu/Home/MeasurementDetails?deviceid=021B5594EAB5&vendorid=60122a8b-b343-49cb-918b-ad2cdd6dff16&appbundle=eu.mobile_alerts.mobilealerts&fromepoch=1674432000&toepoch=1674518400&from=23.01.2023%2000:00&to=24.01.2023%2000:00&command=refresh'
def res = url.toURL().getText(requestProperties:
['User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0'])
println res
You can switch to other valid user-agent values.

Cookie SameSite property works on localhost but not after publishing to server

I've used ASP MVC with .NET 4.7.2 to set the cookie on server side with the following code:
ClientCookie = new HttpCookie("SuperCookie");
ClientCookie.Value = dbNewCustomerCookie.CustomerCookieID.ToString(); // new inserted DB value
ClientCookie.Expires = DateTime.Now.AddYears(2);
ClientCookie.HttpOnly = true;
ClientCookie.Secure = true;
ClientCookie.Shareable = true;
ClientCookie.SameSite = SameSiteMode.None;
Response.SetCookie(ClientCookie);
Response.Flush();
While on localhost this is working fine and SameSite is set to None, after pushing this to server the SameSite flag come unset after every request. Localhost and server version are both running over HTTPS. Checked .NET version on server, have deleted the cookie to be recreated, tried with different web.config settings on server, also tried with URL rewrite module, but nothing worked.
Could this be a code issue or server/host issue ? We are using Amazon (private servers with access to IIS) to host our websites.
UPDATE : running the site on server localhost keeps returning SameSite as empty, while development machine returns always SameSite set as None. Both machines have .NET 4.7.2 installed, are running with the same web.config over IIS 7.
UPDATE 2 : if I set ClientCookie.SameSite = SameSiteMode.Lax then it will also work for server requests; but won't work to set the mode to SameSiteMode.None. With Lax mode the cookie is not created for cross-site requests, which is required because I call the website from an iframe.
UPDATE 3 : I think the reason of this is that the server is not updated with the latest functionality that support the samesite as none : https://learn.microsoft.com/en-us/aspnet/samesite/kbs-samesite, since the company will not update the server (internal policy) I will try to set the cookie from client side
If the server does not support the SameSite=None attribute-value, you could try sending the Set-Cookie header directly.
Response.AppendHeader("Set-Cookie",
"SuperCookie=" + dbNewCustomerCookie.CustomerCookieID.ToString()
+ "; Max-Age=63113904"
+ "; HttpOnly"
+ "; Secure"
+ "; SameSite=None"
);

Using an MVC API with Windows Authentication from VBA

I have developed a MVC Application, which, for the purpose of this question only has one controller:
Public Function GetValue()
Return User.Identity.Name
End Function
The application is to be used on an Intranet network, therefore, I have set it to 'Windows Authentication'
The aim is to query this application, through VBA.
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
With objHTTP
.Open "GET", URL, False
.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
.setRequestHeader "Content-type", "application/json"
.setRequestHeader "data-type", "json"
.send
.WaitForResponse
sResult = .ResponseText
End With
Debug.Print (sResult)
If I run the application locally (ie. debug on the computer that is running Excel), it works through Chrome (accessing localhost:xxxxx/api/name returns an xml file with my ActiveDirectory username).
The VBA routine works fine as well, and the Output window displays the XML I get in Chrome.
Now, if I publish the project to the IIS server, it still works through Chrome (accessing myserver/api/name returns an xml file with my ActiveDirectory username).
However, when I run the VBA module, it returns an Error 401:
Error:401 - Unauthorized: Access is denied due to invalid credentials.
The fact that it works in browsers leads me to believe that server-side configuration is OK, and that I need to tweak something in my VBA.
I have to admit that I am a bit clueless at this point...
Thank you for any leads you may give me :)
Thanks to #SWa comment, I solved this with a minor tweak to the function: Switching to WinHttpRequest and using setAutoLogonPolicy 0
Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
With objHTTP
.Open "GET", URL, False
.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
.setRequestHeader "Content-type", "application/json"
.setRequestHeader "data-type", "json"
.setAutoLogonPolicy 0
.send
.WaitForResponse
sResult = .ResponseText
End With
Debug.Print (sResult)

node.js : identify device (desktop/mobile/ipad) os (android/iOS) source (browser/app) on server side using user-agent string

I am trying to decipher this information from user-agent string on a node.js server based on Sails.js framework.
I have access to user-agent in req.headers["user-agent"]
Currently I am using this function to segregate iPhone, iPad and Android devices.
function findPlatform(userAgent){
var iphoneReg = /\biphone\b/gi;
var ipadReg = /\bipad\b/gi;
var androidReg = /\bandroid\b/gi;
if(!userAgent){
sails.log.error("cant infer user agent");
return "others";
}
if(userAgent.search(androidReg) > -1){
return "android";
}
else if(userAgent.search(iphoneReg) > -1){
return "iphone";
}
else if(userAgent.search(ipadReg) > -1){
return "ipad";
}
else {
return "others";
}
}
However, I also need to segregate between mobile app and mobile browser for both android and iOS. I was looking at certain requests and could see that user-agent from mobile app looks like this:
"Mozilla/5.0 (Linux; Android 5.0; Lenovo A7000-a Build/LRX21M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/45.0.2454.95 Mobile Safari/537.36"
While from mobile browser, it looked like this:
"Mozilla/5.0 (Linux; Android 4.4.4; MI 4W Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36"
Can I user a regex to match keyword "Version" to identify the request as coming from app ? What about iOS ?

Chrome losing cookies

I am getting a error on my live site which i am not seeing on my Dev environment and it seems to only happen with Chrome. I have looked around a bit for a solution to this and i find issues only with the Auth cookie. (I actually raised an issue about chrome and the auth cookie in the past) but this is different.
I store the users cart in a cookie. I set the cookie like so
HttpCookie responseCookie = HttpContext.Response.Cookies[CartHelper.CART];
responseCookie.PackCartCookie(vm.Cart);
Where the extension method PackCartCookie set the cookie value like so
cookie.Value = HttpUtility.UrlEncode(cookieValue);
This results is a cookie being stored with the following settings
Domain = www.foo.com
RawSize = 230b
Path = /
Expires = Session
HttpOnly = HttpOnly
Value = Encrypted
When a user is interacting with the site it seems that the Cart Cookie is being created but it is being lost or dropped from time to time. When i look at the Elmah error and review HTTP_COOKIE I can see all the other cookies (I have others set in the same way which function fine) but i do not see the cart cookie.
I have had to change code to be more defensive because of this issue. But as you can imagine the cart cookie is used through out the purchase process and i have had fails when responding to a purchase where i accept payment but the system crashes as the cart is gone and the user is not notified of a successful buy. Luckily i caught this early and refunded users affected.
User Agents where I have seen the issue
Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36
Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36
let me give you a solution. i have used the cookies for storing most of the values here and is very much working in all browsers and is stored for the particular mentioned time. for this i have used static classes to be accessible every where.
I have also encoded and decoded here. but you can store this by removing encoding and decoding and passing normal. Here's my code
Here i put my class with the static methods. I used HttpSecureCode with Encode and Decode using machine key cryptography. which might not be available by default in this case. you can directly put the value instead.
If you are very particular about using HttpSecureCode then use this link for building up your class
public class CookieStore
{
public static void SetCookie(string key, string value, TimeSpan expires)
{
HttpCookie encodedCookie = HttpSecureCookie.Encode(new HttpCookie(key, value));
if (HttpContext.Current.Request.Cookies[key] != null)
{
var cookieOld = HttpContext.Current.Request.Cookies[key];
cookieOld.Expires = DateTime.Now.Add(expires);
cookieOld.Value = encodedCookie.Value;
HttpContext.Current.Response.Cookies.Add(cookieOld);
}
else
{
encodedCookie.Expires = DateTime.Now.Add(expires);
HttpContext.Current.Response.Cookies.Add(encodedCookie);
}
}
public static string GetCookie(string key)
{
string value = string.Empty;
HttpCookie cookie = HttpContext.Current.Request.Cookies[key];
if (cookie != null)
{
// For security purpose, we need to encrypt the value.
HttpCookie decodedCookie = HttpSecureCookie.Decode(cookie);
value = decodedCookie.Value;
}
return value;
}
}
using these you can easily store values in cookie and fetch value whenever required
using these methods is as simple as
For Setting Cookie:
CookieStore.SetCookie("currency", "GBP", TimeSpan.FromDays(1)); // here 1 is no of days for cookie to live
For Getting Cookie:
string currency= CookieStore.GetCookie("currency");

Resources