2015-10-27 20 views
1

与播放框架+剪影一个成功的谷歌的Web登录后,我希望能够有一个Ajax请求访问。 This answer说,使用2个控制器机智2个环境。Web和移动AOuth2与剪影

Environment[User, SessionAuthenticator] 
Environment[User, JWTAuthenticator] 
  1. 我如何“链接”网络身份验证(SessionAuthenticator)与其他部件使用了JWTAuthenticator
  2. Ajax客户端可以使用数据会话cookie来构建JWT头(怎么) ?

回答

0
Implement aouth2 with User define tables. 
public partial class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     ConfigureAuth(app); 
     app.MapSignalR(); 

     HttpConfiguration config = new HttpConfiguration(); 
     WebApiConfig.Register(config); 
     app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 
     app.UseWebApi(config); 
    } 
} 
call startup class 
ConfigureOAuth(app); 
    public void ConfigureOAuth(IAppBuilder app) 
    { 
     OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() 
     { 
      AllowInsecureHttp = true, 
      TokenEndpointPath = new PathString("/token"), 
      AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), 
      Provider = new SimpleAuthorizationServerProvider(), 
      RefreshTokenProvider = new SimpleRefreshTokenProvider() 
     }; 

     // Token Generation 
     app.UseOAuthAuthorizationServer(OAuthServerOptions); 
     app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); 

    } 
Provider ----- 
    public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider 
{ 
    public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 
    { 
     context.Validated(); 
    } 

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
    { 

     context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); 

     using (AuthRepository _repo = new AuthRepository()) 
     { 
      var user = await _repo.FindUser(context.UserName, context.Password); 

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



     //ClaimsIdentity oAuthIdentity = await _repo.CreateIdentityAsync(user, 
     //  context.Options.AuthenticationType); 
     //ClaimsIdentity cookiesIdentity = await _repo.CreateIdentityAsync(user, 
     // CookieAuthenticationDefaults.AuthenticationType); 
     //AuthenticationProperties properties = CreateProperties(user.UserName); 
     //AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties); 
     //context.Validated(ticket); 
     //context.Request.Context.Authentication.SignIn(cookiesIdentity); 
} 
      var identity = new ClaimsIdentity(context.Options.AuthenticationType); 
     identity.AddClaim(new Claim("sub", context.UserName)); 
     identity.AddClaim(new Claim("role", "user")); 

     context.Validated(identity); 

    } 

    public override async Task GrantRefreshToken(OAuthGrantRefreshTokenContext context) 

    { 
     var originalClient = context.Ticket.Properties.Dictionary["as:client_id"]; 
     var currentClient = context.OwinContext.Get<string>("as:client_id"); 

     // enforce client binding of refresh token 
     if (originalClient != currentClient) 
     { 
      context.Rejected(); 
      return; 
     } 

     // chance to change authentication ticket for refresh token requests 
     var newId = new ClaimsIdentity(context.Ticket.Identity); 
     newId.AddClaim(new Claim("newClaim", "refreshToken")); 

     var newTicket = new AuthenticationTicket(newId, context.Ticket.Properties); 
     context.Validated(newTicket); 
    } 
} 

public class SimpleRefreshTokenProvider : IAuthenticationTokenProvider 
{ 
    private static ConcurrentDictionary<string, AuthenticationTicket> _refreshTokens = new ConcurrentDictionary<string, AuthenticationTicket>(); 


    public async Task CreateAsync(AuthenticationTokenCreateContext context) 
    { 
     var guid = Guid.NewGuid().ToString(); 

     // maybe only create a handle the first time, then re-use 
     _refreshTokens.TryAdd(guid, context.Ticket); 

     // consider storing only the hash of the handle 
     context.SetToken(guid); 
    } 

    public async Task ReceiveAsync(AuthenticationTokenReceiveContext context) 
    { 
     AuthenticationTicket ticket; 
     if (_refreshTokens.TryRemove(context.Token, out ticket)) 
     { 
      context.SetTicket(ticket); 
     } 
    } 

    public void Create(AuthenticationTokenCreateContext context) 
    { 
     var guid = Guid.NewGuid().ToString(); 

     // maybe only create a handle the first time, then re-use 
     _refreshTokens.TryAdd(guid, context.Ticket); 

     // consider storing only the hash of the handle 
     context.SetToken(guid); 
    } 

    public void Receive(AuthenticationTokenReceiveContext context) 
    { 
     AuthenticationTicket ticket; 
     if (_refreshTokens.TryRemove(context.Token, out ticket)) 
     { 
      context.SetTicket(ticket); 
     } 
    } 
} 
Repo------------- 
    public class UserManagerService : UserManager<User>, IUserManagerService<User> 
{ 

    public UserManagerService(IUserStore<User> userStore) 
     : base(userStore) 
    { 
     this.UserValidator = new UserValidator<User>(this) { AllowOnlyAlphanumericUserNames = false }; 
    } 

    public new IUserStore<User> Store 
    { 
     get { return base.Store; } 
    } 


} 


    public class AuthRepository : IDisposable 
    { 
    private AuthContext _ctx; 

    private UserManager<User> _userManager; 

    public AuthRepository() 
    { 
     _ctx = new AuthContext(); 
     _userManager = new UserManager<User>(new UserStore<User>(_ctx)); 
    } 
    //public async Task<IdentityResult> RegisterUser(UserModel userModel) 
    //{ 
    // IdentityUser user = new IdentityUser 
    // { 
    //  UserName = userModel.UserName 
    // }; 

    // var result = await _userManager.CreateAsync(user, userModel.Password); 

    // return result; 
    //} 

    public async Task<User> FindUser(string userName, string password) 
    { 
     User user = await _userManager.FindAsync(userName, password); 

     return user; 
    } 

    public void Dispose() 
    { 
     _ctx.Dispose(); 
     _userManager.Dispose(); 

    } 
    } 


    public class AuthContext : DbContext 
{ 
    public AuthContext() 
     : base("ObjectContext") 
    { 
    } 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 

     modelBuilder.Entity<IdentityRole>().HasKey<string>(i => i.Id).ToTable("Roles"); 
     modelBuilder.Entity<IdentityUser>().HasKey<string>(i => i.Id).ToTable("Users"); 
     modelBuilder.Entity<User>().HasKey<string>(i => i.Id).ToTable("Users"); 
     modelBuilder.Entity<IdentityUserClaim>().HasKey<int>(i => i.Id).ToTable("UserClaims"); 
     modelBuilder.Entity<IdentityUserLogin>().HasKey(q => new { q.LoginProvider, q.UserId, q.ProviderKey }).ToTable("UserLogins"); 
     modelBuilder.Entity<IdentityUserRole>().HasKey(q => new { q.RoleId, q.UserId }).ToTable("UserRoles"); 

     base.OnModelCreating(modelBuilder); 

    } 
} 
+1

剪影和发挥都斯卡拉(或Java)解决方案。你的代码提醒我C#。是这样吗? – ozma

0

这不是一个完整的技术解决方案,但这些都是我的见解:

  1. 有可能在“登录响应”同时嵌入的cookie会话和X-验证令牌。它们被放置在不同名称的标题上。
  2. 为了同时生成您需要登录控制器上的2相关的“环境” S。
  3. 登录客户端将有两种饼干(无论成本),但后来受保护的请求SilhouetteController只能处理一种类型的每个控制器权威性的(用“com.mohiva” %%“玩剪影”%“2.0”之后我认为它在3.0剪影改变)