dotnetopenauth asp.net mvc2 project template - broken when running from localhost:xxxx - visual-studio-2010

So I create a new dnoa mvc2 site from the template, run setup.aspx without issue, login and authorize my openid - all ok, but on the redirect to
http://localhost:18916/Auth/PopUpReturnTo?dnoa.uipopup=1&dnoa.popupUISupported=1&index=0&dnoa.userSuppliedIdentifier=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fid&dnoa.op_endpoint=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fud&dnoa.claimed_id=&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.mode=id_res&openid.op_endpoint=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fud&openid.response_nonce=2010-07-24T18%3A06%3A36ZcustWWIY5CfXTQ&openid.return_to=http%3A%2F%2Flocalhost%3A18916%2FAuth%2FPopUpReturnTo%3Fdnoa.uipopup%3D1%26dnoa.popupUISupported%3D1%26index%3D0%26dnoa.userSuppliedIdentifier%3Dhttps%253A%252F%252Fwww.google.com%252Faccounts%252Fo8%252Fid%26dnoa.op_endpoint%3Dhttps%253A%252F%252Fwww.google.com%252Faccounts%252Fo8%252Fud%26dnoa.claimed_id%3D&openid.assoc_handle=AOQobUdkpLPAPC1LRQKPaQcy2UlG8R4pjWmpDCSV_1odtA33o_HfNleiMi9ZjX8RU-kIIJnJ&openid.signed=op_endpoint%2Cclaimed_id%2Cidentity%2Creturn_to%2Cresponse_nonce%2Cassoc_handle%2Cns.ext1%2Cext1.mode%2Cext1.type.alias3%2Cext1.value.alias3%2Cext1.type.alias1%2Cext1.value.alias1&openid.sig=zkBfpugK7xT0da49hZLNQZz4Xn83UiZB%2BhEHz6B37Cw%3D&openid.identity=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fid%3Fid%3DAItOawk3FGqct35R7wya-0Bkq-0_Qnc1AB-YSw4&openid.claimed_id=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fid%3Fid%3DAItOawk3FGqct35R7wya-0Bkq-0_Qnc1AB-YSw4&openid.ns.ext1=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0&openid.ext1.mode=fetch_response&openid.ext1.type.alias3=http%3A%2F%2Fschema.openid.net%2Fcontact%2Femail&openid.ext1.value.alias3=sky.sanders%40gmail.com&openid.ext1.type.alias1=http%3A%2F%2Faxschema.org%2Fcontact%2Femail&openid.ext1.value.alias1=sky.sanders%40gmail.com&openid.ns.ext2=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fui%2F1.0&openid.ext2.mode=popup
all i get is an alert [object Error].
The 'getting started' says that all I have to do is get the database set up and I would be good to go.
This does not seem good to go. If there are other criteria to getting the sample working they should be declared.
In any case, what is required to get this running on localhost:xxx (cassini/cassinidev)?

What you're seeing is due to a bug in IE8 having to do with crossing trust zones (from Local Computer/Intranet to Internet Zone). If you use a non-IE browser it will work. When you publish your web site on the Internet, IE8 will work fine because it doesn't cross into the Intranet zone during login.

