2015-10-14 3 views
2

Мне нужно получить UserId из системы авторизации пользователей Asp.Net, потому что большинство моих данных хранится в SQL и использует UserId в качестве маркера, который пользователь владеет этими данными. Используя Owin OAuth 2.0, я не могу получить UserId с помощью Identity, он возвращает null. Так я пришел к этому решению:Можете ли вы сохранить UserId внутри токена Owin OAUTH 2?

Токен провайдера

identity.AddClaim(new Claim("user_id", user.Id)); 

API

ClaimsPrincipal principal = Request.GetRequestContext().Principal as ClaimsPrincipal; 
var userName = principal.Claims.Where(c => c.Type == "user_id").Single().Value; 

Simpler кода API

var userName = ClaimsPrincipal.Current.Claims.First(c => c.Type == "user_id").Value; 

Этот подход подходит для корпоративного бизнес-приложения, безопасен, безопасен и прочен? Или вы, может быть, посоветуете что-нибудь еще?

Мне просто не нравится идея пропуска UserId внутри токена, если эта функция (возможно) предоставлена ​​Microsoft.AspNet.Identity (сама по себе .NET), но поскольку я не мог заставить ее работать, это мой единственный вариант на данный момент.

В любом случае, я частично использую код от this great tutorial repository. Как вы можете видеть, этот контроллер прокомментировал строки, которые используют Identity для получения UserId. Но это не работает для меня, поэтому я использую другую прокомментированную строку, в которой используются утверждения.

+0

где вы положили эти две строки кода, в контроллере или фильтр? –

+0

В контроллере (ApiController) – EwanCoder

+0

Каждый контроллер будет иметь свойство 'User', поэтому измените свою первую строку кода:' ClaimsPrincipal main = User as ClaimPrincipal; 'затем он работает –

ответ

4

Поскольку вы используете OWIN, я собираюсь предположить, что вы используете идентификатор ASP.NET. Вам не нужно хранить идентификатор пользователя в качестве претензии. Вы можете получить его в любое время вам нужно с помощью:

User.Identity.GetUserId() 

Если Intellisense выкрутасы, вам просто нужно добавить Microsoft.AspNet.Identity имен.

+1

Ну, я ** пытался ** много раз. Это включает в себя множественную переустановку пакетов Microsoft.AspNet.Identity.Core с использованием Microsoft.AspNet.Identity, дело в том, что 'User.Identity.GetUserId()' возвращает 'null'. И да, мой контроллер полностью защищен [Авторизовать]. Я также попытался установить пакет Microsoft.AspNet.Identity.Owin прямо сейчас, тот же результат. – EwanCoder

+0

Если он возвращает null, это означает, что пользователь анонимен, то есть не аутентифицирован. Легко и просто. Попытка получить идентификатор от претензии не помогла бы, так как она также будет нулевой. –

+0

Также, если это «null», возможно, вы правильно настроили аутентификацию в 'startup.cs' –

0

Я предполагаю идентичность объект в коде ниже имеет тип ClaimsIdentity. Как и где вы инициализируете этот объект?

identity.AddClaim(new Claim("user_id", user.Id)); 

Если вы посмотрите на шаблон по умолчанию, который создается для веб-приложения в Visual Studio будет являться IdentityModel класс, где вы можете увидеть код, как показано ниже, и это называется, когда вы зарегистрировались в ASP.Net Identity.

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) 
    { 
     // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType 
     var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 
     // Add custom user claims here 
     return userIdentity; 
    } 

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

Итак, когда вы создаёте идентификатор ?

Если вы сомневаетесь, если это нормально, чтобы добавить дополнительную информацию в качестве претензии, я думаю, что все должно быть в порядке. Кроме того, каков выход

identity.GetUserId(); 

в вашем случае?

Вы можете дополнительно написать свой собственный класс IdentityExtensions, как описано в http://anthonychu.ca/post/aspnet-identity-20---logging-in-with-email-or-username/

Update 1 -

При входе в систему с помощью ASP.Net удостоверений, она вызывает GenerateUserIdentityAsync, который внутренне вызывает метод CreateAsync, определенный в UserClaimsPrincipalFactory классе. Вот код https://github.com/aspnet/Identity/blob/daa50df87feb9f1b59858a22f00a2984996738c6/src/Microsoft.AspNet.Identity/UserClaimsPrincipalFactory.cs. Если вы посмотрите на этот метод на самом деле делает то, что вы делаете явно

var id = new ClaimsIdentity(Options.Cookies.ApplicationCookieAuthenticationScheme, Options.ClaimsIdentity.UserNameClaimType, Options.ClaimsIdentity.RoleClaimType); 
id.AddClaim(new Claim(Options.ClaimsIdentity.UserIdClaimType, userId)); . 

Так что я считаю, что это то, что вы должны сделать

+0

Вывод GetUserId() является «null». Я как-то понял, как упростить свой код: 'ClaimsPrincipal.Current.Claims.First (c => c.Type ==" userId "). Value;' работает. И я не создаю объект идентификации нигде и не объявлен нигде, у меня даже нет подключения к базе данных в моем контроллере API. API и Token-сервер полностью развязаны, где сервер Token (с подключением к базе данных и AccountController) предоставляет токены и претензии, а сервер API просто предоставляет авторизацию на основе токена (доступ к ресурсам) – EwanCoder

+0

Итак, каков тип объекта идентификации в вашем коде identity.AddClaim? –

+0

ClaimsIdentity (OAuthGrantResourceOwnerCredentialsContext context.Options.AuthenticationType) – EwanCoder

Смежные вопросы