In ASP.net 2.0 Response.Cookies.Add() is a VOID (which boggles me somewhat). Is there a way to check to see if the function successfully added the cookie?
I just spent 2 hours trying to track down an authentication issue for one user. Finally I realized he was in a BUNCH of AD groups and I believe the cookie we were building for him, and trying to set, was > 4096 bytes.
Would be nice to know up front if the call to Response.Cookies.Add() failed.
We were trapping the error later in the global.asax page when we did:
HttpCookie authCookie = Context.Request.Cookies[cookieName];
and authCookie for this user was always null.
Thanks for the responses.
I've decide to check the size before calling Response.Cookies.Add() and alert the user accordingly.
int iSize = System.Text.UTF8Encoding.UTF8.GetByteCount(authCookie.Values.ToString());
if (iSize > 4096)
{
lblMessage.Text = "The authentication cookie cannot be set as it is > 4096 bytes; a limit imposed by the browser. The current size of the Cookie.Values is " + iSize.ToString() + " bytes.";
lblMessage.CssClass = "msgBox Alert";
return;
}
I setup a simple project that write a random cookie value, and used Fiddler to examine the response:
GET http://localhost.:2605/Default.aspx HTTP/1.1
Accept: */*
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Host: localhost.:2605
Pragma: no-cache
Cookie: ASP.NET_SessionId=wxpo32z2zxr1qlbwgx4on3z2; test1047139665=value775124204
You can see the cookie in the Cookie section of the header above. This is consistent with the documentation at: http://msdn.microsoft.com/en-us/library/system.web.httpresponse.cookies.aspx
The size limitation is documented here:
http://support.microsoft.com/kb/306070
Looks like you'll have to check yourself before writing it.
Yes, but likely not how you want to. On the subsequent page or request, check it in Request.Cookies if the cookie is available. If not, you can assume the Response.Cookies wasn't able to add the cookie (they have cookies off, cleared them, etc.).
You can't verify the Response.Add worked when it happens because it doesn't truly happen until the response is sent to the browser.
Response.Cookie.Add() succeeds always. It's the client accepting said cookie that might fail. But the Add() method has no way of knowing - since it just places the cookie in the HTTP response. You won't know until the HTTP response is sent back and the client processes it. Which happens long after Add() returns.
So the only way to verify that is to check for the cookie on subsequent requests, which seems like you're already doing by checking for the auth info.
Related
Currently, I'm using Angular 5 to build a website. My website using 0Auth 2.0 to secure a request send to ASP.net Web API 2.0. So, when i try sending a request to get an access token. I use this function :
userAuthentication(userName, password) {
let data = "username=" + userName + "&password=" + password + "&grant_type=password&client_id=JCWebApp";
return this.http.post(this.rootUrl + '/login', data,{headers:'Content-Type':'application/x-www-form-urlencoded'}});
}
But web api server return for me response with status code 400. When I check an request header of login request, it like this :
Accept
text/html,application/xhtml+xm…plication/xml;q=0.9,/;q=0.8
Accept-Encoding
gzip, deflate
Accept-Language
en-US,en;q=0.5
Access-Control-Request-Headers
no-auth
Access-Control-Request-Method
POST
Connection
keep-alive
Host
localhost:9810
Origin
http://localhost:4200
User-Agent
Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/59.0
I researched on the internet, and try many way, all most the answer same as :
- Angular HttpClient doesn't send header. But it not working with my situation.
So please help me explain why and how to resolve this case.
Thanks.
you need to enable the CORS in your Web API
download this in nuget Microsoft.Owin.Cors
and in ConfigureAuth(IAppBuilder app) located in your Web API
add this line of code app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
I'm accessing Windows authentication information in my ASP.NET MVC application using the following code.
WindowsIdentity identity = HttpContext.Current.Request.LogonUserIdentity;
Value of identity.Name is correctly the Windows login name.
When I inspect the http request that is send from browser to the server I see the following.
GET http://localhost:12010/administration HTTP/1.1
Authorization: Negotiate YIIJqgYGKwYBBQUCoIIJnjCCCZqgMDAuBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCNwICHgYKKwYBBAGCNwICCqKCCWQEgglgYIIJXAYJKoZIhvcSAQICAQBugglLMIIJR6ADAgEFoQMCAQ6iBwMFACAAAACjggfcYYIH2DCCB9SgAwIBBaEKGwhJVC5MT0NBTKIoMCagAwIBAqEfMB0bBEhUVFAbFWl0LWRsMzgyLWhraS5JVC5MT0NBTKOCB5UwggeRoAMCARKhAwIBIaKCB4MEggd
Accept: text/html, application/xhtml+xml, */*
Accept-Language: en-EN
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Host: localhost:12010
Cookie: ASP.NET_SessionId=pr0qmeomsr1rlb1ehp2sffd3
There is no Windows authentication information in the http request, but I can access it in my code.
How are the values of LogonUserIdentity properties passed from browser to server?
Note that these type of authentication is designed to employ in intranet applications.
As you can see, the Request parameters for my own test is:
Params: {ALL_HTTP=HTTP_CACHE_CONTROL%3amax-age%3d0%0d%0aHTTP_CONNECTION%3akeep-alive%0d%0aHTTP_ACCEPT%3atext%2fhtml%2capplication%2fxhtml%2bxml%2capplication%2fxml%3bq%3d0.9%2cimage%2fwebp%2c*%2f*%3bq%3d0.8%0d%0aHTTP_ACCEPT_ENCODING%3agzip%2c+deflate%2c+sdch%0d%0aHTTP_ACCEPT_LANGUAGE%3aen-US%2cen%3bq%3d0.8%2cfa%3bq%3d0.6%0d%0aHTTP_HOST%3alocalhost%3a54035%0d%0aHTTP_USER_AGENT%3aMozilla%2f5.0+(Windows+NT+6.3%3b+WOW64)+AppleWebKit%2f537.36+(KHTML%2c+like+Gecko)+Chrome%2f40.0.2214.94+Safari%2f537.36%0d%0a&ALL_RAW=Cache-Control%3a+max-age%3d0%0d%0aConnection%3a+keep-alive%0d%0aAccept%3a+text%2fhtml%2capplication%2fxhtml%2bxml%2capplication%2fxml%3bq%3d0.9%2cimage%2fwebp%2c*%2f*%3bq%3d0.8%0d%0aAccept-Encoding%3a+gzip%2c+deflate%2c+sdch%0d%0aAccept-Language%3a+en-US%2cen%3bq%3d0.8%2cfa%3bq%3d0.6%0d%0aHost%3a+localhost%3a54035%0d%0aUser-Agent%3a+Mozilla%2f5.0+(Windows+NT+6.3%3b+WOW64)+AppleWebKit%2f537.36+(KHTML%2c+like+Gecko)+Chrome%2f40.0.2214.94+Safari%2f537.36%0d%0a&APPL_MD_PATH=%2fLM%2fW3SVC%2f7%2fROOT&APPL_
PHYSICAL_PATH=c%3a%5cusers%5camirmehr%5cdocuments%5cvisual+studio+2013%5cProjects%5cWindows+Auth%5cWindows+Auth%5c&AUTH_TYPE=Negotiate&AUTH_USER=Amir%5camirmehr&AUTH_PASSWORD=&LOGON_USER=Amir%5camirmehr&REMOTE_USER=Amir%5camirmehr&CERT_COOKIE=&CERT_FLAGS=&CERT_ISSUER=&CERT_KEYSIZE=&CERT_SECRETKEYSIZE=&CERT_SERIALNUMBER=&CERT_SERVER_ISSUER=&CERT_SERVER_SUBJECT=&CERT_SUBJECT=&CONTENT_LENGTH=0&CONTENT_TYPE=&GATEWAY_INTERFACE=CGI%2f1.1&HTTPS=off&HTTPS_KEYSIZE=&HTTPS_SECRETKEYSIZE=&HTTPS_SERVER_ISSUER=&HTTPS_SERVER_SUBJECT=&INSTANCE_ID=7&INSTANCE_META_PATH=%2fLM%2fW3SVC%2f7&LOCAL_ADDR=%3a%3a1&PATH_INFO=%2f&PATH_TRANSLATED=c%3a%5cusers%5camirmehr%5cdocuments%5cvisual+studio+2013%5cProjects%5cWindows+Auth%5cWindows+Auth&QUERY_STRING=&REMOTE_ADDR=%3a%3a1&REMOTE_HOST=%3a%3a1&REMOTE_PORT=54427&REQUEST_METHOD=GET&SCRIPT_NAME=%2f&SERVER_NAME=localhost&SERVER_PORT=54035&SERVER_PORT_SECURE=0&SERVER_PROTOCOL=HTTP%2f1.1&SERVER_SOFTWARE=Microsoft-IIS%2f8.0&URL=%2f&HTTP_CACHE_CONTROL=max-age%3d0&HTTP_CONNECTION=keep-alive&HTTP_
ACCEPT=text%2fhtml%2capplication%2fxhtml%2bxml%2capplication%2fxml%3bq%3d0.9%2cimage%2fwebp%2c*%2f*%3bq%3d0.8&HTTP_ACCEPT_ENCODING=gzip%2c+deflate%2c+sdch&HTTP_ACCEPT_LANGUAGE=en-US%2cen%3bq%3d0.8%2cfa%3bq%3d0.6&HTTP_HOST=localhost%3a54035&HTTP_USER_AGENT=Mozilla%2f5.0+(Windows+NT+6.3%3b+WOW64)+AppleWebKit%2f537.36+(KHTML%2c+like+Gecko)+Chrome%2f40.0.2214.94+Safari%2f537.36}
And Server variables :
ServerVariables: {ALL_HTTP=HTTP_CACHE_CONTROL%3amax-age%3d0%0d%0aHTTP_CONNECTION%3akeep-alive%0d%0aHTTP_ACCEPT%3atext%2fhtml%2capplication%2fxhtml%2bxml%2capplication%2fxml%3bq%3d0.9%2cimage%2fwebp%2c*%2f*%3bq%3d0.8%0d%0aHTTP_ACCEPT_ENCODING%3agzip%2c+deflate%2c+sdch%0d%0aHTTP_ACCEPT_LANGUAGE%3aen-US%2cen%3bq%3d0.8%2cfa%3bq%3d0.6%0d%0aHTTP_HOST%3alocalhost%3a54035%0d%0aHTTP_USER_AGENT%3aMozilla%2f5.0+(Windows+NT+6.3%3b+WOW64)+AppleWebKit%2f537.36+(KHTML%2c+like+Gecko)+Chrome%2f40.0.2214.94+Safari%2f537.36%0d%0a&ALL_RAW=Cache-Control%3a+max-age%3d0%0d%0aConnection%3a+keep-alive%0d%0aAccept%3a+text%2fhtml%2capplication%2fxhtml%2bxml%2capplication%2fxml%3bq%3d0.9%2cimage%2fwebp%2c*%2f*%3bq%3d0.8%0d%0aAccept-Encoding%3a+gzip%2c+deflate%2c+sdch%0d%0aAccept-Language%3a+en-US%2cen%3bq%3d0.8%2cfa%3bq%3d0.6%0d%0aHost%3a+localhost%3a54035%0d%0aUser-Agent%3a+Mozilla%2f5.0+(Windows+NT+6.3%3b+WOW64)+AppleWebKit%2f537.36+(KHTML%2c+like+Gecko)+Chrome%2f40.0.2214.94+Safari%2f537.36%0d%0a&APPL_MD_PATH=%2fLM%2fW3SVC%2f7%2fR
OOT&APPL_PHYSICAL_PATH=c%3a%5cusers%5camirmehr%5cdocuments%5cvisual+studio+2013%5cProjects%5cWindows+Auth%5cWindows+Auth%5c&AUTH_TYPE=Negotiate&AUTH_USER=Amir%5camirmehr&AUTH_PASSWORD=&LOGON_USER=Amir%5camirmehr&REMOTE_USER=Amir%5camirmehr&CERT_COOKIE=&CERT_FLAGS=&CERT_ISSUER=&CERT_KEYSIZE=&CERT_SECRETKEYSIZE=&CERT_SERIALNUMBER=&CERT_SERVER_ISSUER=&CERT_SERVER_SUBJECT=&CERT_SUBJECT=&CONTENT_LENGTH=0&CONTENT_TYPE=&GATEWAY_INTERFACE=CGI%2f1.1&HTTPS=off&HTTPS_KEYSIZE=&HTTPS_SECRETKEYSIZE=&HTTPS_SERVER_ISSUER=&HTTPS_SERVER_SUBJECT=&INSTANCE_ID=7&INSTANCE_META_PATH=%2fLM%2fW3SVC%2f7&LOCAL_ADDR=%3a%3a1&PATH_INFO=%2f&PATH_TRANSLATED=c%3a%5cusers%5camirmehr%5cdocuments%5cvisual+studio+2013%5cProjects%5cWindows+Auth%5cWindows+Auth&QUERY_STRING=&REMOTE_ADDR=%3a%3a1&REMOTE_HOST=%3a%3a1&REMOTE_PORT=54427&REQUEST_METHOD=GET&SCRIPT_NAME=%2f&SERVER_NAME=localhost&SERVER_PORT=54035&SERVER_PORT_SECURE=0&SERVER_PROTOCOL=HTTP%2f1.1&SERVER_SOFTWARE=Microsoft-IIS%2f8.0&URL=%2f&HTTP_CACHE_CONTROL=max-age%3d0&HTTP_CONNECTION=keep-al
ive&HTTP_ACCEPT=text%2fhtml%2capplication%2fxhtml%2bxml%2capplication%2fxml%3bq%3d0.9%2cimage%2fwebp%2c*%2f*%3bq%3d0.8&HTTP_ACCEPT_ENCODING=gzip%2c+deflate%2c+sdch&HTTP_ACCEPT_LANGUAGE=en-US%2cen%3bq%3d0.8%2cfa%3bq%3d0.6&HTTP_HOST=localhost%3a54035&HTTP_USER_AGENT=Mozilla%2f5.0+(Windows+NT+6.3%3b+WOW64)+AppleWebKit%2f537.36+(KHTML%2c+like+Gecko)+Chrome%2f40.0.2214.94+Safari%2f537.36}
which contains my username equal to amirmehr. But in browser request we don't see any user information which says the IIS is reading user data from OS since I'm running my project locally :). Here is browser request:
Request URL:http://localhost:54035/
Request Headers
Provisional headers are shown
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer:http://localhost:54035/
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.94 Safari/537.36
After some research, I found out the question depends on test environment (besides configuration).
For Local case, take a look at Unable to get windows authentication to work through local IIS
And to understand how it works, check the Windows Authentication for
.net MVC 4 - how it works, how to test it. Both have useful
things.
Also we have configuration considerations mentioned below:
Configuration(Microsoft Link)
Configuring Windows Authentication in MVC4 with IIS Express.
For customization check ASP.NET MVC 4 Forms Authentication Customized :)
Depending on your WindowsAuthenticationMode, the browser may or may not authenticate with IIS. For example, if you allow Anonymous Authentication, then IUSR_MACHINENAME user will be used to authenticate the user. If Basic is specified, then the browser will authenticate with IIS (you will need to provide user/password) and then you will see in the requests the authentication information. Then there is NTLM authentication. More information here.
I developing Grails+BlazeDS server and Flex AIR client and stucked with this error:
Detected duplicate HTTP-based FlexSessions, generally due to the remote host disabling session cookies. Session cookies must be enabled to manage the client connection correctly
Google searches didn't successfully, as I see some difference in situations.
The issue I got only when Flex client interact with server via https.
Flex client:
<s:ChannelSet id="userChannel">
<s:SecureAMFChannel uri="https://localhost:8443/Con/messagebroker/amfpolling" />
</s:ChannelSet>
button click in UI triggered login method:
loginResult.token = channelSet.login(usernameInput.text, passwordInput.text);
And finished with DuplicateSessionDetected exception. :(
After investigating network monitor logs, I found that jsession cookie received from server not set in next requests to a server:
Response from server (operation: client_ping)
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=F58F1ADA97E70915EF9E6E4EE1AEBE00; Path=/; Secure
Content-Type: application/x-amf
Content-Length: 173
Date: Sun, 23 Feb 2014 10:17:00 GMT
Flex Message (flex.messaging.messages.AcknowledgeMessageExt) clientId = EA18E8B9-951F-6F87-7B47-48B8B202EE75 correlationId = 7D2782C1-C8A5-41A3-2055-5E3F771424C8 destination = null messageId = EA18E8F6-9E0E-1FE4-0D26-6F0E602F5C5E timestamp = 1393150620542 timeToLive = 0 body = null hdr(DSMessagingVersion) = 1.0 hdr(DSId) = EA18E8B9-950B-4B42-EF70-369D656BA3F2
And next request to server (login operation) without jsession cookie:
POST /Conn/messagebroker/amfsecure HTTP/1.1
Referer: app:/BlazeDSClient.swf
Accept: text/xml, application/xml, application/xhtml+xml, text/html;q=0.9, text/plain;q=0.8, text/css, image/png, image/jpeg, image/gif;q=0.8, application/x-shockwave-flash, video/mp4;q=0.9, flv-application/octet-stream;q=0.8, video/x-flv;q=0.7, audio/mp4, application/futuresplash, */*;q=0.5
x-flash-version: 12,0,0,68
Content-Type: application/x-amf
Accept-Encoding: gzip,deflate
User-Agent: Mozilla/5.0 (Windows; U; en) AppleWebKit/533.19.4 (KHTML, like Gecko) AdobeAIR/4.0
Host: localhost
Content-Length: 299
Flex Message (flex.messaging.messages.CommandMessage) operation = login clientId = null destination = auth messageId = 7B47BBF2-08C0-0E41-5D88-5E3F76FA4882 timestamp = 0 timeToLive = 0 ***not printing credentials***
and server answering with new session cookie:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=03BD8347F9E9511C299B717DD55625C9; Path=/; Secure
Content-Type: application/x-amf
Content-Length: 535
Date: Sun, 23 Feb 2014 10:17:01 GMT
Flex Message (flex.messaging.messages.ErrorMessage) clientId = null correlationId = 7B47BBF2-08C0-0E41-5D88-5E3F76FA4882 destination = auth messageId = EA18F4A7-C80D-103B-F8D0-58B6F148F142 timestamp = 1393150621768 timeToLive = 0 body = null code = Server.Processing.DuplicateSessionDetected message = Detected duplicate HTTP-based FlexSessions, generally due to the remote host disabling session cookies. Session cookies must be enabled to manage the client connection correctly. details = null rootCause = null body = null extendedData = null
And again - when used non-secure protocol everything ok - session cookie sevt to server in login operation as expected.
I have a little experience in Flex development and didn't find any method to set session cookie when triggered channel login request. Can you help to resolve this issue?
Thanks!
Gotcha!!
It's unbelievable, but the cause of DuplicateSessionDetected exception has been a Network Monitor tool of Flash Builder. After switching it off no any exception has been occurred. I think there issues when Monitor acting as proxy when used with secure protocol.
Surely, this question is already dead, but I have got something to say in this regard for future readers.
The Flash Player (including Flex) does not transmit the default JSESSIONID in the request and cannot do it until you have set SameSite=None in the JSESSIONID cookie.
I have faced the problem where the JSESSIONID cookie is dropped in the request and I have discovered that it is because modern browsers (chrome > 80) do not allow the Flash/Flex Player to access the JSESSIONID cookie it the cookie does not have SameSite=None and Secure flash.
Please, read the announcement from Adobe here
More to read about the new cookie policy:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
https://medium.com/adobetech/adobe-experience-cloud-cookie-updates-for-google-chrome-19ad67cf1598
https://digiday.com/media/what-is-chrome-samesite/
Do not perform the client_ping operation and then try the secure channelSet. by pingin the server, you are creating another channelset(by default flash creates one for you) and then you are trying to open another channelset using .login operation. Try this by restarting you server,(fresh instance) or else you will be creating more sessions.
Note:
This question has broadened in scope from previous revisions. I have tried to simplify the issue so it can be easily reproduced by anyone.
Using Fiddler, I can replay an arbitrary request to my default page after erasing my Authorization header from the HTTP request, and I am able to get a response of 200 OK with valid data.
Bounty Update
Here are the steps to reproduce this exact behavior:
1. Create a "New Website" in ASP.NET, feel free to name it "InsecureWebsite"
2. Edit web.config to deny all unauthenticated users:
<authentication mode="Windows" />
<authorization>
<deny users="?"/>
<allow users="*"/>
</authorization>
3. Publish the website to an arbitrary directory on a DEV server and create a virtual directory for the application
4. Ensure the application has script access (.ASP) and Integrated Windows Authentication enabled
5. Open Fiddler to capture the traffic
6. Load the page in your favorite browser and look at the "Inspectors" tab within Fiddler, you'll see a request similar to:
GET /InsecureWebsite/ HTTP/1.1
Host: dev.subdomain.example.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Authorization: NTLM
{Base64-encoded authentication data}
The initial request to Default.aspx will return a 401 Unauthorized, will go into negotiation, and then finally return a 200 OK.
In Fiddler I can then erase the Authorization header directly from a replayed request to Default.aspx and still get a 200 OK. How is that possible?
Solution
It turns out that Fiddler uses the same underlying connection when making the requests, so once the connection is authenticated, any request on the same connection will also be authenticated as the same user as the initial request. You can turn this feature off in Fiddler here:
Screenshot of Fiddler options http://john.cognitivedelay.com/images/fiddler-options.gif
Once this has been unchecked, any replayed requests from within Fiddler will return a 401 Unauthorized as I would expect.
Thanks to all who offered their time to respond!
Edit: per updated question:
Are you doing the replay in Fiddler itself, or by making a direct connection to the webserver? It might be that Fiddler is reusing an existing HTTP connection (which it can do, as a proxy)... I think IWA might mark the whole connnection as authenticated, not just the current request, which means that any future requests on the same connection re-use the authorization and authentication from the first negotiation...
Original answer:
Try
[WebMethod(EnableSession=true)]
[PrincipalPermission(SecurityAction.Demand, Authenticated=true)]
and see if that helps?
(Possibly [PrincipalPermission(SecurityAction.Demand, Role="myDevRole")] if that's more appropriate for you...)
The Ajax call is done on a new thread for an existing authenticated session, That's why you don't see any authentication information in the headers. The session is already authenticated.
You can get the authenticated user's identity, and then pass that on to any role management routines, by referencing System.Threading.Thread.CurrentPrincipal.Identity.Name:
[WebMethod(EnableSession = true)]
public static string WhoAmI()
{
// Return the identity of the authenticated windows user.
Return System.Threading.Thread.CurrentPrincipal.Identity.Name;
}
You could potentially add authentication information to the header of the message, then authenticate yourself in the webmethod.
or you could try something like this or this
Add this attribute to the web method
[PrincipalPermissionAttribute( SecurityAction.Demand, Role = "myDevRole" )].
Then on Global.asax event Application_AuthenticateRequest you can make sure that current thread user is authenticated correctly - i.e. do what is necessary to avoid fraud cookies or sessions.
Using Windows authentication on your local development machine, every request is going to be from an authenticated user. So, deny users="?" will never deny any requests locally.
If you were hitting this on a remote IIS machine you aren't authenticated with or were to use Forms Authentication, it would require authentication before you could successfully request either Default.aspx or the page method.
i am trying to find the url of previous page.Such as if a user navigates from Page A to Page B using Server.Redirect("B.aspx"), page B can display the url referring to it.
I have tried using
Response.Write(Page.PreviousPage.ToString());
Response.Write(Request.UrlReferrer.ToString());
Response.Write(Context.Request.UrlReferrer.ToString());
Response.Write(Request.ServerVariables["HTTP_REFERER"].ToString);
but all in vain it gives me null exception error
You can save you current page in the Session and then retrieve it from there:
string previousPage = Session["PreviousPage"] as string;
Session["PreviousPage"] = System.IO.Path.GetFileName(System.Web.HttpContext.Current.Request.FilePath);
This way the previousPage string will always contain the previous page's filename, and the Session variable will contain the current page, ready to be used on the next page.
This way you can also detect if the referrer is an outside link because then the previousPage string will be null.
If it's only for this scenario (where you programatically redirect to B.aspx) then why not put something on the querystring to say where the redirect came from. This would be more likely to work across muliple browser types and devices.
One advantage to this approach is that you'll be able to tell the difference between a redirect to B.aspx and a direct link (either via a link on one of your pages, or from the user entering the URL into the address base) to page B.aspx.
The referrer is something the the client provides as part of the HTTP request. As such, you can't rely on it.
By the way, this question is related:
Request.UrlReferrer null?
Update
Given your comments it's not clear that's an easy solution other than "edit all your files". I suspect that global search/replace might be your best bet.
Some more background: If you use Fiddler (or any other http debugging tool) you should be able to see that the Referrer header isn't being populated when you perform a redirect. For example, this is the result of a redirect (i.e. an HTTP 302 response causing IE to redirect to another page):
GET /webapplication1/WebForm3.aspx HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
Accept-Language: en-GB
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; Trident/4.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; InfoPath.2; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618; MS-RTC LM 8; Zune 3.0)
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Host: (removed)
Here is the HTTP request that is generated by clicking the "Questions" link on StackOverflow.com:
GET /questions HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
Referer: https://stackoverflow.com/questions/772780/finding-previous-page-url
Accept-Language: en-GB
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; WOW64; Trident/4.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; InfoPath.2; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618; MS-RTC LM 8; Zune 3.0)
Accept-Encoding: gzip, deflate
Host: stackoverflow.com
Connection: Keep-Alive
You can see that the later, generated by a link on a page, generates the Referer header.
You can also use Server.Tansfer("B.aspx") instead of Response.Redirect("B.aspx")
Edit: Searock, if you don't want to change your existing code, Request.ServerVariables["HTTP_REFERER"].ToString() should work fine in that case.
Just to note that HTTP_REFERER is not reliable. You can't rely on that because so many clients doesn't send for various reasons (paranoid settings, security software etc.).
Also some new windows opened by JS might not have REFERER
SSL > NONE SSL pages won't have REFERER either, so be careful about relying something like that.
Better idea would be sending previous page in Querystring.
If it's ASPX you might do it in more clever way like adding a new hidden parameter to all forms or processing link just before writing out the buffer.
Could you just confirm what methods you are actually using here (ideally by editing the original question)?
HttpServerUtility (i.e. Server.) doesn't have a "Redirect" method, it has Transfer and Execute.
HttpResponse (i.e. Response.) does.
HttpResponse.Redirect will send a 302 response to the client, telling it to issue a new request for the value of the Location field. I'm then able to query Request.UrlReferrer to see the value of the page that performed the Redirect.
If you are using HttpServerUtility.Transfer or HttpServerUtility.Execute then these actions happen entirely at the server within ASP.NET, and so the "referrer" may well be null. The client browser will also think it is still on the originally requested page.
See also How to detect if an aspx page was called from Server.Execute