Обычно MVC
не используется для работы API.В то время как MVC
может обрабатывать вызовы API, Microsoft имеет MVC
подобный продукт под названием WebApi
, который более приспособлен для обслуживания API, например, возвращает JSON или XML вместо представления.
В обоих случаяхMVC
и WebApi
, обработка аутентификации и авторизации внутри методов не рекомендуется.Пока он работает, он открывает вам возможность забыть о защите вызова API.Поэтому Microsoft создала атрибуты AuthenticationFilter
и AuthorizationFilter
.Они позволяют вам отмечать, какие API или представления должны быть защищены методом, классом или приложением.
Чтобы получить доступ к основным учетным данным из запроса в MVC
, вам потребуется доступ к заголовку авторизации.Это будет строка в виде Basic [Base64Encoded, colon delimited strings]
.
В следующем коде показан грубый пример того, как считывать учетные данные:
public ActionResult TestView()
{
bool isAuthenticated;
var base64Header = Request.Headers["Authorization"];
//The header is a string in the form of "Basic [base64 encoded username:password]"
if (base64Header != null)
{
var authHeader = AuthenticationHeaderValue.Parse(base64Header);
if (authHeader != null
&& authHeader.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase)
&& authHeader.Parameter != null)
{
//Decode the username:password pair
var credentialPair = Encoding.ASCII.GetString(Convert.FromBase64string(authHeader.Parameter));
//Split into pieces
var credentials = credentialPair.Split(new [] {":"}, StringSplitOptions.None);
var userName = credentials[0];
var plainTextPassword = credentials[1];
isAuthenticated = SomeAuthenticator.Authenticate(userName, password);
}
}
if (isAuthenticated)
return Foo();
else
RedirectResult("your login view");
}
Было бы лучше вставить этот кодв AuthenticationFilter
однако.Это дает вам возможность включать / выключать авторизацию по методу, классу или приложению.
public class CustomAuthFilter : IAuthenticationFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
var header = filterContext.RequestContext.HttpContext.Request.Headers["Authorization"];
if (!Authenticate(header))
filterContext.Result = new HttpUnauthorizedResult();
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
filterContext.Result = new RedirectResult(@"https:\\foo\YourLoginPage");
}
private bool Authenticate(string rawAuthorizationHeader)
{
try
{
if (rawAuthorizationHeader != null)
{
var authHeader = AuthenticationHeaderValue.Parse(rawAuthorizationHeader);
if (authHeader != null
&& authHeader.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase)
&& authHeader.Parameter != null)
{
var credentialPair = Encoding.ASCII.GetString(Convert.FromBase64String(authHeader.Parameter));
var credentials = credentialPair.Split(new[] { ":" }, StringSplitOptions.None);
var userName = credentials[0];
var plainTextPassword = credentials[1];
return SomeAuthenticator.Authenticate(userName, plainTextPassword);
}
}
return false;
}
catch (Exception)
{
return false;
}
}
}
И затем использовать
[CustomAuthFilter] //Secure all methods in the class
public class SecureApiController
{
public ActionResult SecuredApiCall()
{
return Foo();
}
public ActionResult AnotherSecuredCall()
{
return Bar();
}
[AllowAnonymous]
public ActionResult UnsecuredApiCall()
{
return UnsecureFoo();
}
}
Обратите внимание, что в типичном для Microsoft стиле, Аутентификация и Авторизация - это две разные вещи.Вам нужно будет установить фильтр авторизации, если вы хотите защитить API более чем «у этого пользователя есть учетная запись».