asp Forms Authentication across multiple applications (sub-domains) - c#

I have 4 applications running on my IIS server. One of these applications is my 'main site' and there are 3 sub applications as shown in this diagram -
All of these sites are in the same domain: mainSite.mydomain.com, app1.mydomain.com etc..
I would like users to be able to login to either APP 1, APP 2 or APP 3 and also be logged into the MAIN SITE, however if the user is logged into APP 1 they can't access APP 2 or APP3. So basically a user will only have access to one of the apps and the main site using the same login.
I currently use the following code however this allows the user to access all the applications with the same login :
<forms name=".ASPXAUTH" loginUrl="Login/" protection="Validation" timeout="120" path="/" domain=".mydomain.com"/>
and this is the code I use to create the authentication ticket:
var ticket = new FormsAuthenticationTicket(
1, user.EmailAddress,
now,
now.Add(mExpirationTimeSpan),
createPersistentCookie,
user.EmailAddress,
FormsAuthentication.FormsCookiePath);
var encryptedTicket = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
cookie.HttpOnly = true;
if (ticket.IsPersistent)
{
cookie.Expires = ticket.Expiration;
}
cookie.Secure = FormsAuthentication.RequireSSL;
cookie.Path = FormsAuthentication.FormsCookiePath;
if (FormsAuthentication.CookieDomain != null)
{
cookie.Domain = FormsAuthentication.CookieDomain;
}
mHttpContext.Response.Cookies.Add(cookie);
How would I determine what application the user should have access to and limit the users access to the other applications? The only thing I can currently think of is somehow adding information regarding which application to use into the cookie, however would I be able to decrypt this information?

Related

SSRS Forms Authentication - How To Pass Cookie Credentials To Report Server

I am currently attempting to render the SSRS report in my web application using forms authentication.
My SSRS Report Version is 2016.
Initially I was under the impression that NetworkCredentials would work, and after encountering errors, I found that we are required to use FormsAuthentication, with passing the cookie as a means of authenticating the user.
I have done the necessary settings on the config files in the Reporting Server by following the guide from the link below:-
https://github.com/Microsoft/Reporting-Services/tree/master/CustomSecuritySample2016
The reporting services works as intended on the localhost/ReportServer and on
the SSRS Portal, localhost/Reports. I am also able to access said server
remotely.
Below is the code I used to obtain the authenticated cookie.
MyReportingService rsClient = new MyReportingService();
rsClient.Url = "http://xxx.xxx.xxx.xxx/reportserver/ReportService2010.asmx";
try
{
rsClient.LogonUser("user", "password", "");
Cookie myAuthCookie = rsClient.AuthCookie;
HttpCookie cookie = new HttpCookie(myAuthCookie.Name, myAuthCookie.Value);
Response.Cookies.Add(cookie);
}
Which supposedly would then be used to authenticate the user.
Cookie authCookie = new Cookie(cookie2.Name, cookie2.Value);
authCookie.Domain = "DomainName";
rvSiteMapping.ServerReport.ReportServerCredentials = new MyReportServerCredentials(authCookie);
rvSiteMapping.ServerReport.Cookies.Add(authCookie);
And in my forms authentication within the IReportsServerCredentials Class:-
public bool GetFormsCredentials(out Cookie authCookie,
out string user, out string password, out string authority)
{
authCookie = m_authCookie;
user = password = authority = null;
return true; // Use forms credentials to authenticate.
}
The issue I am experiencing is when the application is passing the credentials to the report server. I believe I must be doing this part incorrectly because while my application does get the cookie, when it authenticates the credentials provided by the cookie, I receive the text/html error:-
Object moved to <a href="/ReportServer/logon.aspx?ReturnUrl=%2fReportserver%2fReportExecution2005.asmx" />
This error is in response to setting a default generic Identity in the event that
the HttpContext.Current.User = null.
if (HttpContext.Current != null
&& HttpContext.Current.User != null)
{
userIdentity = HttpContext.Current.User.Identity;
}
else
{
userIdentity = new GenericIdentity("AnonymousUser");
}
I have tried googling the answer but most of the results are for
windows authentication and the few that are related to forms authentication
are very similar to the code I referred to.
The underlying cause of the issue was under my nose the whole time.
The domain name should refer to the web domain and not the active directory domain.
authCookie.Domain = "DomainName";
The cookie is now able to authenticate the user as intended.
Hopefully this helps anyone who happens to make the same mistake.

Store Id after authentication ASP net web forms

I would like to save the user ID after the forms authentication is made through email and password. I am currently using a session to do so;
However the session and the form authentication have different timeouts and because the session is a server type of variable when one user is logged in if I login with a different username on another machine the session simple changes its value and that is a major issue.
Besides Caching is there any other way to accomplish it?
You can store user ID in expanded authentication cookie. On authorization routine compose custom cookie and add it to response:
var ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(60), false, userId.ToString()));
HttpContext.Current.Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket)) { HttpOnly = true });
You can decrypt that cookie for authenticated request and find out what was user ID:
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
int iserId = int.Parse(authTicket.UserData);

Combine server-side and client-side authentication with WebAPI

