/// <summary> /// 當 Token 端點的要求與 "password" 的 "grant_type" 抵達時呼叫。 /// 這會在使用者直接提供名稱和密碼認證到用戶端應用程式的使用者介面時發生,且用戶端應用程式會使用其來取得 "access_token" 和選擇性的 "refresh_token"。 /// 若 Web 應用程式支援資源擁有者認證授與類型,其必須適當驗證 context.Username 和 context.Password。 若要簽發存取語彙基元,context.Validated 必須以新票證呼叫,此票證包括應該與存取票證相關的資源擁有者相關的宣告。 預設行為是要拒絕此授與類型。 /// 另請參閱 http://tools.ietf.org/html/rfc6749#section-4.30.2 /// </summary> /// <param name="context"></param> /// <returns></returns> public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { _logger.Information("SimpleAuthorizationServerProvider GrantResourceOwnerCredentials : 1"); var allowedOrigin = context.OwinContext.Get <string>("as:clientAllowedOrigin"); if (allowedOrigin == null) { allowedOrigin = "*"; } _logger.Information("SimpleAuthorizationServerProvider GrantResourceOwnerCredentials : 2"); //如果allowedOrigin被允許,則將允許來源加入Owin的context中,如果API來源不同的話則回應405狀態 context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin }); //檢查用戶名/密碼, string _userid = null; bool isPhoneNumberConfirmed; using (AuthBLL _auth = new AuthBLL()) { IdentityUser user = await _auth.FindUser(context.UserName, context.Password); if (user == null) { context.SetError("invalid_grant", Resource.AccountOrPasswordError, "461"); return; } _userid = user.Id; isPhoneNumberConfirmed = user.PhoneNumberConfirmed; } _logger.Information("SimpleAuthorizationServerProvider GrantResourceOwnerCredentials : 3"); bool resetpasswd = false; var findUser = await _aspnetUsersService.QueryUsersByIDAsync(_userid); resetpasswd = findUser.resetPW == null ? false : Convert.ToBoolean(findUser.resetPW); _logger.Debug("resetpasswd:" + resetpasswd); //如果帳密有效的則產生claims-包含ClientId和UserName等等ticket資訊 var identity = new ClaimsIdentity(context.Options.AuthenticationType); identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName)); identity.AddClaim(new Claim("sub", context.UserName)); identity.AddClaim(new Claim("role", "user")); var props = new AuthenticationProperties(new Dictionary <string, string> { { "as:client_id", (context.ClientId == null) ? string.Empty : context.ClientId }, { "userName", context.UserName }, { "resetPassword", resetpasswd.ToString() //帳號重設密碼登入(true/false) }, { "as:userId", _userid } }); #region 加進cookiesIdentity 及 Claim:PasswordHash 與 KeyNumber var userManager = context.OwinContext.GetUserManager <ApplicationUserManager>(); ApplicationUser applicationUser = await userManager.FindAsync(context.UserName, context.Password); ClaimsIdentity cookiesIdentity = await applicationUser.GenerateUserIdentityAsync(userManager, CookieAuthenticationDefaults.AuthenticationType); identity.AddClaim(new Claim("PasswordHash", applicationUser.PasswordHash)); string keyNumber = context.OwinContext.Get <string>("as:KeyNumber"); identity.AddClaim(new Claim("KeyNumber", keyNumber)); var ticket = new AuthenticationTicket(identity, props); context.Validated(ticket); context.Request.Context.Authentication.SignIn(cookiesIdentity); #endregion _logger.Information("SimpleAuthorizationServerProvider GrantResourceOwnerCredentials : END"); }