Aggiornato: Grazie all'aiuto qui ho creato la seguente soluzione:chiede all'utente di accedere invece dell'accesso negato?
public class CustomAuthorize : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
// Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs
// If user is not logged in prompt
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
base.HandleUnauthorizedRequest(filterContext);
}
// Otherwise deny access
else
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary {
{"controller", "Account"},
{"action", "NotAuthorized"}
});
}
}
}
ho iniziato da NerdDinner e sto usando FormsAuthentication con ActiveDirectory come il mio provider di appartenenza. Ho aggiunto il supporto per i ruoli tramite il mio db con Global.asax & AccountController (sotto).
Così ora nel mio controller ho il mio attributo Autorizza impostato solo sui ruoli di admin (sotto). Il mio utente che ha effettuato l'accesso è un autore. Quando faccio clic su Elimina mi chiede di accedere anche se l'ho già fatto. Dove posso inserire la logica per restituire una vista negata dell'accesso?
Global.asax.cs
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null || authCookie.Value == "")
{
return;
}
FormsAuthenticationTicket authTicket = null;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch
{
return;
}
if (Context.User != null)
{
string[] roles = authTicket.UserData.Split(new char[] { ';' });
Context.User = new GenericPrincipal(Context.User.Identity, roles);
}
}
AccountController.cs
[HttpPost]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
Justification = "Needs to take same parameter type as Controller.Redirect()")]
public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl)
{
if (!ValidateLogOn(userName, password))
{
ViewData["rememberMe"] = rememberMe;
return View();
}
// Make sure we have the username with the right capitalization
// since we do case sensitive checks for OpenID Claimed Identifiers later.
userName = this.MembershipService.GetCanonicalUsername(userName);
// Lookup user's (CWID) appropriate access level
string accessLevel = userRepository.FindUserByUserName(userName).AccessLevel.LevelName;
FormsAuthenticationTicket authTicket = new
FormsAuthenticationTicket(1, //version
userName, // user name
DateTime.Now, //creation
DateTime.Now.AddMinutes(30), //Expiration
rememberMe, //Persistent
accessLevel); // hacked to use roles instead
string encTicket = FormsAuthentication.Encrypt(authTicket);
this.Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
SpotlightController.cs
[Authorize(Roles="Admin")]
public ActionResult Delete(int id)
Craig ha assolutamente ragione: dovresti gestire l'eccezione di un ruolo rispetto a un utente non autenticato. Non penso che sarebbe troppo difficile, ma non l'ho provato in modo YMMV. Anch'io sconsiglio di fare confusione con AuthorizeCode o OnAuthorization a meno che tu non voglia veramente implementare il tuo schema di autenticazione. – Hal
Ho bisogno di leggere di più. Nel frattempo potrei usare qualche aiuto per sovrascrivere HandleUnauthorizedRequest. Capisco come eseguire il rollover della mia classe che eredita da AuthorizeAttribute e quindi eseguire l'override di HandleUnauthorizedRequest. Non ho bisogno del mio attributo dato che questa è l'unica cosa che sta cambiando. Quindi, come sovrascrivere HandleUnauthorizedRequest senza derivare? – ryan
È necessario derivare un nuovo tipo e sovrascrivere quel metodo. Ma quel metodo è l'unica cosa che devi cambiare. –