I have a legacy ASP.NET webforms application in which users login via a form that is processed server-side. If the entered username + password match to credentials in the database, I set some values in the sessions (e.g., the current user ID) and perform a Response.Redirect afterwards. I'm also creating a HttpCookie for a "automatically relog me next time I visit" functionality.
Currently, I'm also adding WebApi support into that web application. I've managed to implement token authentication which allows me to login on the client side.
How can I combine both authentication approaches? I want to the user to enter his credentials once, get authenticated on the server side and on the client side an redirect the users to another page after authenticating.
The following code will create a cookie to keep user logged in.
// login etc
if (chkRemember.Checked)
{
// calculate the total number of minutes in 20 days to use as the time out.
int timeout = (int)TimeSpan.FromDays(30).TotalMinutes;
// create an authentication ticket
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(txtUserName.Text, true, timeout);
// Encrypt the ticket
string encrptedTicked = FormsAuthentication.Encrypt(ticket);
// create the cookie for the ticket, and put the ticket inside
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrptedTicked);
// give cookie and ticket same expiration
cookie.Expires = ticket.Expiration;
// Attach cookie to current response. it will now to the client and then back to the webserver with every request
HttpContext.Current.Response.Cookies.Set(cookie);
// send the user to the originally requested page.
string requestedPage = FormsAuthentication.GetRedirectUrl(txtUserName.Text, false);
Response.Redirect(requestedPage, true);
}
else
{
// login without saving cookie to client
FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, false);
}
You can use token based authentication in webapi using Angular JS. Visit following link
http://www.dotnetcurry.com/aspnet/1223/secure-aspnet-web-api-using-tokens-owin-angularjs

Asp.net persistent login cookie expires randomly

I'm trying to implement a login form with the remember me functionality in ASP.NET 4.0.
I've set the timeout option in the web.config to 1 year (525600), but after a random amount of time after I logon, I always get logged off.
The cookie is created correctly, I can see it in the browser with the right expire value (september 2014), but it seems that this cookie after some time is not readed by the ASP.NET environment anymore.
I tryed to login with:
FormsAuthentication.RedirectFromLoginPage(username, true);
or:
FormsAuthentication.SetAuthCookie(username, true);
Response.Redirect("/");
or with this custom code:
DateTime expiryDate = DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2, userid, DateTime.Now, expiryDate, true, String.Empty);
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie authenticationCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
authenticationCookie.Expires = ticket.Expiration;
Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
Response.Cookies.Add(authenticationCookie);
Response.Redirect(FormsAuthentication.GetRedirectUrl(username, false));
But the result is always the same. The cookie is present, but after some time it's not used anymore.
The Web.config is like so:
<authentication mode="Forms">
<forms loginUrl="/login" defaultUrl="/" name="appName" path="/" timeout="525600" slidingExpiration="true"/>
</authentication>
The odd thing is that in my local test environment (ASP.NET Development server) things works correctly. Only in the production environment it is not working!
#Felipe Garcia: I don't know if I'm using a load balancer, I'm on a public server. But I tryed to config the MachineKey as you said (using the generator here) and now it seems to work correctly!
Thank you!

How to configure ASP.Net website to have access to Active Directory

I am trying to create a intranet website which can look up a users email address based on their Active Directory username.
I have the following in my web.config:
<authentication mode="Windows"/>
<identity impersonate="true"/>
And I can obtain the the users UserName with:
Environment.UserName
Running on localhost, the following code allows me to query the AD and obtain the email:
public string GetADUser(string userName)
{
DirectoryEntry entry = new DirectoryEntry();
// get a DirectorySearcher object
DirectorySearcher search = new DirectorySearcher(entry);
// specify the search filter
search.Filter = "(&(objectClass=user)(anr=" + userName + "))";
// specify which property values to return in the search
search.PropertiesToLoad.Add("mail"); // smtp mail address
// perform the search
SearchResult result = search.FindOne();
string email = string.Empty;
if (result != null)
{
if (result.Properties["mail"].Count == 1)
{
email = result.Properties["mail"][0].ToString();
}
else
{
email = "no email";
}
}
else
{
email = "not found";
}
return email;
}
Great, this code authenticates using my credentials by default and allows me to pass in a username and look up the users email address.
However, when I upload this test code to the server, the code stops working if I browse to the site from anywhere other than localhost.
[COMException (0x80072020): An operations error occurred.]
Googling this reveals that I have a permissions issue.
To get around this I have tried setting the application pool identity to my credentials but this still does not allow the code to search the AD.
The website authentication is configured in IIS as follows (enabled items tagged with <<):
Anonymous Authentication:Disabled
ASP.NET Impersonation:Enabled <<
Basic Authentication:Disabled
Digest Authentication:Disabled
Forms Authentication:Disabled
Windows Authentication:Enabled <<
Is it even possible to do what I am trying to do?
What am I missing?
OK I found the problem.
In this case, having ASP.NET Impersonation:Enabled in IIS and my Web.Config was conflicting with the Application Pool identity I had configured. (I think).
Once I set the application pool identity to run using an appropriate account authenticated to query the AD, disabled Impersonation and left Windows Authentication:Enabled I was able to get the website to query the AD without passing any credentials in my code.

Categories