authentication and authorizing in ASP.NET MVC 5 - asp.net

Asp.net MVC 5 seems to have left behind using the AuthorizeAttribute class where you could create a custom authorize attribute by implementing the AuthorizeAttribute class, override its methods and hiding the SiteRole property incase you wanted to bake in your own roles. All the examples I have seen either suggest using OWIN or the identity framework. Are these the only two ways to do authentication and authorization in the new ASP.Net framework?. Will I miss out on anything if I do it the old fashioned way? I dont want to have the framework create all the user and role tables for me. What if I want to add an existing user and role table to a new application?
I also really don't see a need for social integration in every application as yet and don't think I will need it immediately as well. Is there any article that explains starting off with a bare minimum by using a custom authorize attribute and then goes on to add the new authentication features. I want something that basically explains all the clutter in a newly created project with No Authentication or Individual User Authentication selected.

You can still customize the AuthorizeAttribute in MVC 5 using ASP.NET Identity. There is an example of doing this in the SimpleSecurity Project. Here is a customized AuthorizedAttribute you can use for controllers and here is customized AuthorizeAttribute you can use for Web API's. The concept behind these custom AuthorizeAttributes is to decouple your security model from your application model which is discussed here. The one for the Web API's also supports basic authentication.
The security pipeline has changed with the introduction of OWIN and I did run into some issues with the behavior of AuthorizeAttribute for Web API's, which is discussed here.
You will also find examples in the SimpleSecurity project on porting of the old membership provider called SimpleMembership to MVC 5. Some of the issues with the upgrade process are discussed here. I did get it to work though so you could go with the old membership provider implementation. But my recommendation would be to go with the ASP.NET Identity as this is the way going forward that Microsoft will be supporting, it is a more flexible architecture, and it eliminates many of the issues found in the old membership provider implementations.

Ben Foster has a two-part series that takes you through steps on implementing cookie-based authentication with ASP.NET Identity from the ground up, starting off with a new Web app with no authentication selected. Follow along "ASP.NET Identity Stripped Bare" Part 1 and Part 2.
use the following Authorize attribute to handle unauthorized access when the user is already authenticated.
public class LoggedOrAuthorizedAttribute : AuthorizeAttribute
{
public LoggedOrAuthorizedAttribute()
{
View = "error";
Master = String.Empty;
}
public String View { get; set; }
public String Master { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
CheckIfUserIsAuthenticated(filterContext);
}
private void CheckIfUserIsAuthenticated(AuthorizationContext filterContext)
{
// If Result is null, we’re OK: the user is authenticated and authorized.
if (filterContext.Result == null)
return;
// If here, you’re getting an HTTP 401 status code. In particular,
// filterContext.Result is of HttpUnauthorizedResult type. Check Ajax here.
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
if (String.IsNullOrEmpty(View))
return;
var result = new ViewResult {ViewName = View, MasterName = Master};
filterContext.Result = result;
}
}
}

Related

Custom Authorize attribute without Identity and OWIN

I would like to construct a custom authorization attribute that does not invoke Identity or OWIN. Essentially, the only thing that it should have access to is a request context and the ability to either tell the MVC framework to process to continue to process the request or deny it.
Question Is there a simple way of achieving this in ASP.NET Core 2?
Some ideas
My understanding of ASP.NET Core is that it provides a way to customize the request pipeline using different middleware. I have seen that there are specific ones that are used for authentication, but they all seem to be very specific to Identity.
Is it better to to use a different type of filter?
A little bit late answer, but still.. the "old" way of overriding attributes comes back with the .Net Core 2.0, where in addition to the base class, you have to implement the IAuthorizationFilter interface:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class CustomAuthorizeAttribute : AuthorizeAttribute, IAuthorizationFilter
{
private readonly string _someFilterParameter;
public CustomAuthorizeAttribute(string someFilterParameter)
{
_someFilterParameter = someFilterParameter;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
// you can play with the context here
}
}
More discussion here

Token-based authentication for Web API in an application which uses SimpleMembershipProvider

I have an ASP.NET Web API MVC 5.0 application. I've configured an ASP.NET Web API as part of this application (contained in the same project).
I'm currently attempting to add token-based authentication to my Web API. The guide I've been using however has been coding everything using Microsoft.AspNet.Identity with Owin.
However, my MVC project is still using the System.Web.Security SimpleMembershipProvider - so initialising the membership tables and managing accounts is performed using the WebSecurity class.
So, it looks like I have two options to move forward here:
Update my MVC application to switch to use Microsoft.AspNet.Identity so that it will work with my Web API token authentication.
Change my Web API authentication code to work with SimpleMembershipProvider
Firstly, is it even practically possible to make my Web API authentication work with SimpleMembershipProvider?
If I update my project to use Microsoft.Asp.Identity, it will involve a bit of work I'm sure. I'm game for doing that but just want to make sure it's not totally trivial to make my Web API token authentication work with SimpleMembershipProvider. Will there be any additional advantages to migrating to use Microsoft.Asp.Identity?
Just to give an example of what I have for my Web API authentication:
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
var user = await userManager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect");
return;
}
var oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType);
var cookiesIdentity = await user.GenerateUserIdentityAsync(userManager, CookieAuthenticationDefaults.AuthenticationType);
var properties = CreateProperties(user.UserName);
var authenticationTicket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(authenticationTicket);
context.Request.Context.Authentication.SignIn(cookiesIdentity);
}
My existing MVC authentication code just uses the WebSecurity methods for managing accounts.
Thank you.
In the end up, I switched over from using the SimpleMembershipProvider to use the Asp.Net.Identity provider. The migration was actually fairly simple.
On my Entity Framework database context, I simply inherited the 'IdentityDbContext' class, e.g.
public class DataContext : IdentityDbContext<ApplicationUser>
And added this to my OnModelCreating override:
base.OnModelCreating(modelBuilder);
In my service which manages accounts, I added code which gets a reference to the new 'ApplicationSignInManager' and 'ApplicationUserManager', e.g.
public ApplicationSignInManager SignInManager
{
get => _signInManager ?? HttpContext.Current.GetOwinContext().Get<ApplicationSignInManager>();
private set => _signInManager = value;
}
public ApplicationUserManager UserManager
{
get => _userManager ?? HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
private set => _userManager = value;
}
And then each time my code referenced the 'WebSecurity' class I simply replaced those calls with the relevant calls using my UserManager or SignInManager.
ASP.NET Identity also offers some advantages:
Supports Web Forms, MVC, Web API, SignalR and web pages. Don't need to have different implementations of a membership system.
Claims based authentication is now an option alongside role-based authentication.
Easy to enable social logons with Facebook, Google, Twitter or Microsoft Live.
Supports OWIN.
No need to code in functionality for account confirmation, password resets and so on - these are out of the box features of Asp.Net Identity.

