1

Довольно новый для авторизации и аутентификации, поэтому, возможно, мне не хватает какого-то важного шага ... Просто посмотрите на многочисленные ссылки, руководства и учебные пособия.Не удается получить доступ или авторизировать веб-интерфейс ASP.Net после установки Директора Thread и HttpContext

Возможно, мне нужно что-то сделать в моем WebApiConfig?

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     config.MapHttpAttributeRoutes(); 

     config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/{controller}/{id}", 
      defaults: new { id = RouteParameter.Optional } 
     ); 
    } 
} 

Или, возможно, в моей Global.asax:

public class WebApiApplication : System.Web.HttpApplication 
{ 
    private const string RootDocument = "/index.html"; 
    protected void Application_Start() 
    { 
     GlobalConfiguration.Configure(WebApiConfig.Register); 
    } 

    protected void Application_BeginRequest(Object sender, EventArgs e) 
    { 
     // Stuff to redirect to index.html unless it's an api url 
    } 
} 

Это ASP.Net Web API проект таргетинга .NET Framework 4.5.2 с угловыми 2 фронтэнда, и я ничего не делать вручную на передняя часть, может быть, мне нужно это сделать? Мое локальное хранилище, хранилище сеансов и файлы cookie пустые в браузере.

Сервер SQL я доступ имеет очень простой пользовательский метод входа, который возвращает роль и USERID, который я называю в моем хранилище здесь:

public static DbUser Logon(AuthUser user) 
    { 
     var parameters = new List<SqlParameter>(); 
     { 
      // Add parameters, get the DbUser (contains role and userId), and return the DbUser 
     } 
    } 

вход в интерфейсе построен с угловыми 2 и делаю HttpPost называют имя пользователя и пароль при представить следующим способом API, создавая идентичность и основной, и установив тему и HttpContext:

// POST api/<controller> 
    [HttpPost] 
    public TokenUser Post(AuthUser user) 
    { 
     var dbUser = DBAccess.Repository.User.Logon(user); 

     var identity = new ClaimsIdentity(); 
     identity.AddClaim(new Claim(ClaimTypes.Name, "CwRole")); 
     identity.AddClaim(new Claim(ClaimTypes.Role, dbUser.AccessLevel)); 
     identity.AddClaim(new Claim(ClaimTypes.UserData, dbUser.ID.ToString())); 

     var principal = new ClaimsPrincipal(identity); 
     Thread.CurrentPrincipal = principal; 
     if (HttpContext.Current != null) 
      HttpContext.Current.User = principal; 

     // Other stuff and a return statement => 
     // Note I'm not actually doing anything manually with the token on the front end 
     // which may be why I'm not seeing it in the debugger's Resources tab... 
    } 

Когда я пошагово этот код я могу ясно видеть, что Thread.CurrentPrincipal и HttpContext .Текущий пользователь оба заселены, соответственно, казалось бы.

Но если я украшаю действие атрибутом [Авторизовать], я не могу получить к нему доступ, будь то вход в систему или нет.

 // Works fine 
     public IEnumerable<ItemGroup> Get() 
     { 
      return DBAccess.Repository.Item.GetItemGroups(); 
     } 

     // Responds with 401 (Unauthorized) no matter what 
     [Authorize] 
     public IEnumerable<RequestItem> Get() 
     { 
      return DBAccess.Repository.Item.GetRequestItems(); 
     } 

Так что я создал эти методы, доступ к ним через браузер URL после вышеуказанного процесса входа и шагнул, только чтобы обнаружить, что пользователь фактически никогда не установлен (претензии пусты, и т.д ...)

public class AuthController : ApiController 
{ 
    public bool Get() 
    { 
     // Stepping through, looks like User.Identity is not even set... 
     var authenticated = User.Identity.IsAuthenticated; 
     return authenticated; 
    } 

    public bool Get(string role) 
    { 
     // As a matter of fact, User doesn't have any claims or anything... 
     var user = User; 
     return user != null && user.IsInRole(role); 
    } 
} 

