ManageController.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. using System;
  2. using System.Linq;
  3. using System.Threading.Tasks;
  4. using System.Web;
  5. using System.Web.Mvc;
  6. using Microsoft.AspNet.Identity;
  7. using Microsoft.AspNet.Identity.Owin;
  8. using Microsoft.Owin.Security;
  9. using Winsoft.GOV.XF.WX.Models;
  10. namespace Winsoft.GOV.XF.WX.Controllers
  11. {
  12. [Authorize]
  13. public class ManageController : Controller
  14. {
  15. private ApplicationSignInManager _signInManager;
  16. private ApplicationUserManager _userManager;
  17. public ManageController()
  18. {
  19. }
  20. public ManageController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
  21. {
  22. UserManager = userManager;
  23. SignInManager = signInManager;
  24. }
  25. public ApplicationSignInManager SignInManager
  26. {
  27. get
  28. {
  29. return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
  30. }
  31. private set
  32. {
  33. _signInManager = value;
  34. }
  35. }
  36. public ApplicationUserManager UserManager
  37. {
  38. get
  39. {
  40. return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
  41. }
  42. private set
  43. {
  44. _userManager = value;
  45. }
  46. }
  47. //
  48. // GET: /Manage/Index
  49. public async Task<ActionResult> Index(ManageMessageId? message)
  50. {
  51. ViewBag.StatusMessage =
  52. message == ManageMessageId.ChangePasswordSuccess ? "已更改你的密码。"
  53. : message == ManageMessageId.SetPasswordSuccess ? "已设置你的密码。"
  54. : message == ManageMessageId.SetTwoFactorSuccess ? "已设置你的双重身份验证提供程序。"
  55. : message == ManageMessageId.Error ? "出现错误。"
  56. : message == ManageMessageId.AddPhoneSuccess ? "已添加你的电话号码。"
  57. : message == ManageMessageId.RemovePhoneSuccess ? "已删除你的电话号码。"
  58. : "";
  59. var userId = User.Identity.GetUserId();
  60. var model = new IndexViewModel
  61. {
  62. HasPassword = HasPassword(),
  63. PhoneNumber = await UserManager.GetPhoneNumberAsync(userId),
  64. TwoFactor = await UserManager.GetTwoFactorEnabledAsync(userId),
  65. Logins = await UserManager.GetLoginsAsync(userId),
  66. BrowserRemembered = await AuthenticationManager.TwoFactorBrowserRememberedAsync(userId)
  67. };
  68. return View(model);
  69. }
  70. //
  71. // POST: /Manage/RemoveLogin
  72. [HttpPost]
  73. [ValidateAntiForgeryToken]
  74. public async Task<ActionResult> RemoveLogin(string loginProvider, string providerKey)
  75. {
  76. ManageMessageId? message;
  77. var result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey));
  78. if (result.Succeeded)
  79. {
  80. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  81. if (user != null)
  82. {
  83. await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
  84. }
  85. message = ManageMessageId.RemoveLoginSuccess;
  86. }
  87. else
  88. {
  89. message = ManageMessageId.Error;
  90. }
  91. return RedirectToAction("ManageLogins", new { Message = message });
  92. }
  93. //
  94. // GET: /Manage/AddPhoneNumber
  95. public ActionResult AddPhoneNumber()
  96. {
  97. return View();
  98. }
  99. //
  100. // POST: /Manage/AddPhoneNumber
  101. [HttpPost]
  102. [ValidateAntiForgeryToken]
  103. public async Task<ActionResult> AddPhoneNumber(AddPhoneNumberViewModel model)
  104. {
  105. if (!ModelState.IsValid)
  106. {
  107. return View(model);
  108. }
  109. // 生成令牌并发送该令牌
  110. var code = await UserManager.GenerateChangePhoneNumberTokenAsync(User.Identity.GetUserId(), model.Number);
  111. if (UserManager.SmsService != null)
  112. {
  113. var message = new IdentityMessage
  114. {
  115. Destination = model.Number,
  116. Body = "你的安全代码是: " + code
  117. };
  118. await UserManager.SmsService.SendAsync(message);
  119. }
  120. return RedirectToAction("VerifyPhoneNumber", new { PhoneNumber = model.Number });
  121. }
  122. //
  123. // POST: /Manage/EnableTwoFactorAuthentication
  124. [HttpPost]
  125. [ValidateAntiForgeryToken]
  126. public async Task<ActionResult> EnableTwoFactorAuthentication()
  127. {
  128. await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), true);
  129. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  130. if (user != null)
  131. {
  132. await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
  133. }
  134. return RedirectToAction("Index", "Manage");
  135. }
  136. //
  137. // POST: /Manage/DisableTwoFactorAuthentication
  138. [HttpPost]
  139. [ValidateAntiForgeryToken]
  140. public async Task<ActionResult> DisableTwoFactorAuthentication()
  141. {
  142. await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), false);
  143. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  144. if (user != null)
  145. {
  146. await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
  147. }
  148. return RedirectToAction("Index", "Manage");
  149. }
  150. //
  151. // GET: /Manage/VerifyPhoneNumber
  152. public async Task<ActionResult> VerifyPhoneNumber(string phoneNumber)
  153. {
  154. var code = await UserManager.GenerateChangePhoneNumberTokenAsync(User.Identity.GetUserId(), phoneNumber);
  155. // 通过 SMS 提供程序发送短信以验证电话号码
  156. return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber });
  157. }
  158. //
  159. // POST: /Manage/VerifyPhoneNumber
  160. [HttpPost]
  161. [ValidateAntiForgeryToken]
  162. public async Task<ActionResult> VerifyPhoneNumber(VerifyPhoneNumberViewModel model)
  163. {
  164. if (!ModelState.IsValid)
  165. {
  166. return View(model);
  167. }
  168. var result = await UserManager.ChangePhoneNumberAsync(User.Identity.GetUserId(), model.PhoneNumber, model.Code);
  169. if (result.Succeeded)
  170. {
  171. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  172. if (user != null)
  173. {
  174. await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
  175. }
  176. return RedirectToAction("Index", new { Message = ManageMessageId.AddPhoneSuccess });
  177. }
  178. // 如果我们进行到这一步时某个地方出错,则重新显示表单
  179. ModelState.AddModelError("", "无法验证电话号码");
  180. return View(model);
  181. }
  182. //
  183. // POST: /Manage/RemovePhoneNumber
  184. [HttpPost]
  185. [ValidateAntiForgeryToken]
  186. public async Task<ActionResult> RemovePhoneNumber()
  187. {
  188. var result = await UserManager.SetPhoneNumberAsync(User.Identity.GetUserId(), null);
  189. if (!result.Succeeded)
  190. {
  191. return RedirectToAction("Index", new { Message = ManageMessageId.Error });
  192. }
  193. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  194. if (user != null)
  195. {
  196. await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
  197. }
  198. return RedirectToAction("Index", new { Message = ManageMessageId.RemovePhoneSuccess });
  199. }
  200. //
  201. // GET: /Manage/ChangePassword
  202. public ActionResult ChangePassword()
  203. {
  204. return View();
  205. }
  206. //
  207. // POST: /Manage/ChangePassword
  208. [HttpPost]
  209. [ValidateAntiForgeryToken]
  210. public async Task<ActionResult> ChangePassword(ChangePasswordViewModel model)
  211. {
  212. if (!ModelState.IsValid)
  213. {
  214. return View(model);
  215. }
  216. var result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
  217. if (result.Succeeded)
  218. {
  219. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  220. if (user != null)
  221. {
  222. await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
  223. }
  224. return RedirectToAction("Index", new { Message = ManageMessageId.ChangePasswordSuccess });
  225. }
  226. AddErrors(result);
  227. return View(model);
  228. }
  229. //
  230. // GET: /Manage/SetPassword
  231. public ActionResult SetPassword()
  232. {
  233. return View();
  234. }
  235. //
  236. // POST: /Manage/SetPassword
  237. [HttpPost]
  238. [ValidateAntiForgeryToken]
  239. public async Task<ActionResult> SetPassword(SetPasswordViewModel model)
  240. {
  241. if (ModelState.IsValid)
  242. {
  243. var result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
  244. if (result.Succeeded)
  245. {
  246. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  247. if (user != null)
  248. {
  249. await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
  250. }
  251. return RedirectToAction("Index", new { Message = ManageMessageId.SetPasswordSuccess });
  252. }
  253. AddErrors(result);
  254. }
  255. // 如果我们进行到这一步时某个地方出错,则重新显示表单
  256. return View(model);
  257. }
  258. //
  259. // GET: /Manage/ManageLogins
  260. public async Task<ActionResult> ManageLogins(ManageMessageId? message)
  261. {
  262. ViewBag.StatusMessage =
  263. message == ManageMessageId.RemoveLoginSuccess ? "已删除外部登录名。"
  264. : message == ManageMessageId.Error ? "出现错误。"
  265. : "";
  266. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  267. if (user == null)
  268. {
  269. return View("Error");
  270. }
  271. var userLogins = await UserManager.GetLoginsAsync(User.Identity.GetUserId());
  272. var otherLogins = AuthenticationManager.GetExternalAuthenticationTypes().Where(auth => userLogins.All(ul => auth.AuthenticationType != ul.LoginProvider)).ToList();
  273. ViewBag.ShowRemoveButton = user.PasswordHash != null || userLogins.Count > 1;
  274. return View(new ManageLoginsViewModel
  275. {
  276. CurrentLogins = userLogins,
  277. OtherLogins = otherLogins
  278. });
  279. }
  280. //
  281. // POST: /Manage/LinkLogin
  282. [HttpPost]
  283. [ValidateAntiForgeryToken]
  284. public ActionResult LinkLogin(string provider)
  285. {
  286. // 请求重定向至外部登录提供程序,以链接当前用户的登录名
  287. return new AccountController.ChallengeResult(provider, Url.Action("LinkLoginCallback", "Manage"), User.Identity.GetUserId());
  288. }
  289. //
  290. // GET: /Manage/LinkLoginCallback
  291. public async Task<ActionResult> LinkLoginCallback()
  292. {
  293. var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId());
  294. if (loginInfo == null)
  295. {
  296. return RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error });
  297. }
  298. var result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login);
  299. return result.Succeeded ? RedirectToAction("ManageLogins") : RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error });
  300. }
  301. protected override void Dispose(bool disposing)
  302. {
  303. if (disposing && _userManager != null)
  304. {
  305. _userManager.Dispose();
  306. _userManager = null;
  307. }
  308. base.Dispose(disposing);
  309. }
  310. #region 帮助程序
  311. // 用于在添加外部登录名时提供 XSRF 保护
  312. private const string XsrfKey = "XsrfId";
  313. private IAuthenticationManager AuthenticationManager
  314. {
  315. get
  316. {
  317. return HttpContext.GetOwinContext().Authentication;
  318. }
  319. }
  320. private void AddErrors(IdentityResult result)
  321. {
  322. foreach (var error in result.Errors)
  323. {
  324. ModelState.AddModelError("", error);
  325. }
  326. }
  327. private bool HasPassword()
  328. {
  329. var user = UserManager.FindById(User.Identity.GetUserId());
  330. if (user != null)
  331. {
  332. return user.PasswordHash != null;
  333. }
  334. return false;
  335. }
  336. private bool HasPhoneNumber()
  337. {
  338. var user = UserManager.FindById(User.Identity.GetUserId());
  339. if (user != null)
  340. {
  341. return user.PhoneNumber != null;
  342. }
  343. return false;
  344. }
  345. public enum ManageMessageId
  346. {
  347. AddPhoneSuccess,
  348. ChangePasswordSuccess,
  349. SetTwoFactorSuccess,
  350. SetPasswordSuccess,
  351. RemoveLoginSuccess,
  352. RemovePhoneSuccess,
  353. Error
  354. }
  355. #endregion
  356. }
  357. }