Create cookie before authentication in MVC application - c#

I have a scenario in which I need to create a cookie before user is authenticated by my MVC application. Now, here, login is done using external application. (which lies on different server). For this, I did below code in my local environment. I am overriding built-in Authorize attribute and use my custom attribute.
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
HttpCookie _testCookie = new HttpCookie("myCookie");
_redirectCookie.Value = "someValue";
HttpContext.Current.Response.Cookies.Add(_testCookie);
base.HandleUnauthorizedRequest(filterContext);
}
Above code works if I have local url in tag in my web.config. Can somebody please tell me if the same will work with external login url or not?
Thanks in advance,
Suhani.

Well.. solved it.. I just had to use the same domain name while creating this cookie so that the consuming site can see the cookie created by the original site. Deployed the same code (adding domain name while creating a cookie) and it worked.
thank you anyways!

Related

Issue in accessing one site from another site through limited access URL

I have two websites, both in separate domains. So for e.g. http://example1.com and http://example2.com. Both sites are in ASP .NET and use Forms authentication. Users of example1.com need to access certain resources of example2.com without needing to have accounts in example2.com. So whenever a user of example1.com needs to access a resource in example2.com, a temporary URL is generated through which the user can access the resource. The URL is a limited period one time use URL that is invalidated after first time use. Here is how it works.
When example1.com needs to access resource on example2.com side, a response.redirect occurs with an encrypted token in the query string. e.g. http://example2.com/path/resource1/?token=encryptedToken
This token is read on example2.com side and if it is valid, forms authentication is set to "temp user". "Temp User" is a limited access user created specifically as a proxy for example.com users.
Below is the code to achieve this in Application_AuthenticateRequest event
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
const string TempUser = "TempUser";
if (!Request.IsAuthenticated)
{
var url = Request.Url;
var token = Request.QueryString["token"];
if(IsKnownUrl(url) && IsValidToken(token))
{
FormsAuthentication.SetAuthCookie(TempUser, false);
Response.Redirect(Request.RawUrl);
}
}
}
private bool IsKnownUrl(string url){
//Logic to check the url is from known sources
}
private bool IsValidToken(string token){
//Logic to token is valid and not expired
}
This was working fine until both sites were switched to SSL. i.e. https://example1.com and https://example2.com. and this stopped working. The Response.Redirect from example1.com to example2.com goes into a 302 loop, which means for some reason the authentication cookie is not being set or accepted. When I view the network activity in Chrome Browser Developer tools, I see following trail
Name Status
https://example2.com/path/resource1/?token=encryptedToken 302
https://example2.com/path/resource1/?token=encryptedToken 302
https://example2.com/path/resource1/?token=encryptedToken 302
..................
Finally the Browser gives up and indicates the page is redirecting too many times.
Any ideas on what could be wrong?
Thanks Aydin for your tip. For anyone who is also facing similar issue, here is the solution.
After checking with Fiddler, I found that Authentication cookies (.ASPXAUTH) were being sent from the server but the browser was not sending them on subsequent requests.
Also, the URLs from example2.com were being displayed in example1.com inside an IFrame. After some searching I found that for IFrames, the browser will send cookies only if "SameSite=None" is specified in the Set-Cookie response header.
So in the end I had to update my code to create the ASPXAUTH cookie manually since the cookie created by FormsAuthentication class sets its to "Lax".

Custom Authentication along with Integrated Windows Authentication

I am using Integrated Windows Authentication in my application so domain users alone can access the application.
After this step, I am doing some additional authentication to check whether that domain user is permitted to access the application (domain user will be added in a database table).
To achieve this, I am doing in the following way. Is this the best practice?? Please advise.
public class CCUKAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var isAuthorized = base.AuthorizeCore(httpContext);
var isUserAddedinDB = true; //Code to check whether user is added in DB
return isUserAddedinDB;
}
}
What you are trying to do is first check authentication and then check for an authorization rule(can he access application). I guess this is a onetime check which happens only during the first time authentication process. In that case you better separate that logic into a different method (Separation of Concerns).
Generally in a MVC application if you need to do a custom Authorization check, I would recommend to do Authorization check by overriding "Authorize" attribute (example).

Forms Authentication with JASIG CAS Custom operation after logon

