Share same SessionId between two asp.net web applications - c#

I used a sql server session mode between two web applications.
The session id is created in the ASPState database. I need to share the session id from first application to second without using querystring and cookies. I followed the steps from this link. Below is the code.
In both apps (web.config)
<add name="DBConnection" connectionString="Data Source=localhost;DataBase=ASPState;Integrated Security=True;uid=sa;pwd=password-1" providerName="System.Data.SqlClient"/>
<sessionState mode="SQLServer" sqlConnectionString="DBConnection" allowCustomSqlDatabase="true" regenerateExpiredSessionId="false" cookieless="false" timeout="1" ></sessionState>
<machineKey validationKey="566A547C407CB0C47ABAEC581B8B90C45E15039806352E4611B35E0FB70C1C096350A4BBAE816191331DCA55874D3F96B41FFDED4C6A913591684A90825F53A0" decryptionKey="B299127DFC22648C2EF92D7EDF2E4960277F562C60F3BDE4A4C3BFDFEA602FDF" validation="SHA1" decryption="AES" />
<modules runAllManagedModulesForAllRequests="true">
<add name="BasicAuthenticationModule" type="UserAuthenticator" />
</modules>
In first app Home.aspx.cs
protected void imgBTN_Click(object sender, EventArgs e)
{
string sessionKey = HttpContext.Current.Session.SessionID;
//How to transfer the same session id to the second application
Response.Redirect("http://localhost:43392/PartnerHome.aspx"");
}
I got the session key from ASPState database. But how to pass from the same session id to the second application ?

You can use SessionManager to set the ID to whatever you want in the target site. You just need to pass it via querystring GET or form POST from one to the other:
Source
Response.Redirect("http://localhost:43392/PartnerHome.aspx?SessID="
+ Session.SessionID);
Target
string sessionId = Request.QueryString["SessId"];
bool redirected = false;
bool isAdded = false;
new System.Web.SessionState.SessionIDManager().SaveSessionID(
HttpContext.Current, sessionId, out redirected, out isAdded);
See SessionIDManager on MSDN

Related

Why asp.net randomly create cookies on some devices?

I have a Web Server:
Windows Server 2008 R2 X64
IIS version : 7.5.7600.16385
(By this link We checked) installed .net on our machine is: 4.7 (460805)
Our website has been developed on .net 4.7 and MVC 5 and we use ASP.NET Forms Authentication to authenticate our clients.
On the loading of login page, we write a simple test cookie:
HttpCookie cookie = new HttpCookie("test", "123");
cookie.Expires = DateTime.UtcNow.AddYears(1);
Response.Cookies.Add(cookie);
when user click on the login button we read that cookie and count all cookies:
if (Request.Cookies["test"] == null)
{
if (Request.Cookies.Count > 0)
{
for(int i=0;i< Request.Cookies.Count;i++)
Loger.PointLoger.LogIt("Cookies:" +
Request.Cookies[i].Name
+" Value: "+ Request.Cookies[i].Value);
}
HttpBrowserCapabilitiesBase bc = Request.Browser;
...//Some codes to log
}
By this way we can be sure, writing cookies are enable and we can write our authentication cookie. If we can not read that test cookie we redirect user to another page and ....
Some our users reported, they can not login to our website and our server logs shows that we can not write cookie on their devices , the important thing is writing cookies are enable on their devices.
After doing some testes we found that writing cookies are randomly or something like that and one time its OK and another time its not.
By this codes we collected some information of out users:
HttpBrowserCapabilitiesBase bc = Request.Browser;
...
"IsMobileDevice:" + bc.IsMobileDevice
"-Browser:" + bc.Browser
...
For example :
Cookies.Count: 2
Cookies:_ga Value: GA1.2.163980100.1507000247
Cookies:_gid Value: GA1.2.1373100693.1518900032
IsMobileDevice:True
-Browser:Chrome
-Beta:False
-Platform:Unknown
-Type:Chrome47
-Version:47.0
-MobileDeviceModel:Unknown
-MobileDeviceManufacturer:Unknown
-GatewayMajorVersion:0
-MinorVersion:0
-MinorVersionString:0
-MajorVersion:47
-GatewayVersion:None
-Id:chrome
-HasBackButton:True
-Cookies:True
-ClrVersion: 0.0
-InputType:keyboard
Whey these cookies ( _gid and _ga) have been written but our test cookie not?
I read some posts like :
Asp.Net Forms Authentication when using iPhone UIWebView
ASP MVC Cookies not persisting
C# Login code not work on safari
Strange problem with cookies in Safari and Asp.net
Now the question is that: IS THAT A BUG ON .NET 7 ? IF YES WHAT IS THE SOLUTION?
I past here some codes of our project and because of security I replaced some codes with "....." :
On Web.config:
<authentication mode="Forms">
<forms domain=".mysite.com" name="abc" cookieless="UseCookies"
enableCrossAppRedirects="true" loginUrl="/Accounts/Login"
timeout="2880" requireSSL="false" path="/" />
</authentication>
<machineKey compatibilityMode="Framework45" validationKey="C121487......"
decryptionKey="7E43716E4C97....." validation="SHA1" decryption="AES" />
<sessionState mode="InProc" customProvider="DefaultSessionProvider" cookieless="UseCookies" cookieName="debnf">
<providers>
<add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf38...." connectionStringName="DefaultConnection" />
</providers>
</sessionState>
In App_Browsers :
<browsers>
<browser refID="Default">
<capabilities>
<capability name="cookies" value="true" />
</capabilities>
</browser>
</browsers>
UPDATE:
This is my main codes :
I write this test cookie here 
public ActionResult Login()
{     
HttpCookie cookie = new HttpCookie("test", "123");
cookie.Expires = DateTime.UtcNow.AddHours(1);
Response.Cookies.Add(cookie);
return View();
}
and when user click login I check that cookie here:
[HttpPost]
public ActionResult Login(LoginModel loginModel)
{
if (Request.Cookies["test"] == null)
{
 .....
} 
}

IIS8 MVC asp.NET Session not working. Getting null object reference error

Can't get session variables working, I've tried all the solutions I could find online.
On page 1, I call the following in the c# model
HttpContext.Current.Session["lol1"] = "123";
Later on I use an ajax call to return this session variable to me in the c# model,
return HttpContext.Current.Session["lol1"].ToString();
In javascript, I pick it up in the ajax success function and put it in an alert box with alert(e);
I get an null object reference error. Seems like my variable didn't save into the session. This all works fine on localhost via debug, including the alert.
Things I have tried (currently set):
-DefaultAppPool setting Maximum Worker Processes: 1
-IIS manager->ASP->Services->Session Properties->Enable Session State:true
-IIS manager->Session State->In process
-In my solution web.config:
<system.web>
<sessionState mode="InProc" timeout="25"></sessionState>
</system.web>
<system.webServer>
<modules>
<remove name="Session" />
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
</modules>
</system.webServer>
Try setting the SessionStateBehavior in your controller. For example:
[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
It is recommended to use ReadOnly if you only need to read from Session and not write to it to prevent blocking.
Link to Microsoft's SessionStateBehavior enumeration.
(for more info on ASP.NET's blocking when controllers use writable sessions see this link: Does Session State read/write everything when you access with DynamoDB)
Hope this helps!
Regards,
Ross

get and set values using threadlocal or cookies in wcf service

i have a wcf service deployed in iis and running. then i have created the http handlers as ny extending IHttpHandler class and in web.config file added entry as below
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="*.sync" type="MyHandler.SyncHandler, MyHandler" />
</httpHandlers>
</system.web>
</configuration>
and in the begin method of handler i have set the value in both threadlocal and cookie as
ThreadName.Value = "sample";
and
httpCookie userCookie = new HttpCookie("Cookiename");
userCookie.Value = "sample";
context.Response.Cookies.Add(userCookie);
and while retrieving those values inside wcf service application i am getting null values from both cookies and thread local.
the code which i used was
return (String)ThreadName.Value;
i do not know where i went wrong or the approach which i used is correct!
waiting for your valuable suggestions and comments

Working with Connection string

My below code sample is working fine, but I would like to add my client credentials into the web.config file (i.e, Inside the connection string).
I tried but had no luck. Can anyone please help?
protected void Page_Load(object sender, EventArgs e)
{
// Organisation service URL
var organizationUri = new Uri(ConfigurationManager.ConnectionStrings["CrmConnectionStr"].ConnectionString);
//Client credentials
var credentials = new ClientCredentials();
credentials.UserName.UserName = #"domain\username";
credentials.UserName.Password = "password";
// Use the Microsoft Dynamics CRM Online connection string from the web.config file named "CrmConnectionStr".
using (OrganizationServiceProxy _service = new OrganizationServiceProxy(organizationUri, null, credentials, null))
{
Response.Write("Connected");
}
}
Web.config file
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="CrmConnectionStr" connectionString="https://test.domain.com/XRMServices/2011/Organization.svc" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
</configuration>
As RandomWebGuy pointed out you could be connecting to Microsoft Dynamics CRM in which case you could just change your connection string to include the username etc like this connectionString="https://test.domain.com/XRMServices/2011/Organization.svc; Username=Fred.Bloggs; Password=P#ssword;"
However, if you connecting to a webservice or want to store arbitrary values such as URIs, usernames, passwords etc then use the AppSettings section, not ConnectionString.
So, something like this in your config file:
<appSettings>
<add key="UserName" value="Fred.Bloggs" />
<add key="Password" value="P#ssword" />
<add key="ServiceUri" value="https://test.domain.com/XRMServices/2011/Organization.svc />
</appSettings>
And then in code:
var organizationUri = new Uri(ConfigurationManager.AppSettings["ServiceUri"]);
// ...
credentials.UserName.UserName = ConfigurationManager.AppSettings["UserName"];
credentials.UserName.Password = ConfigurationManager.AppSettings["Password"];
Write a custom configuration to store your specific data (and do not try to piggy back on the existing connection strings area, which has an exact format).
Here is an example:
How to include simple collections in ConfigurationSection
This is much better than having several disjointed AppSetting(s) values.
Everything germane to your values is encapsulated into a known area.

Forms Authentication adding additional information along with ReturnUrl

With Forms Authentication when the app needs to redirect to sign-in page is there an event or any extensibility point that will let me do additional work to the request before it redirects to the sign-in page?
I would like to send additional information in the query string that could vary such that it wouldn't work to just statically embed that in the link in the loginUrl node in the web.config.
Edit: For clarification, I want to intercept the request prior to being redirected TO the login page.
Example:
<authentication mode="Forms">
<forms loginUrl="http://the/interwebs/login.aspx" timeout="2880"
enableCrossAppRedirects="true" />
</authentication>
And prior the user being redirected to http://the/interwebs/login.aspx I would like to be able to pack in query values so the url could end up something like http://the/interwebs/login.aspx?Action=Refresh
You can do this via handling the event HttpApplication.AuthenticateRequest
private void Application_AuthenticateRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = context.Request.Cookies[cookieName];
if (authCookie == null || string.IsNullOrEmpty(authCookie.Value))
{
//... do something
}
FYI, We currently do this via an IHttpModule implementation.
I've done this before with an http module. My example (stripped down), in vb.net. I'm just checking for a 401 status code and doing my own redirect. The big trick here was that I had to remove and add back the web.config httpModules to make sure my httpmodule stepped in from of the url authorization module. In my case I had some url rewriting for localization, and I needed to send the locale ID to the login page as it was lost by the normal redirect in the url authorization module. I made heavy use of Reflector to build up the base path (not shown), as these are private methods.
Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init
AddHandler context.EndRequest, AddressOf Context_EndRequest
End Sub
Private Sub Context_EndRequest(ByVal sender As Object, ByVal e As EventArgs)
If TypeOf sender Is HttpApplication Then
Dim hApplication As HttpApplication = DirectCast(sender, HttpApplication)
Dim hContext As HttpContext = hApplication.Context
If (hContext.Response.StatusCode = &H191) Then
hContext.Response.Redirect(String.Format("{0}?ReturnUrl={1}&someparam2={2}", basepath, HttpUtility.UrlEncode(hContext.Request.RawUrl), someparam2))
End If
End If
End Sub
web.config changes
<httpModules>
<clear/>
<!-- custom -->
<add name="SomeHttpModule" type="SomeCompany.SomeProduct.SomeHttpModule"/>
<!-- add back defaults, exlude PassportAuthentication, AnonymousIdentification, Profile -->
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/>
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule"/>
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/>
<add name="RoleManager" type="System.Web.Security.RoleManagerModule"/>
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"/>
<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule"/>
</httpModules>
You don't have to use the Forms authentication's mechanism to redirect people to a URL. You can do that in code. Just sign them in and Redirect them yourself using Response.Redirect.

Categories