I\'ve been trying to get my feet wet with ASP.net MVC 5 for 2013, but so far I\'ve failed to get even the most basic authentication working correctly.
I\'ve been rea
I have had similar problems
I could not figure out what was different between my app (I inherited from someone else) and the default sample code.
I discovered that my [Authorize] attribute was not being applied by the framework even when the rest of the user management stack was working.
I realised eventually that AuthorizeAttribute is an example of a Filter and that by adding it explicitly in the FilterConfig it started to be used as expected (even though it is not added by the default sample code):
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new AuthorizeAttribute());
}
}
and everything as usual in the Application_Start method:
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
Edit:
Although this lets the basic Authorize attribute work, it leads to a problem where the framework isn't instantiating the attribute per-method call with the Roles property set. So I had to figure out what caused the problem. It was due to some Unity setup code:
var oldProvider = FilterProviders.Providers.Single(f => f is FilterAttributeFilterProvider);
FilterProviders.Providers.Remove(oldProvider);
Removing this (it was actually unused) fixed the issue, so I no longer needed FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); either
In the following post http://www.khalidabuhakmeh.com/asp-net-mvc-5-authentication-breakdown there is an helpful OWIN examples.
I did a mistake, the correct link is: http://www.khalidabuhakmeh.com/asp-net-mvc-5-authentication-breakdown-part-deux So, here we go with vb approach for basic cookie login:
a) Cookie Config.
Imports Microsoft.AspNet.Identity
Imports Microsoft.Owin
Imports Microsoft.Owin.Security.Cookies
Imports Owin
Partial Public Class Startup
Public Sub ConfigureAuth(app As IAppBuilder)
app.UseCookieAuthentication(New CookieAuthenticationOptions() With {
.AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
.LoginPath = New PathString("/Account/Login")})
End Sub
End Class
b) Home controller (Home index available for auth users)
<Authorize>
Public Class HomeController
Inherits System.Web.Mvc.Controller
<HttpGet>
Function Index() As ActionResult
Return View()
End Function
End Class
c) Account controller (Login)
Imports System.Security.Claims
Imports System.Threading.Tasks
Imports Microsoft.AspNet.Identity
Imports Microsoft.AspNet.Identity.Owin
Imports Microsoft.Owin.Security
<Authorize>
Public Class AccountController
Inherits Controller
Private Function AuthenticationManager() As IAuthenticationManager
Return HttpContext.GetOwinContext().Authentication
End Function
<AllowAnonymous>
Public Function Login(returnUrl As String) As ActionResult
ViewBag.ReturnUrl = returnUrl
Return View()
End Function
<HttpPost>
<AllowAnonymous>
<ValidateAntiForgeryToken>
Public Function Login(model As LoginViewModel, returnUrl As String) As ActionResult
If ModelState.IsValid Then
If model.UsuarioValido Then 'Local authentication, this must be on Repository class
Dim Identidad = New ClaimsIdentity({New Claim(ClaimTypes.Name, model.UserName)},
DefaultAuthenticationTypes.ApplicationCookie,
ClaimTypes.Name,
ClaimTypes.Role)
Identidad.AddClaim(New Claim(ClaimTypes.Role, "Invitado"))
AuthenticationManager.SignIn(New AuthenticationProperties() With {.IsPersistent = model.RememberMe}, Identidad)
Return RedirectToAction("index", "home")
End If
End If
Return RedirectToAction("login", model)
End Function
<HttpGet>
Public Function LogOff() As ActionResult
AuthenticationManager.SignOut()
Return RedirectToAction("login")
End Function
End Class
d) Account Model
Imports System.ComponentModel.DataAnnotations
Public Class LoginViewModel
<Required>
<Display(Name:="Nombre de usuario")>
Public Property UserName As String
<Required>
<DataType(DataType.Password)>
<Display(Name:="Contraseña")>
Public Property Password As String
<Display(Name:="¿Recordar cuenta?")>
Public Property RememberMe As Boolean
Public ReadOnly Property UsuarioValido As Boolean
Get
Return Password = "secreto" 'Password Here!
End Get
End Property
End Class
e) Index view
@Imports Microsoft.AspNet.Identity
@Code
ViewData("Title") = "Página Inicial"
End Code
<h2>Bienvenido @User.Identity.GetUserName()</h2>
<a href="@Url.Action("LogOff", "Account")">
Click para salir! (Cerrar Sesión)
</a>
f) Login View
@ModelType LoginViewModel
@Code
ViewBag.Title = "Iniciar sesión"
End Code
<h2>@ViewBag.Title.</h2>
<div class="row">
<div class="col-md-8">
<section id="loginForm">
@Using Html.BeginForm("Login", "Account", New With { .ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, New With {.class = "form-horizontal", .role = "form"})
@Html.AntiForgeryToken()
@<text>
<h4>Utilice una cuenta local para iniciar sesión.</h4>
<hr />
@Html.ValidationSummary(True)
<div class="form-group">
@Html.LabelFor(Function(m) m.UserName, New With {.class = "col-md-2 control-label"})
<div class="col-md-10">
@Html.TextBoxFor(Function(m) m.UserName, New With {.class = "form-control"})
@Html.ValidationMessageFor(Function(m) m.UserName)
</div>
</div>
<div class="form-group">
@Html.LabelFor(Function(m) m.Password, New With {.class = "col-md-2 control-label"})
<div class="col-md-10">
@Html.PasswordFor(Function(m) m.Password, New With {.class = "form-control"})
@Html.ValidationMessageFor(Function(m) m.Password)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox">
@Html.CheckBoxFor(Function(m) m.RememberMe)
@Html.LabelFor(Function(m) m.RememberMe)
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Iniciar sesión" class="btn btn-default" />
</div>
</div>
</text>
End Using
</section>
</div>
</div>
@Section Scripts
@Scripts.Render("~/bundles/jqueryval")
End Section