How do I use windows authentication with roles with Hot Towel? - asp.net-mvc-4

I can spin up a standard asp.net mvc 4 intranet project and decorate the controller or methods with things like:
[System.Web.Mvc.Authorize(Roles = "MyApp Users")]
I have tested it and it will work perfectly (since my domain account is a member of the "MyApp Users" in Active Directory)
However my problem/question is how do I get the same type of behavior for a "Hot Towel" application? I try decorating my breeze controller, HotTowel Controller, or any method with the same attribute and I can never authenticate... what gives?
Your help is greatly appreciated.

Finally figured it out. I hope this is of use to others.
First you must set the WindowsProvider as your roleManager like so:
<roleManager defaultProvider="WindowsProvider"
enabled="true"
cacheRolesInCookie="false">
<providers>
<add
name="WindowsProvider"
type="System.Web.Security.WindowsTokenRoleProvider" />
</providers>
</roleManager>
Then you will be able to check the roles for the user [using Roles.IsUserInRole()], and more specifically to this question use the authorize attribute. The only thing is that you will have to include the domain in the authorize attribute, like so:
[System.Web.Mvc.Authorize(Roles = "YourDomain\\MyApp Users")]
And now everything works as you would expect.

Related

BetterCMS with MVC4 Simple membership provider

I've set up BetterCMS in my MVC4 app. and it seems like it's working except I can't figure out how to configure it to use Simple Membership Provider that comes with MVC4 internet app.
http://www.devbridge.com/articles/better-cms-for-developers
please help!. thanks
EDIT: I've created my MVC4 app using Internet Template which comes with Simple Membership Provider already configured and working. I would like to have those members I've "registered" as BetterCMS users.
If you want to use Better CMS, use BetterCms.Module.Users module from NuGet with it's role provider, membership provider and UI for managing users. How to setup users module, you can read in BetterCMS wiki pages on Github
But if you still wish to use Better CMS with Simple Membership Provider, follow steps below. That's what I've done and it works fine for me.
Create an MVC 4 solution and select Internet template
Run the application and create a user
Install BetterCMS by following steps, explained in Better CMS github wiki, section "Project Setup".
Do not forget to remove default routes registration (routes.MapRoute(name: "Default" ....) from RouteConfig class.
Register routes below in the RouteConfig class. After that MVC home page can be reached by URL /home/:
routes.MapRoute("mvc-account-controller", "account/{action}/{id}", new
{
area = string.Empty,
controller = "Account",
action = "Login",
id = UrlParameter.Optional
});
routes.MapRoute("mvc-home-controller", "home/{action}/{id}", new
{
area = string.Empty,
controller = "Home",
action = "Index",
id = UrlParameter.Optional
});
Add role provider and membership provider to web.config (solution found here):
<roleManager enabled="true" defaultProvider="simple">
<providers>
<clear/>
<add name="simple" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData"/>
</providers>
</roleManager>
<membership defaultProvider="simple">
<providers>
<clear/>
<add name="simple" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData"/>
</providers>
</membership>
Add LazyInitializer to global.asax as explained here
Remove [InitializeSimpleMembership] attribute from AccountController, because database connection is already initialized. Also, SMP2.Filters.InitializeSimpleMembershipAttribute class can also be deleted.
Create an admin role and assign it for user (it can be done using ASP.NET Configuration or directly in the database). For example, create role with name "Role1".
There are two ways to set up administrator roles for the user (you can read more in the Better CMS Github Wiki, topic "CMS configuration"):
Set your created role as full access role (cms.config, security section's fullAccessRoles attribute set to fullAccessRoles="Role1" )
Add roles mappings in the cms.config's security section:
<customRoles>
<add permission="BcmsEditContent" roles="Role1" />
<add permission="BcmsPublishContent" roles="Role1" />
<add permission="BcmsDeleteContent" roles="Role1" />
<add permission="BcmsAdministration" roles="Role1" />
</customRoles>
Run application. Go to url /account/login and log-in using admininstrator account, which was created in the 2nd step. Then go back to any CMS page, for example, root page (/).
Here you go, you're connected as administrator and CMS sidebar is availabe for web site editing.

Use Anonymous authentication in MVC4 on single controller when the whole application uses Windows Authenticaion

I have an MVC4 Web application which uses Windows Authentication, that is in web.config I have
<authentication mode="Windows" />
And that works fine and everything is ok.
However now I need a controller (an Web API controller in fact) that should be accessed anonymously from a third party component. The problem is that every time I want to invoke this method it requests user credentials.
I tried putting AllowAnonymous attribute to controller and methods but it was not successful.
[AllowAnonymous]
public bool Get(string Called, string Calling, string CallID, int direction)
I checked on both IIS Express and IIS 8 with Anonymous authentication and Windows authentication enabled.
It seems that windows authentication precedes any other authentication and cannot be overridden.
Is there a way to accomplish this?
Add this to your Web.config. Here, my controller is named "WebhookController".
<location path="Webhook">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
See this KB article for more info.
Edit
- As Erik mentioned below, in MVC applications you should not use web.config <authorization> tags for security. Instead, use [Authorize] attributes. Doing so will allow your [AllowAnonymous] attributes to work correctly. You can read more about this here.
The accepted answer seems to be out of date, so...
In your web.config, remove these lines:
<authorization>
<deny users="?" />
</authorization>
In the solution explorer, click your project, then click f4 (or open the properties explorer). Enable Anonymous Authentication.
Now you're free to use the Authorize and AllowAnonymous Attributes. They're pretty straightforward, Authorize means the user needs to be authorized in order to access the action or controller, AllowAnonymous means the opposite. If an unauthorized user attempts to access a controller or action with the Authorize attribute, they'll be redirected to a login page. If you put Authorize on a controller it applies to all the controller's actions, except ones with AllowAnonymous.
web.config should not be touched as indicated here.
In order to achieve desired result AllowAnonymous and [Authorize] (and maybe some custom authorization attribute, if needed) should be used.
Steps to be performed:
Ensure IIS has both Anonymous Authentication and Windows Authentication configured for the web application / web site
All controllers should use [Authorize] attribute. This can be easily achieved if all inherit from a common controller class (e.g. BaseController / BaseApiController). E.g.:
[Authorize]
public class BaseController : System.Web.Mvc.Controller
{
}
[Authorize]
public class BaseApiController : System.Web.Http.ApiController
{
}
Add [AllowAnonymous] attribute to all actions that are supposed to be anonymous. E.g.:
[RoutePrefix("Api/Anonymous")]
[Authorize]
public class AnonymousController : ApiController
{
[HttpGet]
[Route("GetServiceStatus")]
[AllowAnonymous]
public string GetServiceStatus()
{
return "OK";
}
}

How do I reset or change passwords using SimpleMembership in MVC4?

I've been writing a web application using the MVC4 Internet template. I really didn't need anything complicated for user management, so I went with the default SimpleMembershipProvider. I'm initializing membership in App_Start, and I have roles and users set up and working. I am not using SSO or any of the other OAuth features. Now I have a tester that has forgotten his password and after googling all day I realize I have no idea how to just reset his password or change it!
I've read through the documentation and found that the ResetPassword function is not supported if using SimpleMembership. My question is, how do I either:
switch from SimpleMembership to standard membership that uses the SimpleMembership tables and format
reset the user's password to something I specify?
I've found the web.config settings to (theoretically) set the membership provider to use SimpleMembership, but I'm not sure of how to specify the table to use (assuming that's the right way to do it).
web.config section:
<roleManager enabled="true" defaultProvider="SimpleRoleProvider">
<providers>
<clear/>
<add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData"/>
</providers>
</roleManager>
<membership defaultProvider="SimpleMembershipProvider">
<providers>
<clear/>
<add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
</providers>
</membership>
and the current InitializeDatabaseConnection that I (think) I need to have in the web.config:
WebSecurity.InitializeDatabaseConnection("UPEFSSecurity", "Datamart_User", "UserId", "UserName", autoCreateTables: true);
To do this properly you would need to set up an email recovery link. But here's the API calls you would make:
var token = WebSecurity.GeneratePasswordResetToken(username);
// create a link with this token and send email
// link directed to an action with form to capture password
WebSecurity.ResetPassword(token, password);
http://msdn.microsoft.com/en-us/library/webmatrix.webdata.websecurity.resetpassword(v=vs.111).aspx

Why is ServiceSecurityContext.Current null in an MVC Controller?

I have an ASP.NET MVC 4 project that's using Windows authentication in the Web.config like so:
<system.web>
<authentication mode="Windows" />
</system.web>
However, if I investigate ServiceSecurityContext.Current from a Controller method, it's null. Shouldn't it contain the authentication info of the user since I'm using Windows authentication?
The reason I'm trying to figure this out is because I would like to know what credentials CredentialCache.DefaultNetworkCredentials is using from a Controller method. From what I gathered by reading the MSDN article on the property, it uses the current security context's credentials... which is null.
Thanks for the help!
The ServiceContext classes is intended to be used inside WCF services. It has nothing to do with ASP.NET MVC.
Trying to use ServiceContext.Current inside an ASP.NET MVC application is like trying to use HttpContext.Current inside a console application => you get NULL.
The reason I'm trying to figure this out is because I would like to
know what credentials CredentialCache.DefaultNetworkCredentials is
using from a Controller method
Then you are looking for the User.Identity.Name property:
[Authorize]
public ActionResult Index()
{
string currentUser = User.Identity.Name;
...
}

potentially dangerous Request servicestack

I am submitting a query string that contains a value
Body=%3Ch2%3E (Body=<h1>)
to a servicestack rest endpoint. That results in:
A potentially dangerous Request.QueryString value was detected from the client (Body=\"<h2>\").
I know that in MVC 4 you can allow Html content for an specific field, if you decorate the field in the model with [AllowHtml] like so:
[AllowHtml]
public string Body { get; set; }
Did that, but the error persists. Had doubts that it was service stack not partaking properly in the validation process, so tested by creating a pure MVC 4 controller with the same model, and that works fine.
However I need a solution for ServiceStack. Their documentation is thin and Google searches lead nowhere.
It looks like you are hosting your ServiceStack service inside an ASP.NET application.
You could add the following to the <system.web> section of your web.config file in order to disable request validation for the entire application:
<system.web>
<httpRuntime requestValidationMode="2.0" />
...
</system.web>
And if you want to disable request validation only for a particular endpoint and not the entire application use the <location> tag in your web.config:
<location path="hello">
<system.web>
<httpRuntime requestValidationMode="2.0" />
</system.web>
</location>
This will disable request validation for all /hello endpoints in your application. For example /hello?Body=%3Ch2%3E will work but /bar?Body=%3Ch2%3E won't work.
You can read more about request validation in ASP.NET in the following MSDN article.
And obviously you should not be worried about this if you are self-hosting your ServiceStack service.