It's my First question here so i apologize for my english :)
we are building MVC 4 application with authentication made by Jasig CAS SSO.
It works pretty good but i need to do custom action after authentication of user.
Steps should look like:
User goes to our site to HomeController which is decorated by AuthorizeAttribute
Controller redirects user to CAS
User pass his username and password
CAS properly authenticates user and redirects to our site
(here goes custom action) After logon we build up Session (get user parameters from DB and put them in to chache and etc)
action 5. is run only once after successful logon! every next request skips this step.
I have read documentation of CAS and MSDN about forms authentication but i couldn't any information.
I found that i could extend AuthorizeAttribute and override AuthorizeCore method but it is ran every request.
thanks for help
I found answer by myself. Maybe there are better resolutions but this one makes what i wanted.
To make some custom action after logon in Jasig CAS you need to implement
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
in Global.asax
sample code:
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
//must check if user is authenticated (this method can be called before authentication)
if (Context.User.Identity.IsAuthenticated && Context.Session != null && Context.Session["IsLogged"] == null)
{
Context.Session.Add("YourKey", YourData);
Context.Session.Add("IsLogged", true);
}
}
Probably the same approach could be used in standard forms authentication if needed

Page.User.Identity.Name is blank on pages of subdomains

I have multiple subdomains trying to use a single subdomain for authentiction using forms authentication all running on windows server 2008 r2.
All of the forms authentication pages are setup to use the same name, and on the authentication page the cookie is added with the following snippet:
FormsAuthentication.SetAuthCookie(txtUserName.Text, false);
System.Web.HttpCookie MyCookie = System.Web.Security.FormsAuthentication.GetAuthCookie(User.Identity.Name.ToString(), false);
MyCookie.Domain = ConfigurationManager.AppSettings["domainName"];
Response.AppendCookie(MyCookie);
When I am logged in to signon.mysite.com the page.user.identity.isauthenticated and page.user.identity.name properties both work fine. When I navigate to subdomain.mysite.com the page.user.identity.isauthenticated returns true, bue the name is empty.
I tried to retrieve it from the cookie using the following, but it also was blank.
HttpCookie cookie = Request.Cookies[".ASPXAUTH"];
FormsAuthenticationTicket fat = FormsAuthentication.Decrypt(cookie.Value);
user2_lbl.Text = fat.Name;
When googling the issue I found some people saying something must be added to global.asax and other saying it wasn't necessary.
The goal is to be able to login on the authentication subdomain and have the user identity accessible from the root site and other subdomains. Machine keys match in all web.config, and the AppSettings["domainName"] is set to "mysite.com" currently.
Does anyone know what is preventing me from accessing the user information?
Change "mysite.com" to be ".mysite.com" (note the leading ".").
That'll tell the browser that the cookie is valid for subdomains as well.

FormsAuthentication Membership.GetUser() Null

I am using Forms Authentication and have the basic logon page and default page.
When I am on the logon page, and call the SignOn this works just great. However, when I am still on the Logon page the Membership.GetUser() returns null. When I redirect to my default page, the Membership.GetUser() returns my user information.
Is there any way I get get this method to return my user while still on the logon page. I have read all over google that other have similar issues where it will only work once you redirect.
Let me know if you need further information.
Here is a simple code snippet of what I am using to verify that the information is being set:
bool authenticated = User.Identity.IsAuthenticated;
string username = User.Identity.Name;
MembershipUser user = Membership.GetUser();
I put this code on both the logon page and the default page in the code behind and only the default page has values and shows that it is authenticated after the authentication process executes.
Something else to try is the following code:
MembershipUser user = Membership.GetUser(username);
GenericIdentity identity = new GenericIdentity(user.UserName);
RolePrincipal principal = new RolePrincipal(identity);
System.Threading.Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
This might be because you allow anonymous users on your login page. Therefore the browser doesn't bother sending any more information to this page than is necessary.
I was in this same situation, here is what worked for me on MVC 4 .NET 4.5.
Membership.GetUser(HttpContext.Current.User.Identity.Name)
I had a similar issue and the problem turned out to be that I was missing authentication method = form in the web config .
<system.web>
<authentication mode="Forms"/>
....
Don't forget that one (I was migrating an old legacy site to aspnet)
I had this issue and found it was due to having multiple membership providers, so instead of
Membership.GetUser()
you can try
Membership.Providers["MyMembershipProvider"].GetUser()
or more specifically
Membership.Providers["MyMembershipProvider"].GetUser(LoginCtrl.UserName, false)
I had a similar problem (it was all pages on the site) and it was caused by an error in the AspNetSqlMembershipProvider connection string, which SHOULD have been different in different environments but wasn't, so it worked locally but not when deployed to the server.

Categories