AuthorizeAttribute, anyway of checking in advance if this will pass - asp.net

I have controller actions which have AuthorizeAttribute on them
Often someone will try an old url which will take them (forms authentication) to the logon page and then redirect to the url, but it may be for whatever reason that they are no longer allowed to access to that page
Is there any way of testing the url before redirecting?
I can decompose the url into the area/controller/action and test it but it feels clumsy to do that
(Extra info)
Our site is part of a product family, in the desktop app we can determine who has access to what parts. e.g. we may have a clocking page, a user accesses it and keeps the url. In the main product we remove their access to this page, the authorizeattribute now says they don't have access to it.
So we get
they try to access the url
forms authentication says they don't have access and reroutes to the logon page
they logon, however they still don't have access to this page and they are redirected again to the logon page.

With form authentication, please make sure you have set authentication cookie on logon page after validating user:
FormsAuthentication.SetAuthCookie(userId, rememberMe);
This will authenticate user in order to prevent from redirecting to Logon page again.
You can also check to see whether the user has been authenticated by:
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
var loggedOnUserId = HttpContext.Current.User.Identity.Name;
}

Related

How to set Azure Authentication custom login return url?

I followed this article https://azure.microsoft.com/en-us/blog/announcing-app-service-authentication-authorization/ to set up Azure authentication for my MVC app. First I turned on Azure AD provider. In the Authentication / Authorization settings, I selected "Allow request(no Action)" for "Action to take when request is not authenticated" because I only need users to login for certain controller actions.
Then I added a custom FilterAttribute to check if one action needs authentication as in https://stackoverflow.com/a/26652816/1837339. In the OnAuthenticationChallenge function, I had this code to redirect to login page:
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
if (filterContext.Result is HttpUnauthorizedResult) {
filterContext.Result = new RedirectResult("~/.auth/login/aad");
}
}
All of this works, except after user finished authentication, it is redirected back to mysite/.auth/login/done page saying "You have successfully signed in" and a button to return to my site's base url.
What I want is the redirection goes back to the user's original url, so I think I need somehow set the return url for the login redirect. But I couldn't find any documentation about this. Anyone could give any advice?
You can use the post_login_redirect_url query string parameter to do this.
For example, if you want to automatically navigate the user to /welcome.html after logging in, you can set your login redirect to ~/.auth/login/aad?post_login_redirect_url=/welcome.html, and the user will be redirected to this page instead of the generic welcome page.
Thank you.
This really helped.
The below worked ok for me:
return RedirectToAction(string.Format("login/{0}?post_login_redirect_url=/Home/LoginCallBack", provider), ".auth");
provider can be one the strings: google, twitter, microsoftaccount,aad,facebook.
Also each provider must be configured on your project at the Azure Portal.
redirect url may be any uri on your project

Caching anonymous page with redirect if user is authenticated

I would like to use page caching for our asp.net mvc site's landing page. This page is accessible to anonymous users only. If the user is logged in however, I would like this page to redirect to the user home page which is authenticated.
The problem is that if I cache the landing page, a logged in user can still access this page because it is cached on their browser.
Obviously a meta refresh header if the user is authenticated will also not work because the page will cache without the header in the first place.
Is there any way to cache the landing page but also redirect if the user is logged in, without using query params, or is conditional GET the only way to do this?
You could use the OutputCacheAttribute, with the VaryByCustom parameter.
If you set it to something like "IsAuthenticated" and then define the GetVaryByCustomString method in your Global.asax file, and return a string of "True" or "False" depending on if the user is authenticated or not perhaps.
In fact, the following Blog Post answers your exact question: Read This

How to sign-in to WIF federation on the same page?

I have this scenario.
RP with passive federation to 2.
Custom STS for user/password authentication
Everything is working fine. So far the user would press login link, which would go to a restricted area, thus the federation security was triggered, and login screen appeared. It would prompt him to write the credentials, the request was then processed, etc.
Now I'm required to create login (user/password) text-boxes on the same page (default page). How can I achieve federation sign-in operation without redirecting to a login page? Should (or can) I use FederatedPassiveSignIn control? If so, how?
You could show the login boxes on the unprotected landing page if IsAutheticated is false and then send a message to the custom STS login page with the credentials encrypted or whatever which then logs in behind the scenes and redirects back to your app. with the token in the normal manner.
However, if the user is not authenticated and bookmarks a page behind the landing page, they'll be redirected to the STS.
For anyone interested (I doubt someone actually is), I've solved it through - basically - simulating what login page does.
// makes credentials validation, and creates IClaimsPrincipal with the acquired claims
IClaimsPrincipal principal = LoginHelper.SignIn(editEmail.Value, editPassword.Value);
// retrieves the instance of the STS (in this case my custom STS)
TrustedSecurityTokenService service = (TrustedSecurityTokenService) TrustedSecurityTokenServiceConfiguration.Current.CreateSecurityTokenService();
// creates the request manually to point to my original page (or whatever page you desire)
SignInRequestMessage request = FederatedAuthentication.WSFederationAuthenticationModule.CreateSignInRequest(Guid.NewGuid().ToString(), "http://page/i/want/to/go/after/the/validation.aspx", true);
// processes first the request...
SignInResponseMessage response = FederatedPassiveSecurityTokenServiceOperations.ProcessSignInRequest(request, principal, service);
// ...then the response is processed, and redirected to URL above
FederatedPassiveSecurityTokenServiceOperations.ProcessSignInResponse(response, Response);
This created cookies, and principal is not IsAuthenticated. As if it were process by login page (at least it seems to work so far as expected).