I'm using that method you gave me before for my authentication, and here is my Controller Authentication Code
<ValidateInput(False)> _
Public Function Authenticate(ByVal returnUrl As String) As ActionResult
Dim response = openid.GetResponse()
If response Is Nothing Then
' Stage 2: user submitting Identifier
Dim id As Identifier
If Identifier.TryParse(Request.Form("openid_identifier"), id) Then
Try
Return openid.CreateRequest(Request.Form("openid_identifier")).RedirectingResponse.AsActionResult()
Catch ex As ProtocolException
ViewData("Message") = ex.Message
Return View("Login")
End Try
Else
ViewData("Message") = "Invalid identifier"
Return View("Login")
End If
Else
' Stage 3: OpenID Provider sending assertion response
Select Case response.Status
Case AuthenticationStatus.Authenticated
If Not OpenIDService.IsOpenIdAssociated(response.ClaimedIdentifier) Then
UserService.AddUser(response.ClaimedIdentifier, response.FriendlyIdentifierForDisplay)
UserService.SubmitChanges()
ActivityLogService.AddActivity(OpenIDService.GetOpenId(response.ClaimedIdentifier).UserID, _
Utilities.ActivityLog.LogType.UserAdded, _
HttpContext.Request.UserHostAddress)
Else
ActivityLogService.AddActivity(OpenIDService.GetOpenId(response.ClaimedIdentifier).UserID, _
Utilities.ActivityLog.LogType.UserLogin, _
HttpContext.Request.UserHostAddress)
End If
ActivityLogService.SubmitChanges()
' Create the authentication cookie. This cookie
' includes the AuthUserData information in the
' userData field of the FormsAuthentication Cookie.
Dim authUser As Authentication.AuthUserData = New Authentication.AuthUserData(OpenIDService.GetOpenId(response.ClaimedIdentifier).User)
HttpContext.Response.Cookies.Add(Authentication.CustomAuthentication.CreateAuthCookie(response.ClaimedIdentifier, _
authUser, _
True))
authUser = Nothing
If Not String.IsNullOrEmpty(returnUrl) Then : Return Redirect(returnUrl)
Else : Return RedirectToAction("Index", "Events")
End If
Case AuthenticationStatus.Canceled
ViewData("Message") = "Canceled at provider"
Return View("Login")
Case AuthenticationStatus.Failed
ViewData("Message") = response.Exception.Message
Return View("Login")
End Select
End If
Return New EmptyResult()
End Function
I have a custom table in my database called Users and I also have an OpenIDs table with a UserID field. The OpenIds table allows me to have an unlimited number of OpenIds per user.
All of this works both locally for me as well as on the production server and staging server.

Related

MediaWiki API login: "Unable to continue login. Your session most likely timed out."

Trying to create an invite only wiki, that we can login to with a bot account once the customer has authenticated using our own webpage on our corporate website.
I've been using the documentation from here:
https://www.mediawiki.org/wiki/API:Login
Anyway I can get a success response from the API sandbox, but the POST from our new API interface webpage errors with "Unable to continue login. Your session most likely timed out."
I get the same message even if I deliberately enter invalid login credentials, so I would imagine it's not getting as far as actually checking the username/password/token. It's really annoying that there's no decent error to work from.
GETting a token via action=query works fine from the same webpage.
Our webpage is a web forms page written in VB (I know).
ServicePointManager.Expect100Continue = True
ServicePointManager.SecurityProtocol = DirectCast(3072, SecurityProtocolType)
ServicePointManager.DefaultConnectionLimit = 9999
Dim webClient As New System.Net.WebClient
Dim result As String = webClient.DownloadString("https://tmsinsight.com/TMSWiki/api.php?action=query&meta=tokens&type=login&format=json")
Dim j As Object = New JavaScriptSerializer().Deserialize(Of Object)(result)
Dim LoginToken As String = j("query")("tokens")("logintoken")
Response.Write(LoginToken & "<br/>")
webClient.Headers(HttpRequestHeader.ContentType) = "application/x-www-form-urlencoded"
Dim parameters = New NameValueCollection()
parameters.Add("action", "login")
parameters.Add("format", "json")
parameters.Add("lgname", "botusername#botusername")
parameters.Add("lgpassword", "botpassword")
parameters.Add("lgtoken", LoginToken)
Dim responsebytes = webClient.UploadValues("https://tmsinsight.com/TMSWiki/api.php", "POST", parameters)
Dim resultRequest = Encoding.UTF8.GetString(responsebytes)
Response.Write(resultRequest)

Authenticating a Xamarin Android app using Azure Active Directory fails with 401 Unauthorzed

