Mis à jour: Merci à l'aide ici que j'ai créé la solution suivante:attribut demande à l'utilisateur de se connecter au lieu de l'accès refusé?
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"}
});
}
}
}
Je suis parti de NerdDinner et je utilise FormsAuthentication avec ActiveDirectory comme mon fournisseur d'appartenances. J'ai ajouté le support pour les rôles via mon db avec Global.asax & AccountController (ci-dessous).
Alors maintenant, dans mon contrôleur j'ai mon attribut Autorisez défini sur les rôles de seul administrateur (ci-dessous). Mon utilisateur connecté est un auteur. Lorsque je clique sur Supprimer, il me demande de me connecter même si je l'ai déjà fait. Où puis-je mettre la logique pour retourner une vue d'accès refusé?
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 a tout à fait raison: vous devez gérer l'exception de rôles par rapport à un utilisateur non authentifié. Je ne pense pas que ce serait trop difficile, mais je ne l'ai pas essayé donc YMMV. Je vous déconseillerais aussi de jouer avec AuthorizeCode ou OnAuthorization, sauf si vous voulez vraiment implémenter votre propre schéma d'authentification. – Hal
Je dois lire plus. En attendant, je pourrais utiliser un peu d'aide avec HandleUnauthorizedRequest. Je comprends comment lancer ma propre classe qui hérite de AuthorizeAttribute, puis redéfinir HandleUnauthorizedRequest. Je n'ai pas besoin de mon propre attribut puisque c'est la seule chose qui change. Alors, comment remplacer HandleUnauthorizedRequest sans dériver? – ryan
Vous devez dériver un nouveau type et remplacer cette méthode. Mais cette méthode est la seule chose que vous devez changer. –