Get session in ASP boilerplate service layer

I am currently use AspNetBoilerplate to implement my services in service layer...
So I can access session in MVC controller like:
Token token = HttpContext.Session["Token"] as Token;
After login Token session be initiated....
I can access thta everywhere in MVC controllers but in ApplicationServiceBase it is null like:
public class AuditAppService : ApplicationServiceBase, IAuditAppService
{
public GetUserActions_Box GetUserActions()
{
var token = HttpContext.Current.Session.GetToken();
return GetUserActions_Box.Empty;
}
}
HttpContext.Current.Session is null why?
that app services are implemented in separate library which is added in main web application.
I followed the documentation and crossed This, I think AbpSession is not my solution which mean by it we can access some basics info about session that initiated by AbpBoilerPlate authentication system not ours.
use IAbpSession .
you can use claims to add your custom values to the AbpSession.
previously answered here about how to extend AbpSession
Extend ClaimsAbpSession
read AbpSession https://aspnetboilerplate.com/Pages/Documents/Abp-Session

ASP.NET MVC4 authorization depending on role and information

I'm currently developing an ASP.NET MVC4 application which have 3 roles: admin, manager and editor. The editors can CRUD articles in the system BUT the editors can only read, update or delete their OWN articles. I've seen I can control the access to the controller and action by adding:
[Authorize(Roles="editor")]
but it only restricts the role not the information.
If the editor A created the article 1 ONLY the editor A has access to that article.
No other role has access to the controller or the information.
What would be the best practice in order to restrict the access by role and by context?
It is not practical to create a custom AuthorizeAttribute to check whether a user is allowed to update a specific article.
Instead, you want to check that logic in controller (or business logic). You can see that approach in a lot of open source projects.
[HttpPost]
[Authorize(Roles="editor")]
[ValidateAntiForgeryToken]
public ActionResult Update(ArticleModel model)
{
if(IsUserAllowedToUpdate(userId, model.ArticleId))
{
// Update article
}
return View(model);
}
You could implement this in the core of your system, for example by having a field in your datastore, identifying creator and users with permission.
Then you could implement your own authorizeattribute like;
public class CustomAuthenticateAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
// your own business logic, for instance, check if the user is the
// creator of the requested resource (check a database field you
// have created to identify the creator etc...)
// if that goes well authorize using regular roles, below
return base.AuthorizeCore(httpContext);
}
}
You would then decorate your controller with
[AuthorizeAttribute(Role = "editors")]

What is the most unobtrusive way to add a layer of security for a private beta of website?

Let's say I have an ASP.NET site (MVC in this case) that uses Forms authentication and a typical membership system. The site allows both authenticated and anonymous users.
When I release the site as a private beta I want to add another layer of security on top of the application, like superuser's simple password system, for example. Once a user has passed this layer of security, I still want my forms authentication/membership system in place so beta testers can view the site as authenticated or anonymous users.
What's the most unobtrusive way to achieve this? I'm looking for the easiest solution that will require the least amount of new or modified code. E.g. I don't want to modify every controller to check for a special cookie. There must be a better way...
There's a very similar question here, but it seems the site in question (once public) will only serve anonymous requests, so it doesn't necessarily compare to my situation. This answer suggests ServerFault used some cookie system, but there are no further details about how it might have been implemented.
Implement security at server level, in IIS and add the accounts/passwords in Active Directory of Windows running the IIS server.
You won't need to change any of the code.
Well, I know you don't want to modify your current controllers but here's what I did for a similar behaviour.
I've created a custom ActionFilterAttribute that I've given to every controller that requires to have that specific access check. You can have something like this :
public class CheckBetaAccess : ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext filterContext) {
if (!canAccess) {
filterContext.Controller.ViewData["someViewData"] = "some text";
filterContext.Result = new ViewResult {
ViewName = "the-view-anonymous-users-should-see",
ViewData = filterContext.Controller.ViewData
};
filterContext.Result.ExecuteResult(filterContext);
}
}
}
Then I decorated my controllers :
[CheckBetaAccess]
public class SomeController : Controller {
//....
}

Resources