I am trying to Authenticate a Xamarin Android app using Azure Active Directory by following article here:
https://blog.xamarin.com/authenticate-xamarin-mobile-apps-using-azure-active-directory/
I have registered a native application with AAD; note that i havent given it any additional permissions beyond creating it.
Then i use the below code to authenticate the APP with AAD
button.Click += async (sender, args) =>
{
var authContext = new AuthenticationContext(commonAuthority);
if (authContext.TokenCache.Count > 0)
authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().GetEnumerator().Current.Authority);
authResult = await authContext.AcquireTokenAsync(graphResourceUri, clientId, returnUri, new PlatformParameters(this));
SetContentView(Resource.Layout.Main);
doGET("https://management.azure.com/subscriptions/{subscription-id}/resourceGroups/OPSLABRG/providers/Microsoft.Compute/virtualMachines/LABVM?api-version=2015-08-01", authResult.AccessToken);
};
private string doGET(string URI, String token)
{
Uri uri = new Uri(String.Format(URI));
// Create the request
var httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
httpWebRequest.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + token);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "GET";
// Get the response
HttpWebResponse httpResponse = null;
try
{
httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
}
catch (Exception ex)
{
Toast.MakeText(this, "Error from : " + uri + ": " + ex.Message, ToastLength.Long).Show();
return null;
}
}
This seems to be getting a token when using a Work account.
Using a valid hotmail account throws error A Bad Request was received.
However the main problem is when i try to retrieve VM details using REST.
the REST GET method fails with 401 Unauthorized error even when using the Work account.
I am not sure if the code is lacking something or if i need to give some additional permissions for the App. This needs to be able to support authenticating users from other tenants to get VM details.
Any guidance is appreciated.
note that i havent given it any additional permissions beyond creating
it.
This is the problem here.
In order for you to call the Azure Management API https://management.azure.com/, you must first register your application to have permissions to call this API.
You can do that as a part of your app registration like so:
Only at that point, will your app be authorized to call ARM, and your calls should start to work.
According to your description, I checked this issue on my side. As Shawn Tabrizi mentioned that you need to assign the delegated permission for accessing ARM Rest API. Here is my code snippet, you could refer to it:
var context = new AuthenticationContext($"https://login.windows.net/{tenantId}");
result = await context.AcquireTokenAsync(
"https://management.azure.com/"
, clientId, new Uri("{redirectUrl}"), platformParameter);
I would recommend you using Fiddler or Postman to simulate the request against ARM with the access_token to narrow this issue. If any errors, you could check the detailed response for troubleshooting the cause.
Here is my test for retrieving the basic information of my Azure VM:
Additionally, you could leverage jwt.io for decoding your access_token and check the related properties (e.g. aud, iss, etc.) as follows to narrow this issue.

ServiceStack user session not found when using sessionId in client Headers or Cookies