ASP.NET Cookieless Forms Auth not setting cookie when Login page is bookmarked

Our ASP.NET 4.0 application's forms authentication is set to cookieless="AutoDetect." I've noticed that if a user bookmarks our login page, the bookmark link is set to https://hostname.com/Login.aspx?AspxAutoDetectCookieSupport=1. If a user navigates to this directly from a new browser session and performs a valid login, the cookie is not set. If I navigate directly to that page, bu remove AspxAutoDetectCookieSupport from the query string, the cookie is created correctly.
If a user navigates directly to Default.aspx or the root directory, login functions correctly, even with AspxAutoDetectCookieSupport=1 tacked on to the query string.
When the user clicks the login button, we do a postback to the login page and manually check the users credentials against our database. If successful, we do:
FormsAuthentication.RedirectFromLoginPage(userName, false);
I've spent many hours debugging this, including looking at the ASP.NET forms authentication code in the reference source, and haven't been able to determine what is causing this. The only solution we have at the moment is telling users to remove the Login page from their bookmark URL and adding a bookmark button on our Login page for users to click.
Is there another solution to fix this forms authentication issue? Is it a but in forms authentication?
The problem here is that you are always using the RedirectFromLoginPage, whether or not the redirect location is provided. If it is not provided, then the redirect will fail. A proper solution to this would be to check the redirect url and redirect to the default.aspx if it is not available (source example borrowed from this blog article):
// Once the user's entered credentials are verified //
if(Request.Params["ReturnUrl"] != null)
{
FormsAuthentication.RedirectFromLoginPage(txtUserName.text, false);
}
else
{
FormsAuthentication.SetAuthcookie(txtUserName.text, false);
Response.Redirect("Default.aspx");
}

ASP.NET: directing user to login page, after login send user back to page requested originally?

I am trying to manually implement a login system in ASP.NET 3.5. Basically, on load, I would like the site to check and see if user object is active, if not, than I want the login page to appear.
After user has logged in successfully, I would like the user to be able to access the same page he has requested originally.
for example:
user request to: MyPage.aspx - not logged in
login page appears instead of MyPage.aspx
user logs in successfully
MyPage.aspx appears instead of Default.aspx for example
Peering at the System.Net namespace, I see that there is an "HttpWebRequest Class" which has a "HttpWebRequest.AllowAutoRedirect Property" but am unsure how that would get me back from the login page.
NOTE: I know there are automatic authentication systems setup in ASP.NET, but I would like to have manual control over the database.
-- Tomek
What you could do, if you don't want to actually use the built in Forms Authentcation is:
Check if the user is authenticated on each page you want to hide from anonymous users. If they are not authenticated, redirect them to your login page with the URL in the query string.
if(!HttpContext.Current.User.Identity.IsAuthenticated) {
Response.Redirect(~/login.aspx?redirect=this_page.aspx");
}
Then on your login page, after a user logs in. Check the query string to see if there is a redirect parameter.
if(!String.IsNullorEmpty(Request.QueryString["redirect"]) {
string url = ResolveClientURL(redirect);
Response.Redirect(url);
}
Of course this is all built into .NET using Authentication, where you can deny anonymous access to certain directories, and when you do that, .NET will redirect to your login page (which is set in the web.config) and will include a "ReturnURL=blahblah" on your login page.
Just an FYI.
Just save the originally requested url in Session or a hidden field on the login page
After successful login, use Server.Transfer or Response.Redirect to jump to that page.
It looks like another method is described here. It seems that you can use the following object to return from the login page:
FormsAuthentication.RedirectFromLoginPage
Yet, according to the article, the better method is to use what JackM described, but with an overload:
Response.Redirect("~/default.aspx", false);
In doing so, you prevent the Session from ending when the page is redirected.

Resources