Пример использования ASP.NET Identity 2.0 UserManagerFactory с использованием метода UseOAuthBearerTokens?

ASP.NET Identity 2.0 alpha поставляется с новым промежуточным программным обеспечением для управления получением экземпляра UserManager (app.UseUserManagerFactory, чтобы установить это) и получения экземпляра DbContext (app.UseDbContextFactory, чтобы установить это). Существует пример, показывающий, как получить эту работу с приложением MVC, но нет документации о том, как получить эту работу из шаблона SPA, который использует OAuthBearerTokens, в отличие от образца.

В настоящее время я застрял:

UserManagerFactory = () => new DerivedUserManager(new CustomUserStore(new CustomDbContext()));

OAuthOptions = new Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerOptions
    {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new MyApp.Web.Api.Providers.ApplicationOAuthProvider(PublicClientId, UserManagerFactory),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true
    };
app.UseOAuthBearerTokens(OAuthOptions);

и не имеют понятия, как заменить UserManagerFactory выше на вызовы, подобные этим из 2,0 альфа-выборок, все еще работая с объектами OAuthBearerTokens, используемыми в шаблоне SPA:

        app.UseDbContextFactory(ApplicationDbContext.Create);

        // Configure the UserManager
        app.UseUserManagerFactory(new IdentityFactoryOptions<ApplicationUserManager>()
        {
            DataProtectionProvider = app.GetDataProtectionProvider(),
            Provider = new IdentityFactoryProvider<ApplicationUserManager>()
            {
                OnCreate = ApplicationUserManager.Create
            }
        });

Спасибо... -Бен

Ответ 1

Я добавляю здесь заглушки, которые показывают вам, как вы можете использовать OAuthBearerTokens... Вам не нужно использовать UserManagerFactory, который вы использовали в SPA. Вы можете переключить это, чтобы использовать шаблон PerOWINContext.

Startup.Auth.cs

app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

OAuthOptions = new OAuthAuthorizationServerOptions
{
    TokenEndpointPath = new PathString("/Token"),
    Provider = new ApplicationOAuthProvider(PublicClientId),
    AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
    AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
    AllowInsecureHttp = true
};

ApplicationOAuthProvider.cs

public ApplicationOAuthProvider(string publicClientId)
{
   if (publicClientId == null)
   {
       throw new ArgumentNullException("publicClientId");
   }
   _publicClientId = publicClientId;
}

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
   var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();

   ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);

   if (user == null)
   {
       context.SetError("invalid_grant", "The user name or password is incorrect.");
       return;
   }

   ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
               OAuthDefaults.AuthenticationType);
   ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
                DefaultAuthenticationTypes.ApplicationCookie);

   AuthenticationProperties properties = CreateProperties(user.UserName);
   AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
   context.Validated(ticket);
   context.Request.Context.Authentication.SignIn(cookiesIdentity); 
}

// namespace below needed to enable GetUserManager extension of the OwinContext
using Microsoft.AspNet.Identity.Owin;

Ответ 2

Некоторые новые шаблоны с идентификатором ASP.NET 2.0

Идентификатор ASP.NET включает поддержку для создания одного экземпляра UserManager и идентификатора DBContext для каждого запроса приложения. Для поддержки этого шаблона используйте следующие методы расширения для объекта IAppBuilder:

app.CreatePerOwinContext<AppUserIdentityDbContext>(AppUserIdentityDbContext.Create);
app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create);

Вы можете найти отличный пример, реализующий этот шаблон ниже:

ASP.NET Identity 2.0 Проверка файлов cookie и токенов, включая пример проекта.

Вот класс AppManager:

public class AppUserManager : UserManager<AppUserIdentity>
{
    public AppUserManager(IUserStore<AppUserIdentity> store)
        : base(store) { }

    public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
    {
        var manager = new AppUserManager(new UserStore<AppUserIdentity>(context.Get<AppUserIdentityDbContext>()));
        return manager;
    }

}

В этой статье используются компоненты промежуточного ПО OWIN UseOAuthBearerAuthentication и UseCookieAuthentication для поддержки аутентификации на основе браузера, а также одного объекта Owin контекста IdentityDb и одного AppManager.

Идентификаторы маркера установки

Startup.Auth.cs

OAuthBearerOptions = new OAuthBearerAuthenticationOptions();

//This will used the HTTP header: "Authorization" Value: "Bearer 1234123412341234asdfasdfasdfasdf"
app.UseOAuthBearerAuthentication(OAuthBearerOptions);
// Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login")
}); 

HostAuthenticationFilter представляет собой фильтр аутентификации, который аутентифицируется через промежуточное ПО OWIN:

WebApiConfig.cs

config.SuppressDefaultHostAuthentication();
//This will used the HTTP header: "Authorization" Value: "Bearer 1234123412341234asdfasdfasdfasdf"
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

Чтобы создать токен:

var identity = new ClaimsIdentity(Startup.OAuthBearerOptions.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, user));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userIdentity.Id));
AuthenticationTicket ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
var currentUtc = new SystemClock().UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));
string AccessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);
return AccessToken;

Ответ 3

Бен, некоторые из этих вещей изменились с альфа-1 на бета-версии (в настоящее время доступны в ASP.NET Nightly NuGet Repo на https://aspnetwebstack.codeplex.com/wikipage?title=Use%20Nightly%20Builds). Если вы обновляетесь до последних бета-бит, вы больше не будете использовать этот синтаксис, но вместо этого:

// Configure the db context and user manager to use per request
app.CreatePerOwinContext(ApplicationIdentityContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

Также обратите внимание, что HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager> теперь перемещается в Microsoft.AspNet.Identity.Owin.

Вы можете установить пакет Microsoft.AspNet.Identity.Samples(желательно в новый проект MVC, поскольку он может перезаписывать файлы). Это помогло мне узнать, как они делают определенные вещи, учитывая документацию на 2.0, в настоящее время не существует, кроме нескольких сообщений в блоге (все они написаны для альфа-версий).