Итак, какой шаг я пропустил, чтобы сделать доступным принципала после его установки? Нужно ли мне обращаться к нему с помощью чего-то другого, кроме встроенных «User» методов WebApi, или установить что-то в моей конфигурации или сделать что-то вручную на передней панели?

+0

Где «пользователь» в 'var dbUser = DBAccess.Repository.User.Logon (пользователь);' отсюда и где выполняется этот фрагмент кода. Пожалуйста, предоставьте [mcve]. Вы в настоящее время не разделены. – Nkosi

+0

Поставщик авторизации следует добавить в webapiconfig.cs.Подробнее здесь http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api –

+0

@Nkosi благодарит вас за отзыв. Я добавил подробности. Мне просто не нравится ставить много кода в вопрос, когда я не уверен, что относится к проблеме ... – Methodician

ответ

1

Вы используете аутентификацию претензии, поэтому при успешной аутентификации вы получите токен.Поэтому для того, чтобы сохраняться маркером для последующих/следующих запросов Web Api вы должны выполнить одно из следующих способов упорствовать

  1. Вы должны установить детали аутентификации к Cookie, который будет автоматически добавленного браузером все последующие запросы OR OR
  2. Вы можете сохранить токен в локальном хранилище браузера, для следующего запроса - вы должны добавить токен носителя требований в заголовок запроса [для аутентификации].

Вариант 1:

Настройка аутентификации печенье

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, username, DateTime.Now, DateTime.Now.AddMinutes(30), true, userData); 
     string encTicket = FormsAuthentication.Encrypt(ticket); 
     HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket); 
     Response.Cookies.Add(faCookie); 

Доступ к куки для аутентификации в последующих запросах.

HttpCookie authCookie = Request.Cookies[ 
      FormsAuthentication.FormsCookieName]; 
    if(authCookie != null) 
    { 
     //Extract the forms authentication cookie 
     FormsAuthenticationTicket authTicket = 
       FormsAuthentication.Decrypt(authCookie.Value); 
     // Create an Identity object 
     //CustomIdentity implements System.Web.Security.IIdentity 
     CustomIdentity id = GetUserIdentity(authTicket.Name); 
     //CustomPrincipal implements System.Web.Security.IPrincipal 
     CustomPrincipal newUser = new CustomPrincipal(); 
     Context.User = newUser; 
    } 

Вариант 2:

Вы можете получить маркер и сохранить его в браузере Local Storage, и, когда все вы делаете запрос к любому API с Authorize ключевого слова, убедитесь, что вы добавляете Bearer токена в заголовке запроса.

Что-то вроде этого

var authData = localStorageService.get('authorizationData'); 
     if (authData) { 
      config.headers.Authorization = 'Bearer ' + authData.token; 
     } 

следующей статьи объясняет проверку подлинности на основе токенов и имеет образец кода для углового JS, а просто посмотреть http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-and-identity-2/

Наконец,

Для проверки на сервере стороне, вы можете написать настраиваемую авторизацию вместо значения по умолчанию, чтобы проверить токен и установить его соответствующим образом.

+0

Спасибо. Работая над этим сейчас, но в отношении связанной статьи: я не могу использовать Entity Framework с этой унаследованной системой, и насколько я знаю, это исключает использование «UserManager» и, возможно, OAuth вообще, или, может быть, я просто не могу перевести ... – Methodician

+0

Я нашел тему StackOverflow в членстве ASP.Net с Entity Framework. Надеюсь, это поможет - http://stackoverflow.com/a/6449001/2952405 –

+0

Итак, я проработал ваш ответ и столкнулся с проблемой, когда Response.Cookies.Add() недоступен, поскольку это ApiController, а не MVC-контроллер ... – Methodician

0

OnAuthorization Событие происходит очень рано в трубопроводе. Через него проходит любой тип ActionFilter. Как я думаю, вы написали свой код аутентификации (первый фрагмент) в фильтре действий или где-то, что выполняется после события OnAuthorization.

Вы должны рассмотреть возможность передачи этого кода, например, это событие (в global.asax.cs)

Application_PostAuthenticateRequest(Object sender, EventArgs e).

И более элегантный способ это реализовать пользовательские AuthorizeAttribute и получить информацию о пользователях из Request и установить принципал.