Is it possible to get session cookie name in medium trust level? The code below works in full trust, but throws a security exception in medium trust level.
string sessionCookieName = ((SessionStateSection)WebConfigurationManager.GetSection("system.web/sessionState")).CookieName;
You can use HTTP_COOKIE server variable from the Request object, to get the cookie string that was included with the request.
string cookieString = Request.ServerVariables["HTTP_COOKIE"]
If what you want is to obtain the session cookie name from the web.config, why don't you add a simple entry in the appSettings section containing the session cookie name?
<appSettings>
<add key="SessionCookieName" value="__SessionCookieName"/>
<appSetting>
<sessionState cookieName="__SessionCookieName" />
Then you can read the web.config setting value by using the following code:
public static bool SessionCookieName
{
get { return ConfigurationManager.AppSettings["SessionCookieName"]; }
}
Related
I'm working with cookies.
I want to delete my asp .net session cookies which are not pointing to the root directory as shown below.
I have updated the path of the cookie using the below piece of code:
public class CookieManager : SessionIDManager, ISessionIDManager
{
void ISessionIDManager.SaveSessionID(HttpContext context, string id, out bool redirected, out bool cookieAdded)
{
base.SaveSessionID(context, id, out redirected, out cookieAdded);
if (cookieAdded)
{
SessionStateSection sessionStateSection = (System.Web.Configuration.SessionStateSection)ConfigurationManager.GetSection("system.web/sessionState");
var cookie = context.Response.Cookies[sessionStateSection.CookieName];
cookie.Path = context.Request.ApplicationPath;
}
}
}
Web.config code :
<sessionState sessionIDManagerType="ANJU.Reports.WebUI.Library.CookieManager" timeout="30" cookieName="DVCookie"/>
I tried deleting this cookie, like how we delete the cookies which are pointing to the root directory but failed to do so.
Similar to ISessionIDManager.SaveSessionID, we also have ISessionIDManager.RemoveSessionID to remove the session cookies.
As per the microsoft document, mentioned in the below link:
https://learn.microsoft.com/en-us/dotnet/api/system.web.sessionstate.sessionidmanager.removesessionid?view=netframework-4.8
We can't directly call this method from our application code.
The SessionStateModule calls the RemoveSessionID method during the ReleaseRequestState event to remove the session identifier from the Cookies collection of the HttpResponse if a new session was created but was not used.
Can you please help me how to trigger this ReleaseRequestState event from my asp.net application?
Every piece of help is much appreciated.
Thank you all in advance.
I am working on ADFS authentication using IDP page of ADFS.
I am able to redirect to IDP page successfully and also able to redirect back to my application successfully after getting authenticated.
Here I am getting below error message after returning back to my application:
No valid key mapping found for securityToken:
'System.IdentityModel.Tokens.X509SecurityToken' and issuer
I have added below code in web.config file to decrypt claims information.
<authority name="http://idp.neuronetics.com/adfs/services/trust">
<keys>
<add thumbprint="1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234"/>
</keys>`enter code here
<validIssuers>
<add name="http://adfsServiceDomain/adfs/services/trust" />
</validIssuers>
</authority>
I have reviewed many articles related to this. Most of the articles suggest to verify the thumbprint of token signing certificate of ADFS.
I have double checked and the thumbprint is perfect.
Anyone have any idea regarding this issue ?
Please advise.
Please let me know if you have any concern or query or if you need more information.
Since you are using WIF rather than OWIN, you can pretty much override the default issuer registry and provide your own one that gives you much more control over what issuers are accepted.
Overriding the issuer registry involves providing a class that inherits from the IssuerNameRegistry
public class CustomIssuerNameRegistry : IssuerNameRegistry
{
public override string GetIssuerName( SecurityToken securityToken )
{
X509SecurityToken x509Token = securityToken as X509SecurityToken;
if ( x509Token != null &&
x509Token.Certificate != null
)
{
// this is where you validate the certificate programatically
// for example, you can verify the thumbprint against
// a list of accepted thumprints
// return a string, the name of the issuer to indicate
// succesfull validation
return "issuer name";
}
throw new SecurityTokenException( "Untrusted issuer." );
}
and registering the issuer registry in the WIF pipeline in web.config
<system.identityModel>
<identityConfiguration>
<issuerNameRegistry type="Namespace.CustomIssuerNameRegistry, AssemblyName" />
</identityConfiguration>
</system.identityModel>
This approach lets you debug incoming token's certificate thoroughly.
I have two sites, both on the same domain, but with different sub-domains.
site1.mydomain.example
site2.mydomain.example
Once I'm authenticated on each, I look at the cookies included in subsequent request and they are identical for each site.
However, if I log into the first site, and then navigate to the other, I expect my cookie from site 1 to be sent with the request to site2, but this is not the case. Here are the properties of my cookies.
Logging into Site1, this cookie then exists
Name = MySite
Domain =
Has Keys = False
HttpOnly = False
Path = /
Value = 1C41854066B03D8CC5679EA92DE1EF427DAC65D1BA0E672899E27C57245C1F0B7E93AB01B5563363AB4815A8F4BDE9D293FD261E03F8E60B8497ABBA964D8D315CCE1C8DD220C7176E21DC361935CF6
Expires = 1/1/0001 12:00:00 AM
Logging into Site2, these cookies then exists.
Name = MySite
Domain =
Has Keys = False
HttpOnly = False
Path = /
Value = C8C69F87F993166C4D044D33F21ED96463D5E4EB41E1D986BF508DA0CBD5C2CA7D782F59F3BC96871108997E899FF7401C0D8615705BDB353B56C7E164D2302EE6731F41705016105AD99F4E0578ECD2
Expires = 1/1/0001 12:00:00 AM
I've set the domain on each (doesn't show up in a request cookie as it's only needed on the client).
I've made sure my Forms setting for each are identical
I've made sure my machine key settings are the same in both web configs.
I'm at a loss on why this isn't working. What is it that a cookie contains that the client will send it for one sub-domain and not the other when they are both using the same auth cookies so far as I can tell?
Please comment if there is more info you'd like to see. I've been struggling with this for two days now. According to this article this should be working.
code added
Here is my config file setting for my authentication. This is used in both sites.
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn"
defaultUrl="~/Home/Index"
name="MySite"
protection="All"
path="/"
domain="mydomain.example"
enableCrossAppRedirects="true"
timeout="2880"
/>
And here is my code to create the cookie in Site1.
//Add a cookie that the Site2 will use for Authentication
var cookie = FormsAuthentication.GetAuthCookie(userName, true);
cookie.Name = "MySite";
cookie.HttpOnly = false;
cookie.Expires = DateTime.Now.AddHours(24);
cookie.Domain = "mydomain.example";
HttpContext.Response.Cookies.Add(cookie);
HttpContext.Response.Redirect(site2Url,true);
UPDATE 2:
I noticed something strange while testing. When I add a cookie to the response for site1, it get's added to this directory...
C:\Users\jreddy\AppData\Roaming\Microsoft\Windows\Cookies
When I add a cookie to the response for site, it gets added to this directory...
C:\Users\jreddy\AppData\Roaming\Microsoft\Windows\Cookies\Low
That could be my problem. Could it be that one of my sites is included in the local intranet zone?
UPDATE 3: Problem found, solution unknown
It seems that my problem has to do with my second site being part of the Local Intranet Zone. If I go to Site1 using Firefox it works, but I have to enter my Windows credentials. If I go thru IE, my credentials are picked up automatically, but the cookies can't be read by site2. I may ask this in another question.
Set the property of Domain to .mydomain.example in each Cookies of two subdomains websites. Like:
Response.Cookies["test"].Value = "some value";
Response.Cookies["test"].Domain = ".mysite.example";
In Site A:
HttpCookie hc = new HttpCookie("strName", "value");
hc.Domain = ".mydomain.example"; // must start with "."
hc.Expires = DateTime.Now.AddMonths(3);
HttpContext.Current.Response.Cookies.Add(hc);
In Site B:
HttpContext.Current.Request.Cookies["strName"].Value
Add new cookie and specify domain like this
HttpCookie cookie = new HttpCookie("cookiename", "value");
cookie.Domain = "domain.example";
For forms authentication set this in web.config
<forms name=".ASPXAUTH"
loginUrl="login.aspx"
protection="All"
timeout="30"
path="/"
requireSSL="false"
domain="domain.example">
</forms>
The cookie will be accessible to all the subdomains.
In order for each domain to decrypt the the cookie, all web.config files must use the same encryption/decryption algorithm and key. (how to create a machine key)
Example:
// do not wrap these values like this in the web.config
// only wrapping for code visibility on SO
<machineKey
validationKey="21F090935F6E49C2C797F69BBAAD8402ABD2EE0B667A8B44EA7DD4374267A75
D7AD972A119482D15A4127461DB1DC347C1A63AE5F1CCFAACFF1B72A7F0A281
B"
decryptionKey="ABAA84D7EC4BB56D75D217CECFFB9628809BDB8BF91CFCD64568A145BE59719
F"
validation="SHA1"
decryption="AES"
/>
For easier deployments, these values can be stored in a separate file:
<machineKey configSource="machinekey.config"/>
For added security you can also encrypt the machine key for further protection..
If you're using Forms authentication on all of your sub domains, all you need to do is to add domain=".mydomain.example" property to the <forms> node in your web.config
Note the leading period in .mydomain.example
This simple change by itself will make your authentication cookie valid in all sub-domains; no need to manually set any cookies.
I've created a HttpContext extension method that will write a sub domain safe cookie.
Blog post and discussion
public static class HttpContextBaseExtenstions
{
public static void SetSubdomainSafeCookie(this HttpContextBase context, string name, string value)
{
var domain = String.Empty;
if (context.Request.IsLocal)
{
var domainSegments = context.Request.Url.Host.Split('.');
domain = "." + String.Join(".", domainSegments.Skip(1));
}
else
{
domain = context.Request.Url.Host;
}
var cookie = new HttpCookie(name, value)
{
Domain = domain
};
context.Response.SetCookie(cookie);
}
}
// usage
public class MyController : Controller
{
public ActionResult Index()
{
this.Context.SetSubdomainSafeCookie("id", Guid.NewGuid().ToString());
return View();
}
}
how to check whether users is authenticated and session is valid on pages after say 30 mins.
Assuming you are either hooking into the standard ASP.NET membership providers or using Basic/Digest authentication in IIS then you can easily tell if a user is authenticated using:
if (Request.IsAuthenticated)
{
// User is authenticated, allow them to do things
}
If their authentication token has expired (defaults to 20 minutes with Forms Auth, Windows auth should re-authenticate correctly with each request), then the next time you check that, IsAuthenticated will return false.
You could store a token in the users session that maps back to their user account (either a hash of their user name, or their user id or similar), and then check the two on the request - if they don't match, then the session has become invalid:
// Get the current user, and store their ID in session
MembershipUser user = Membership.GetUser();
Session["UserId"] = user.ProviderUserKey;
To check this:
if (null != Session["UserId"]) {
MembershipUser user = Membership.GetUser();
if (Session["UserId"] == user.ProviderUserKey) {
// User and session are valid
}
}
But to be honest, it depends on what you are trying to do.
If you want to restrict access to certain areas of your website if the user isn't logged in, then there are mechanisms in the configuration that allow for that:
In your web.config you can add lines like the following:
<location path="SecureDirectory">
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</location>
This will deny all anonymous users access to the directory /SecureDirectory/ and all content below it, and direct them instead to your configured login page - for more information on the Authorization element, see "How to: Configure Directories Using Location Settings".
You have to make the session expire after certain time.
So, there is a section in your web.config or you have to add the section in <system.web />
Put this section inside:
<sessionState mode="InProc" stateConnectionString="tcpip=127.0.0.1:42424"
stateNetworkTimeout="10" cookieless="false" timeout="30" />
If you notice we are using InProc mode and timeout to be 30
Now its all up to you.
Add a key in Session object when you can find in any WebForm page.
public void btnLogin(object sender, EventArgs e) {
if (validUser) {
Session["authenticated"] = true;
}
}
and check Session["authenticated"] when required.
Session object will be expired in 30 minutes of session instantiation.
Hope this help. Please feel free to leave me a comment if you face trouble.
In the start of a session, you can store some key value in session state via the Global.asax:
void Session_Start(object sender, EventArgs e)
{
Session["userId"] = userId; // obtained from a data source or some other unique value, etc.
}
Whenever a user makes a page request or postback, on page load of any or all your pages, check if session value is null:
protected void Page_Load(object sender, EventArgs e)
{
if(Session["userId"] == null)
{
Response.Redirect("logout.aspx");
}
// do other stuff
}
If it is, then the session has expired and you can redirect then to logout page or whatever. The timeout interval is defined in your web.config file.
I have a WCF service, hosted in IIS, which I require to impersonate the annon account.
in my Webconfig
<authentication mode="Windows"/>
<identity impersonate ="true"/>
Testing the following, with vs2008
public void ByRuleId(int ruleId)
{
try
{
string user = WindowsIdentity.GetCurrent().Name;
string name = Thread.CurrentPrincipal.Identity.Name;
........
//get the data as a string.
using (FileStream fs = File.Open(location, FileMode.Open))
using (StreamReader reader = new StreamReader(fs))
{
rawData = reader.ReadToEnd();
}
}
catch.....
}
this works. however if I add impersonation attribute
[OperationBehavior(Impersonation=ImpersonationOption.Required)]
public void ByRuleId(int ruleId)
this does not work with the error message
"Either a required impersonation level was not provided, or the provided impersonation level is invalid."
a little poking around I noticed the first way was authenticated by Kerboros and the second way just failed on authentication type
I am using the WCF client tool, to pass my credentials. this seems to be working.
Check the 'TokenImpersonationLevel' of identity of the current thread; you'll need it to be at least 'Impersonation' to perform operations on the machine that the service is running on.
Typically, if you are using a proxy client, you'll need to set the 'TokenImpersonationLevel' of the client:
http://www.devx.com/codemag/Article/33342/1763/page/4
the main goal of this was to get anon access, even tho MattK answer was a great help.
here is what i did to do so.
on the implementation of the WCF contract I added the
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class TransferFile : ITransferFile
and in the web.config
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled ="true" />
after this i was able to impersonate the anon account