I am using ServiceStack v4 with custom Authentication. This is setup and working correctly. I can call the /auth service and get a returned AuthorizationResponse with unique SessionId.
I also have swagger-ui plugin setup. Using it, I can authenticate via /auth and then call one of my other services which require authentication without issue.
Now, from a secondary MVC application using the c# JsonServiceClient I can again successfully make a call to /auth and then secured services using the same client object. However, if I dispose of that client (after saving the unique sessionId to a cookie), then later create a new client, and either add the sessionId as a Cookie or via headers using x-ss-pid as documented, calling a services returns 401. If I call a non-secure service, but then try to access the unique user session, it returns a new session.
If I look at the request headers in that service, the cookie or Header is clearly set with the sessionId. The sessionId also exists in the sessionCache. The problem seems to be that the code which tries to get the session from the request isn't finding it.
To be more specific, it appears that ServiceExtensions.GetSessionId is looking at the HostContext and not the calling Request. I'm not sure why. Perhaps I misunderstand something along the way here.
If I directly try and fetch my expected session with the following code it's found without issue.
var req = base.Request;
var sessionId = req.GetHeader("X-" + SessionFeature.PermanentSessionId);
var sessionKey = SessionFeature.GetSessionKey(sessionId);
var session = (sessionKey != null ? Cache.Get<IAuthSession>(sessionKey) : null)?? SessionFeature.CreateNewSession(req, sessionId);
So, am I missing something obvious here? Or maybe not so obvious in creating my secondary client?
Sample code of client calls
Here is my authorization code. It's contained in a Controller class. This is just the relevant parts.
using (var client = new JsonServiceClient(WebHelper.BuildApiUrl(Request)))
{
try
{
loginResult = client.Post(new Authenticate()
{
UserName = model.Email,
Password = model.Password,
RememberMe = model.RememberMe
});
Response.SetCookie(new HttpCookie(SessionFeature.PermanentSessionId, loginResult.SessionId));
return true;
}
}
Here is my secondary client setup and service call, contained in it's own controller class in another area of the MVC application
using (var client = new JsonServiceClient(WebHelper.BuildApiUrl(Request)))
{
var cCookie = HttpContext.Request.Cookies.Get(SessionFeature.PermanentSessionId);
if (cCookie != null)
{
client.Headers.Add("X-" + SessionFeature.PermanentSessionId, cCookie.Value);
client.Headers.Add("X-" + SessionFeature.SessionOptionsKey, "perm");
}
response = client.Get(new SubscriptionStatusRequest());
}
Additional Update
During the Authenticate process the following function is called from HttpRequestExtensions with the name = SessionFeature.PermanentSessionId
public static class HttpRequestExtensions
{
/// <summary>
/// Gets string value from Items[name] then Cookies[name] if exists.
/// Useful when *first* setting the users response cookie in the request filter.
/// To access the value for this initial request you need to set it in Items[].
/// </summary>
/// <returns>string value or null if it doesn't exist</returns>
public static string GetItemOrCookie(this IRequest httpReq, string name)
{
object value;
if (httpReq.Items.TryGetValue(name, out value)) return value.ToString();
Cookie cookie;
if (httpReq.Cookies.TryGetValue(name, out cookie)) return cookie.Value;
return null;
}
Now what occurs is the httpReq.Items contains a SessionFeature.PermanentSessionId value, but I have no clue why and where this gets set. I don't even understand at this point what the Items container is on the IRequest. The code thus never gets to the functionality to check my cookies or headers
The Session wiki describes the different cookies used by ServiceStack Session.
If the client wants to use a Permanent SessionId (i.e. ss-pid), it also needs to send a ss-opt=perm Cookie to indicate it wants to use the permanent Session. This Cookie is automatically set when authenticating with the RememberMe=true option during Authentication.
There was an issue in the Session RequestFilter that was used to ensure Session Id's were attached to the current request weren't using the public IRequest.GetPermanentSessionId() API's which also looks for SessionIds in the HTTP Headers. This has been resolved with this commit which now lets you make Session requests using HTTP Headers, e.g:
//First Authenticate to setup an Authenticated Session with the Server
var client = new JsonServiceClient(BaseUrl);
var authResponse = client.Send(new Authenticate
{
provider = CredentialsAuthProvider.Name,
UserName = "user",
Password = "p#55word",
RememberMe = true,
});
//Use new Client instance without Session Cookies populated
var clientWithHeaders = new JsonServiceClient(BaseUrl);
clientWithHeaders.Headers["X-ss-pid"] = authResponse.SessionId;
clientWithHeaders.Headers["X-ss-opt"] = "perm";
var response = clientWithHeaders.Send(new AuthOnly()); //success
This fix is available from v4.0.37+ that's now available on MyGet.
However, if I dispose of that client (after saving the unique sessionId to a cookie)
If the client is disposed where is the cookie you are saving the sessionId located? This answer might provide some additional information.
then later create a new client, and either add the sessionId as a Cookie or via headers using x-ss-pid as documented, calling a services returns 401
If you store/save a valid sessionId as a string you should be able to supply it within a CookieContainer of a new client (given the sessionId is still authenticated). I know you said you tried adding the sessionId as a Cookie but I don't a see sample within your question using the CookieContainer so it should look something like...
using (var client = new JsonServiceClient(WebHelper.BuildApiUrl(Request)))
{
var cCookieId = savedCookieId; //a string that I believe you saved from a successfully authenticated client that is now disposed
if (cCookieId != null)
{
var cookie = new Cookie(SessionFeature.PermanentSessionId, cCookieId);
//cookie.Domian = "somedomain.com" //you will probably need to supply this as well
client.CookieContainer.Add(cookie)
}
response = client.Get(new SubscriptionStatusRequest());
}

Google+ insert moment using google-api-dotnet-client

I am trying to write an activity in Google+ using the dotnet-client. The issue is that I can't seem to get the configuration of my client app correctly. According to the Google+ Sign-In configuration and this SO question we need to add the requestvisibleactions parameter. I did that but it did not work. I am using the scope https://www.googleapis.com/auth/plus.login and I even added the scope https://www.googleapis.com/auth/plus.moments.write but the insert still did not work.
This is what my request url looks like:
https://accounts.google.com/ServiceLogin?service=lso&passive=1209600&continue=https://accounts.google.com/o/oauth2/auth?scope%3Dhttps://www.googleapis.com/auth/plus.login%2Bhttps://www.googleapis.com/auth/plus.moments.write%26response_type%3Dcode%26redirect_uri%3Dhttp://localhost/%26state%3D%26requestvisibleactions%3Dhttp://schemas.google.com/AddActivity%26client_id%3D000.apps.googleusercontent.com%26request_visible_actions%3Dhttp://schemas.google.com/AddActivity%26hl%3Den%26from_login%3D1%26as%3D-1fbe06f1c6120f4d&ltmpl=popup&shdf=Cm4LEhF0aGlyZFBhcnR5TG9nb1VybBoADAsSFXRoaXJkUGFydHlEaXNwbGF5TmFtZRoHQ2hpa3V0bwwLEgZkb21haW4aB0NoaWt1dG8MCxIVdGhpcmRQYXJ0eURpc3BsYXlUeXBlGgdERUZBVUxUDBIDbHNvIhTeWybcoJ9pXSeN2t-k8A4SUbfhsygBMhQivAmfNSs_LkjXXZ7bPxilXgjMsQ&scc=1
As you can see from there that there is a request_visible_actions and I even added one that has no underscore in case I got the parameter wrong (requestvisibleactions).
Let me say that my app is being authenticated successfully by the API. I can get the user's profile after being authenticated and it is on the "insert moment" part that my app fails. My insert code:
var body = new Moment();
var target = new ItemScope();
target.Id = referenceId;
target.Image = image;
target.Type = "http://schemas.google.com/AddActivity";
target.Description = description;
target.Name = caption;
body.Target = target;
body.Type = "http://schemas.google.com/AddActivity";
var insert =
new MomentsResource.InsertRequest(
// this is a valid service instance as I am using this to query the user's profile
_plusService,
body,
id,
MomentsResource.Collection.Vault);
Moment result = null;
try
{
result = insert.Fetch();
}
catch (ThreadAbortException)
{
// User was not yet authenticated and is being forwarded to the authorization page.
throw;
}
catch (Google.GoogleApiRequestException requestEx)
{
// here I get a 401 Unauthorized error
}
catch (Exception ex)
{
} `
For the OAuth flow, there are two issues with your request:
request_visible_actions is what is passed to the OAuth v2 server (don't pass requestvisibleactions)
plus.moments.write is a deprecated scope, you only need to pass in plus.login
Make sure your project references the latest version of the Google+ .NET client library from here:
https://developers.google.com/resources/api-libraries/download/stable/plus/v1/csharp
I have created a project on GitHub showing a full server-side flow here:
https://github.com/gguuss/gplus_csharp_ssflow
As Brettj said, you should be using the Google+ Sign-in Button as demonstrated in the latest Google+ samples from here:
https://github.com/googleplus/gplus-quickstart-csharp
First, ensure you are requesting all of the activity types you're writing. You will know this is working because the authorization dialog will show "Make your app activity available via Google, visible to you and: [...]" below the text that starts with "This app would like to". I know you checked this but I'm 90% sure this is why you are getting the 401 error code. The following markup shows how to render the Google+ Sign-In button requesting access to Add activities.
<div id="gConnect">
<button class="g-signin"
data-scope="https://www.googleapis.com/auth/plus.login"
data-requestvisibleactions="http://schemas.google.com/AddActivity"
data-clientId="YOUR_CLIENT_ID"
data-accesstype="offline"
data-callback="onSignInCallback"
data-theme="dark"
data-cookiepolicy="single_host_origin">
</button>
Assuming you have a PlusService object with the correct activity type set in data-requestvisibleactions, the following code, which you should be able to copy/paste to see it work, concisely demonstrates writing moments using the .NET client and has been tested to work:
Moment body = new Moment();
ItemScope target = new ItemScope();
target.Id = "replacewithuniqueforaddtarget";
target.Image = "http://www.google.com/s2/static/images/GoogleyEyes.png";
target.Type = "";
target.Description = "The description for the activity";
target.Name = "An example of add activity";
body.Target = target;
body.Type = "http://schemas.google.com/AddActivity";
MomentsResource.InsertRequest insert =
new MomentsResource.InsertRequest(
_plusService,
body,
"me",
MomentsResource.Collection.Vault);
Moment wrote = insert.Fetch();
Note, I'm including Google.Apis.Plus.v1.Data for convenience.
Ah it's that simple! Maybe not? I am answering my own question and consequently accept it as the answer (after a few days of course) so others having the same issue may be guided. But I will definitely up-vote Gus' answer for it led me to the fix for my code.
So according to #class answer written above and as explained on his blog the key to successfully creating a moment is adding the request_visible_actions parameter. I did that but my request still failed and it is because I was missing an important thing. You need to add one more parameter and that is the access_type and it should be set to offline. The OAuth request, at a minimum, should look like: https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/plus.login&response_type=code&redirect_uri=http://localhost/&request_visible_actions=http://schemas.google.com/AddActivity&access_type=offline.
For the complete and correct client code you can get Gus' example here or download the entire dotnet client library including the source and sample and add what I added below. The most important thing that you should remember is modifying your AuthorizationServerDescription for the Google API. Here's my version of the authenticator:
public static OAuth2Authenticator<WebServerClient> CreateAuthenticator(
string clientId, string clientSecret)
{
if (string.IsNullOrWhiteSpace(clientId))
throw new ArgumentException("clientId cannot be empty");
if (string.IsNullOrWhiteSpace(clientSecret))
throw new ArgumentException("clientSecret cannot be empty");
var description = GoogleAuthenticationServer.Description;
var uri = description.AuthorizationEndpoint.AbsoluteUri;
// This is the one that has been documented on Gus' blog site
// and over at Google's (https://developers.google.com/+/web/signin/)
// This is not in the dotnetclient sample by the way
// and you need to understand how OAuth and DNOA works.
// I had this already, see my original post,
// I thought it will make my day.
if (uri.IndexOf("request_visible_actions") < 1)
{
var param = (uri.IndexOf('?') > 0) ? "&" : "?";
description.AuthorizationEndpoint = new Uri(
uri + param +
"request_visible_actions=http://schemas.google.com/AddActivity");
}
// This is what I have been missing!
// They forgot to tell us about this or did I just miss this somewhere?
uri = description.AuthorizationEndpoint.AbsoluteUri;
if (uri.IndexOf("offline") < 1)
{
var param = (uri.IndexOf('?') > 0) ? "&" : "?";
description.AuthorizationEndpoint =
new Uri(uri + param + "access_type=offline");
}
// Register the authenticator.
var provider = new WebServerClient(description)
{
ClientIdentifier = clientId,
ClientSecret = clientSecret,
};
var authenticator =
new OAuth2Authenticator<WebServerClient>(provider, GetAuthorization)
{ NoCaching = true };
return authenticator;
}
Without the access_type=offline my code never worked and it will never work. Now I wonder why? It would be good to have some explanation.

ASP.NET MVC3 - Anti-CSRF and Session timeout

I am implementing Anti-Forgery framework as described here:
http://weblogs.asp.net/srkirkland/archive/2010/04/14/guarding-against-csrf-attacks-in-asp-net-mvc2.aspx
Plus, to minimize the coding effort, I did the token insertion part at client side handling form.onsumit and ajaxsend events. Everything works fine – until the session expires.
In my application, I display a popup when the user session gets timed out where the user can re-login and continue without refreshing the current page so that the work-in-progress will be safe. But this doesn't go well with the Anti-CSRF logic. When the user tries to re-login after a timed-out session, this throws a CSRF exception as the cookie (__RequestVerificationToken_Lw__) is already expired and all the future POSTs will be invalid until next page refresh.
Is there any way to set the cookie end time to a future date rather than 'session'? I tried to edit Response.Cookie but that made the cookie invalid.
Any help would be appreciated.
Thanks
At the time of user session out (when displaying a popup) is it possible for you to set the httpcookie with expiry in server side.
I have extracted some code from the microsofts antiforgery token implementation.
internal static string GetAntiForgeryTokenName(string appPath)
{
if (string.IsNullOrEmpty(appPath))
{
return "__RequestVerificationToken";
}
return "__RequestVerificationToken_" + Base64EncodeForCookieName(appPath);
}
private static string Base64EncodeForCookieName(string s)
{
byte[] bytes = Encoding.UTF8.GetBytes(s);
string text = Convert.ToBase64String(bytes);
return text.Replace('+', '.').Replace('/', '-').Replace('=', '_');
}
Below code which set the cookie in server side.
string antiForgeryTokenName = GetAntiForgeryTokenName(HttpContext.Request.ApplicationPath);
HttpCookie httpCookie = HttpContext.Request.Cookies[antiForgeryTokenName];
HttpCookie httpCookie2 = new HttpCookie(antiForgeryTokenName, httpCookie.Value)
{
HttpOnly = true
//// your domain Domain = ,
//// path Path = ,
//// set path Expires =
};
HttpContext.Response.Cookies.Set(httpCookie2);
Please note that I haven't tested this code, just give a try if you dont have any other options.

Resources