View elmah logs without creating role/user authentication - asp.net-mvc

I started using ELMAH and I think its great. I read some documentation online but right now my app doesn't have roles/user authorization setup.
I would like to be able to read the error logs on production by accessing /elmah.axd but I don't want to just open it up to everyone, does elmah have any functionality that would allow me to create a password (in web.config) and pass it via querystring? Mimicking a "secure" RSS feed. Or something similar ofcourse....

but right now my app doesn't have roles/user authorization setup
Actually it's not that hard to configure forms authentication:
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880">
<credentials passwordFormat="Clear">
<user name="admin" password="secret" />
</credentials>
</forms>
</authentication>
and then protect elmah.axd:
<location path="elmah.axd">
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</location>
and finally you could have an AccountController:
public class AccountController : Controller
{
public ActionResult LogOn()
{
return View();
}
[HttpPost]
public ActionResult LogOn(string username, string password)
{
if (FormsAuthentication.Authenticate(username, password))
{
FormsAuthentication.SetAuthCookie(username, false);
return Redirect("~/elmah.axd");
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
return View();
}
}
and a LogOn.cshtml view:
#Html.ValidationSummary(false)
#using (Html.BeginForm())
{
<div>
#Html.Label("username")
#Html.TextBox("username")
</div>
<div>
#Html.Label("password")
#Html.Password("password")
</div>
<p>
<input type="submit" value="Log On" />
</p>
}
Now when an anonymous user tries to access /elmah.axd he will be presented with the logon screen where he needs to authenticate in order to access it. The username/password combination is in web.config. I have used passwordFormat="Clear" in this example but you could also SHA1 or MD5 the password.
Of course if you don't want to configure authentication you could also configure elmah to store logging information in a XML file or SQL database and then completely disable the elmah.axd handler from your publicly facing website. Then create another ASP.NET site which only you would have access to with the same elmah configuration pointing to the same log source and simply navigate to the /elmah.axd handler of your private site to read the logs of your public site.

Related

AllowAnonymous Attribute not working MVC 5

Inside the Azure Portal I set App Service Authentication "On" For my Web App and I use AAD as Authentication Provider.
This has worked great up until now, I need an endpoint that will allow anonymous users, however the attribute [AllowAnonymous] does not work, I am still required to sign in.
Code:
[Authorize]
[RoutePrefix("users")]
public class UsersController : Controller
{
[Route("register/{skypeid}")]
public ActionResult Register(string skypeid)
{
///stuff...
}
catch (Exception ex)
{
return Content(ex + "");
}
ViewBag.Name = name;
return View();
}
[AllowAnonymous]
[Route("exists/{skypeid}")]
public ActionResult Exists(string skypeid)
{
return Content("Hello " + skypeid);
}
I think the code is right, so does it have something to do with the fact that I use App Service Authentication for my Web App?
EDIT:
So, I found the source of the problem, In Azure if you set "Action to take when not Authenticated" to "Sign in with Azure Active Directory", it does never allow anonymous.
However, If I change it to allow anonymous then users are not prompted to sign in when trying to access a control with the [Authorize]-Attribute, it just tells me "You do not have permission to view this directory or page."
Is this intended? It seems really weird. I want users to be redirected to Login if there is an [Authorize]-Attribute.
Screenshots for clarity:
Check your web.config if you have
<authorization>
<deny users="?" />
</authorization>
its override [AllowAnonymous]
add
<location path="YourController/AnonymousMethod">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
to allow anonymous access
I've just written about this in my book - http://aka.ms/zumobook - look in Chapter 6 for the MVC section.
The basic gist of it is that you need to do a little more to enable authentication; most specifically, you need to set up an auth pipeline (Azure Mobile Apps Server SDK will do this for you) and you need to set up a forms redirect within Web.config:
<system.web>
<compilation debug="true" targetFramework="4.5.2"/>
<httpRuntime targetFramework="4.5.2"/>
<authentication mode="Forms">
<forms loginUrl="/.auth/login/aad" timeout="2880"/>
</authentication>
</system.web>
Since there are several details to adding the Mobile Apps SDK to your ASP.NET application, I'd refer to the referenced chapter for those details.

ASP.NET MVC Login Not Sticking

I'm having an issue with my ASP.NET MVC 5 simple membership provider login code. The code is as follows:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel model, string returnUrl)
{
bool active = true;
if (ModelState.IsValid && WebSecurity.Login(model.Email, model.Password, persistCookie: model.RememberMe))
{
UserDetail userModel = UserDetail.Initialize(model.Email);
FormsAuthentication.SetAuthCookie(model.Email, true);
active = userModel.ActiveBit;
if (active)
{
return Redirect("~/");
}
else
{
WebSecurity.Logout();
ModelState.AddModelError("", "Account is inactive.");
}
}
else
{
ModelState.AddModelError("", "*Either the Username or Password provided is incorrect.");
}
return View(model);
}
The login processes successfully and I can see the authentication cookie (.ASPXAUTH) in the browser. The problem arises on the next page request. The authentication cookie is passed back to the server, but the server seems to have no record of the login any more. When I set a breakpoint and check after processing the login and requesting a new page (after completing the post-login redirect), User.Identity.IsAuthenticated is false as is WebSecurity.IsAuthenticated and WebSecurity.HasUserID. WebSecurity.CurrentUserId is -1 and WebSecurity.CurrentUserName is an empty string.
It's not a database connectivity issue since I do authenticate successfully. I do a roundtrip to the server and back and I am still not authenticated so the common answers I've seen for CurrentUser == -1 don't seem to apply.
I'm a relative newbie on MVC but I had a coworker who's got a decent amount experience on this look at my code and he couldn't find anything either. Thanks for your help.
By default asp.net MVC5 web.config not supporting FormsAuthentication, check below section of your web config file and remove "<remove name="FormsAuthentication" />" if you want to use FormsAuthentication.
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
</system.webServer>
Authentication timeout configuration
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
</system.web>
Hope this helps.

MVC5 Forms authentication not working

I'm very new to .NET and security. I've chosen to implement Forms authentication (correct me if I should use something else). From what I gathered on the internet, I did the following, but it's not working:
Web.config
<authentication mode="Forms">
<forms loginUrl="~/Home/Index" timeout="30" />
</authentication>
HTTPPost ajax Login method:
[HttpPost]
public ActionResult Login(LoginInputModel loginModel)
{
if (ModelState.IsValid)
{
var success = UserService.Login(loginModel.Password, loginModel.Email);
if (success)
{
return Json(new { Url = Url.Action("Index","Home") });
}
loginModel.ErrorMessages = "Failed to log in with these credentials. Please try again.";
return PartialView("Widgets/Login/_LoginInput", loginModel);
}
return PartialView("Widgets/Login/_LoginInput", loginModel);
}
With actual login code in UserService class:
public static bool Login(string password, string email)
{
var user = Connector.GetUserByCredentials(password, email);
if (user == null) return false;
FormsAuthentication.SetAuthCookie(email, false); // this line
SessionService.Delete(UserSessionKey);
SessionService.Store(UserSessionKey, UserMapper.DbUserToUser(user));
return SessionService.HasKey(UserSessionKey);
}
Whenever I hit login, it works okay (it refreshes the page and I see different content), but if I then navigate to another page, I get redirected to the login page again. What am I (not) doing wrong?
If you need more code, I'll be happy to post it.
When you say you're using MVC5, what version of Visual Studio are you using? Are you using an application that was originally created by a default wizard?
If the application was created by the default wizard, then by default it enables ASP.NET Identity, and it removes the FormsAuthentication module from processing. If you want to keep using FormsAuth then you have to remove the "remove" key from the web.config for the FormsAuthentication module.
You need to remove this line
<system.webServer>
<modules>
<remove name="FormsAuthentication" /> <----****
</modules>
</system.webServer>

MVC: Redirecting to login screen

I am taking over an existing ASP.NET MVC 5 project in order to try to understand the MVC framework. I have noticed that when a user is not logged in, and he attempts to go to some of the webpages, then it automatically redirects him to the login screen. I believe that this has something to do with the following in the Web.config file:
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
However, some webpages allow access to them (and are not redirected as above) even when the user is not logged in.
So my question is: Where do I configure which web pages will be automatically redirected to the login screen, and which web pages can be accessed without authentication?
This article explains how to do this with forms authentication. A short snippet of the configuration looks like below. Where default1.aspx is given access to.
<configuration>
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
<!-- This section denies access to all files in this application except for those that you have not explicitly specified by using another setting. -->
<authorization>
<deny users="?" />
</authorization>
</system.web>
<!-- This section gives the unauthenticated user access to the Default1.aspx page only. It is located in the same folder as this configuration file. -->
<location path="default1.aspx">
<system.web>
<authorization>
<allow users ="*" />
</authorization>
</system.web>
</location>
</configuration>
You can set an [Authorize] attribute on the controller action that will require the user to be authorized, otherwise they will be redirected to the page specified in the config. You can also specify individual roles that are required to access an action or require authorization for all actions on a controller and explicitly turn off authorization for actions.
Authorize Individual Actions
public class HomeController: Controller
{
public string Index()
{
// Not authorized
}
[Authorize]
public string SecretAction()
{
// Authorized (redirects to login)
}
}
Authorize All Actions
[Authorize]
public class HomeController: Controller
{
public string Index()
{
// Authorized (redirects to login)
}
public string SecretAction()
{
// Authorized (redirects to login)
}
}
Authorize All Actions Except For One
[Authorize]
public class HomeController: Controller
{
public string Index()
{
// Authorized (redirects to login)
}
[AllowAnonymous]
public string PublicAction()
{
// Not authorized
}
}
More here: http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx
And here: Authorize attribute in ASP.NET MVC
An easy workaround if you are doing something simple (like a page or two of public content) is just this:
Response.SuppressFormsAuthenticationRedirect = true;

ASP.NET MVC - Authenticate users against Active Directory, but require username and password to be inputted

I'm developing a MVC3 application that will require a user to be authenticated against an AD. I know that there is the option in MVC3 to create an Intranet Application that automatically authenticates a user against an AD, but it uses Windows Authentication and automatically logs them on. This application may be accessed on 'Open' workstations where the user will need to enter their Domain Username and Password. Any examples or online tutorial would be great. An example project would be exceptional.
You can use the standard Internet application template with forms authentication and insert an ActiveDirectoryMembershipProvider into the web.config:
<connectionStrings>
<add name="ADConnectionString" connectionString="LDAP://YOUR_AD_CONN_STRING" />
</connectionStrings>
<system.web>
<authentication mode="Forms">
<forms name=".ADAuthCookie" loginUrl="~/Account/LogOn"
timeout="15" slidingExpiration="false" protection="All" />
</authentication>
<membership defaultProvider="MY_ADMembershipProvider">
<providers>
<clear />
<add name="MY_ADMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider"
connectionStringName="ADConnectionString"
attributeMapUsername="sAMAccountName" />
</providers>
</membership>
</system.web>
In this way you get the Internet application template login form, and it validates against AD for you.
Then it's just a matter of some AccountController cleanup to remove reset password/change password/register functionality leaving just Login.
As mentioned above, you can use the membership provider defined in the web.config file.
The code below is within the implementation of the 'AccountController' from the MVC 3 Template code and has been slightly modified to work with ActiveDirectory:
[HttpPost]
public ActionResult LogOn( LogOnModel model, string returnUrl )
{
if( ModelState.IsValid )
{
// Note: ValidateUser() performs the auth check against ActiveDirectory
// but make sure to not include the Domain Name in the User Name
// and make sure you don't have the option set to use Email Usernames.
if( MembershipService.ValidateUser( model.UserName, model.Password ) )
{
// Replace next line with logic to create FormsAuthenticationTicket
// to encrypt and return in an Http Auth Cookie or Session Cookie
// depending on the 'Remember Me' option.
//FormsService.SignIn( model.UserName, model.RememberMe );
// Fix this to also check for other combinations/possibilities
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
If using .NET 3.5 -- then read this article for the alternative:

Resources