AllowAnonymous Attribute not working MVC 5 - asp.net-mvc

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.

Related

How can I redirect unauthorized users to a login page

I'm using MVC5 and AD authorization. I want to redirect to a login page if there is no authorization. So I added some setting in web.config as below.
<authentication mode="Forms">
<forms loginUrl="~/Account/Login.aspx" timeout="2880"/>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
But after it. When I start to debug. the homepage's URL is like below.
What's wrong with it? it seems returnUrl is the problem. any suggestions to fix it?
http://localhost:62435/Account/Login?ReturnUrl=%2FAccount%2FLogin%3FReturnUrl%3D%252FAccount%252FLogin%253FReturnUrl%253D%25252FAccount%25252FLogin%25253FReturnUrl%25253D%2525252FAccount%2525252FLogin%2525253FReturnUrl%2525253D%252525252FAccount%252525252FLogin%252525253FReturnUrl%252525253D%25252525252FAccount%25252525252FLogin%...................
2019/08/05
I've solved my problem by setting the steps below.
change the web.config's setting.
From
<authentication mode="Forms">
<forms loginUrl="~/Account/Login.aspx" timeout="2880"/>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
To
<authentication mode="None" />
add code as below.
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
// I've add code here
filters.Add(new AuthorizeAttribute());
}
}
By the way, I'm using UseCookieAuthentication.
I don't understand FormsAuthentication. and the difference between CookieAuthentication and FormsAuthentication.
It looks like your Login action on the Account controller is secured, maybe with the Authorize attribute. Unauthenticated users need to be able to access Login so use the AllowAnonymous attribute with it.
[AllowAnonymous]
public ActionResult Login()
...
Also, you said you're using MVC but your web.config Forms Authentication refers to login.aspx. Based on this - I think it just needs to be ~/Account/Login

MVC 4 Windows Authentication

I'm relatively new to MVC, I need to retrieve username and pass it to my company library that checks for user credential.
Web.config
<authentication mode="Windows" />
<authorization>
<allow users="*"/>
<deny users="?"/>
</authorization>
Controller
[Authorize]
public class MVCAuthen : Controller
{
public string GetCredentials()
{
var userName = HttpContext.Current.User.Identity.Name;
string credential = library.Getcredential(userName);
return credential;
}
}
My question is I keep getting blank when I try to retrieve username. Can someone tell me what I'm doing wrong or how I retrieve username?
Note: I'am trying to do this locally since I'm trying to debug it.
First you should be using a Internet Application or Intranet Application template.
Then on the web.config you should comment or remove the forms authentication and use the windows authentication. Something like this:
<--
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
-->
<authentication mode="Windows" />
And add this in the 'appSettings'
<appSettings>
<add key="autoFormsAuthentication" value="false" />
<add key="enableSimpleMembership" value="false"/>
</appSettings>
Now go to you solution explorer, right click the project and go to properties. There you must change Windows Authentication to enabled.
If you do not want to allow any anonymous access you may disable Anonymous Authentication too.
Once that is done you can add the [Authorize] on any Controller or Action.
Then you should be able to login with your windows password.
If you are able to login and view the page then you can retrieve the user name like this.
var username = HttpContext.User.Identity.Name;

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;

using windows authentication with active directory groups as roles

I've read several questions on this topic,
such as here, here, here and here;
but none have provided a working solution in my case.
What I want to do:
Implement Windows authentication for a web app that is only used by our own employees. This way they should not need to log into the app, but already be authenticated by way of having logged into windows.
Also, I need to restrict certain areas of the app, based on Active Directory Security Groups that the user may be assigned to.
So I want to be able to decorate Controllers / Actions with
[Authorize(Roles="SomeRole")]
What I've tried:
I have
<authentication mode="Windows" />
in my web.config. And I have added several permutations of a <roleManager> as found in some of the posts linked to above. Currently I have this role manager
<roleManager defaultProvider="WindowsProvider"
enabled="true"
cacheRolesInCookie="false">
<providers>
<add
name="WindowsProvider"
type="System.Web.Security.WindowsTokenRoleProvider" />
</providers>
</roleManager>
as found in this post.
As it is, if I decorate a controller with [Authorize], I can access it fine.
However:
I can see in my user settings on the network, that I am part of a AD security group called "IT". But if I decorate the same controller with [Authorize(Roles="IT")] I get the blank screen that is is served by the asp.net development server for a 401 not authorized. This is unexpected. I would think that I should be able to view the page as I am logged in to windows and am part of the group "IT".
Most everything I am finding on this topic make it sound very simple to accomplish what I'm trying to do, but I am clearly missing something here.
For dev I am using IISExpress
with development server properties of the MVC project set up so that
Anonymous Authentication is Disabled and Windows Authentication is Enabled.
The web config is deployed using our TFS build server to test and release servers for which authentication is also setup as above and works in those locations as well.
In my web.config I have.
<system.web>
....
<authentication mode="Windows" />
<authorization>
<deny users="?" />
</authorization>
<roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">
<providers>
<clear />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
....
</system.web>
I can use
[Authorize(Roles = #"DOMAIN\ADGroup")]
Public ActionResult Index()
{...}
or
public ActionResult Index()
{
var User = System.Web.HttpContext.Current.User;
if (User.IsInRole("DOMAIN\\ADGroup"))
{
return RedirectToAction("IRSAdmin");
}
return View();
}
After i remember to logoff and log back in so the permission i was given to the AD group were applied.

View elmah logs without creating role/user authentication

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.

Resources