J'ai un service réparateur ASP MVC3 qui utilise l'authentification de base. Après avoir fouillé le débordement de la pile, j'ai créé le code suivant.
public class BasicAuthentication : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var req = filterContext.HttpContext.Request; if (String.IsNullOrEmpty(req.Headers["Authorization"])) { filterContext.Result = new HttpNotFoundResult(); } else { var credentials = System.Text.ASCIIEncoding.ASCII .GetString(Convert.FromBase64String(req.Headers["Authorization"].Substring(6))) .Split(':'); var user = new { Name = credentials[0], Password = credentials[1] }; if(!(user.Name == "username" && user.Password == "passwords")) { filterContext.Result = new HttpNotFoundResult(); } } } }
4 Réponses :
1) Non, les attributs d'actionFilter ne sont pas une bonne approche pour authentifier un utilisateur.
(comme nous devons authentifier une fois et définir authentifier cookie, httpcontext.user restera authentifié jusqu'à ce que Cookie expire) strong> 2) Oui, définir le filtreContext.Result est un moyen idéal pour empêcher l'accès. (mais au lieu d'attribuer httpnotfoundresult, utilisez RedirectriceResult pour rediriger la page de connexion) strong> p> 3) Je ne comprends vraiment pas pourquoi avoir une telle mise en œuvre pour l'autorisation.
La meilleure approche serait d'avoir une action qui recevra des données postées par formulaire (nom d'utilisateur et mot de passe). et utilisez l'attribut Autoriser pour empêcher l'accès non autorisé. strong> p> suivi est le code de l'application d'échantillon MVC3 par défaut dans VS2010. P> [HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Je comprends le modèle de connexion des formulaires et l'utiliser pour un site Web normal. Comment cela fonctionne-t-il pour un service reposant? Comment l'utilisateur fournit-il le login?
MVC est toujours reposant à l'aide de formulaires Authentication.are Vous recherchez un système / service invoquera l'URI MVC, passant des informations d'identification du réseau. Si tel est le cas, l'approche ci-dessus semble bien. (Mais mieux vous pouvez trouver un basocontrôleur et hériter de tous les contrôleurs d'enfants ..Ellez vous pouvez écrire le même code que ci-dessus dans la méthode OnactionExecutation, Sauf si vous n'êtes pas tout à fait d'une API < / b>)
Je pense que vous avez terminé d'ignorer les mots "Service" et "Authentification de base" dans le titre de la question en répondant.
La réponse est non pertinente et en partie à cause de ce non-pertinence aussi. Les filtres sont le moyen préféré d'authentifier et d'authentifier les demandes, peu importe si WebAPI ou MVC sont utilisés. Redirection de la page de connexion n'est pas une préoccupation du processus d'authentification, cela se fera par ASP.NET ou une autre couche si nécessaire. Une autre question pourquoi la réponse est incorrecte est que l'authentification des formulaires utilise des cookies, tandis que les API utilisent généralement l'en-tête d'autorisation, typiquement des jetons porteurs, mais il existe de nombreux autres régimes.
1) est un 2) est le paramètre 3) Y a-t-il quelque chose que je fais mal? Em> p> ci-dessous dans ma mise en œuvre de votre code (que je suis sûr que ses problèmes aussi). p> notes strong> < / p> (1) http://msdn.microsoft.com/en-us/magazine/gg232768.aspx p> p> actionfilterattribute code> le meilleur moyen de faire cela? em>
Je le pense. Cette approche reflète la mise en œuvre de l'attribut authentifié code>.
filtercontext.result code> la bonne façon de refuser l'accès à la méthode du contrôleur? em>
Oui. C'est ce qui est là pour là-bas. (1) p>
httpunauthoriséResult () code> pour envoyer un http
401 Erreur au lieu d'une erreur HTTP 404 via
httpnotfoundresult () code>. Li>
ul>
Version refoulée de Adrian
public class BasicAuthenticationAttribute : ActionFilterAttribute { private static readonly string AuthorizationHeader = "Authorization"; private static readonly string BasicHeader = "Basic "; private static readonly string Username = "username"; private static readonly string Password = "password"; private static readonly char[] Separator = ":".ToCharArray(); public override void OnActionExecuting(ActionExecutingContext filterContext) { try { if (!Authenticated(filterContext.HttpContext.Request)) filterContext.Result = new HttpUnauthorizedResult(); base.OnActionExecuting(filterContext); } catch { filterContext.Result = new HttpUnauthorizedResult(); } } private bool Authenticated(HttpRequestBase httpRequestBase) { bool authenticated = false; if (String.IsNullOrEmpty(httpRequestBase.Headers[AuthorizationHeader]) == false && httpRequestBase.Headers[AuthorizationHeader].StartsWith(BasicHeader, StringComparison.InvariantCultureIgnoreCase)) { string[] credentials = Encoding.ASCII.GetString(Convert.FromBase64String( httpRequestBase.Headers[AuthorizationHeader].Substring(BasicHeader.Length))).Split(Separator); if (credentials.Length == 2 && credentials[0] == Username && credentials[1] == Password) { authenticated = true; } } return authenticated; } }
+1 pour le temps et les efforts. Très utile. Cependant, si la première condition est si «non» authentifiée puis soulevez le httpunauthoriseResult.
Voici une sorte d'échantillon officiel pour l'authentification de base: p>
http://www.asp.net/web-api/ Vue d'ensemble / Sécurité / Authentification-filtres P>
Un autre article, maintenant en utilisant Owin: P>
Utilisez-vous BASIC pour formulaires / authentification de type personnalisé avec BASIC (Auth-Auth à deux étapes) ou toujours à l'aide de comptes de domaine?