You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

387 lines
13 KiB

  1. using DefenseWeb.Helper;
  2. using DefenseWeb.Models;
  3. using Newtonsoft.Json;
  4. using Newtonsoft.Json.Linq;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.DirectoryServices;
  8. using System.DirectoryServices.AccountManagement;
  9. using System.Linq;
  10. using System.Web;
  11. using System.Web.Mvc;
  12. using System.Web.Security;
  13. namespace DefenseWeb.Controllers
  14. {
  15. [Authorize]
  16. public class AccountController : CustomControllerBase
  17. {
  18. List<adUrl> adUrl = new List<adUrl>()
  19. {
  20. new adUrl() { name = "台北", url = "192.168.6.128" },
  21. };
  22. //
  23. // GET: /Account/Login
  24. [OutputCache(Duration = 60)]
  25. [AllowAnonymous]
  26. public ActionResult Login(string returnUrl)
  27. {
  28. SelectList selectList = new SelectList(adUrl, "url", "name");
  29. ViewBag.adUrl = selectList;
  30. if (User.Identity.IsAuthenticated)
  31. {
  32. return RedirectToAction("Index", "Home");
  33. }
  34. ViewBag.ReturnUrl = returnUrl;
  35. return View();
  36. }
  37. //
  38. // POST: /Account/Login
  39. [HttpPost]
  40. [AllowAnonymous]
  41. [Obsolete]
  42. public ActionResult Login(LoginViewModel model, string returnUrl)
  43. {
  44. SelectList selectList = new SelectList(adUrl, "url", "name");
  45. string sMsg = null;
  46. int iDiffDay = 0;
  47. ViewBag.adUrl = selectList;
  48. if (!ModelState.IsValid)
  49. {
  50. return View(model);
  51. }
  52. #if DEBUG
  53. var result = IsValidationForAD(model.Domain, model.Username, model.Password, out sMsg, out iDiffDay);
  54. #else
  55. var result = IsValidationForAD(model.Domain, model.Username, model.Password ,out sMsg, out iDiffDay);
  56. #endif
  57. if (sMsg != null)
  58. {
  59. ModelState.AddModelError("", sMsg);
  60. return View(model);
  61. }
  62. if (result)
  63. {
  64. string url = new ConfigHelper().GetWebConfig("UserInfoUrl");
  65. var data = CallRemote(url, true);
  66. var obj = JObject.Parse(data);
  67. if (obj.GetValue("Success").ToObject<bool>() == true && obj["UserData"].Type == JTokenType.Null)
  68. {
  69. ModelState.AddModelError("", "找不到該員工資料/Cannot find this employee profile");
  70. return View(model);
  71. }
  72. else if (obj.GetValue("Success").ToObject<bool>() == false)
  73. {
  74. ModelState.AddModelError("", "伺服器發生問題,無法登入/Server problem, unable to log in");
  75. return View(model);
  76. }
  77. //檢查是否已填寫問卷
  78. url = new ConfigHelper().GetWebConfig("DepartureUrl");
  79. var departure_obj = JObject.Parse(CallRemote(url, true));
  80. if (departure_obj.GetValue("desc") != null && !string.IsNullOrEmpty(departure_obj.GetValue("desc").ToString()))
  81. {
  82. ModelState.AddModelError("", "伺服器發生問題,無法登入/Server problem, unable to log in");
  83. return View(model);
  84. }
  85. if (!departure_obj.GetValue("Success").ToObject<bool>())
  86. {
  87. ModelState.AddModelError("", "已離職人員/Terminated staff");
  88. return View(model);
  89. }
  90. //檢查是否已填寫問卷
  91. url = new ConfigHelper().GetWebConfig("ExistSurveyUrl");
  92. var survey_data = CallRemote(url, true);
  93. var survey_obj = JObject.Parse(survey_data);
  94. if (survey_obj.GetValue("desc") != null && !string.IsNullOrEmpty(survey_obj.GetValue("desc").ToString()))
  95. {
  96. ModelState.AddModelError("", "伺服器發生問題,無法登入/Server problem, unable to log in");
  97. return View(model);
  98. }
  99. if (!survey_obj.GetValue("Success").ToObject<bool>())
  100. {
  101. ModelState.AddModelError("", "今天已經填過問卷/Have completed the questionnaire today");
  102. return View(model);
  103. }
  104. obj["UserData"]["password"] = model.Password;
  105. obj["UserData"]["domain"] = model.Domain;
  106. obj["UserData"]["DiffDay"] = iDiffDay;
  107. FormsAuthentication.SetAuthCookie(model.Username, true, FormsAuthentication.FormsCookiePath);
  108. FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket
  109. (
  110. 1, model.Username, DateTime.Now, DateTime.Now.AddMinutes(15), false, obj["UserData"].ToString(), FormsAuthentication.FormsCookiePath);
  111. //將 Ticket 加密
  112. var encTicket = FormsAuthentication.Encrypt(authTicket);
  113. Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
  114. return RedirectToLocal(returnUrl);
  115. }
  116. else
  117. {
  118. ModelState.AddModelError("", "登入嘗試失試。");
  119. return View(model);
  120. }
  121. }
  122. public static class ADUserProperties
  123. {
  124. public const String OBJECTCLASS = "objectClass";
  125. public const String CONTAINERNAME = "cn";
  126. public const String LASTNAME = "sn";
  127. public const String COUNTRYNOTATION = "c";
  128. public const String CITY = "l";
  129. public const String STATE = "st";
  130. public const String TITLE = "title";
  131. public const String POSTALCODE = "postalCode";
  132. public const String PHYSICALDELIVERYOFFICENAME = "physicalDeliveryOfficeName";
  133. public const String FIRSTNAME = "givenName";
  134. public const String MIDDLENAME = "initials";
  135. public const String DISTINGUISHEDNAME = "distinguishedName";
  136. public const String INSTANCETYPE = "instanceType";
  137. public const String WHENCREATED = "whenCreated";
  138. public const String WHENCHANGED = "whenChanged";
  139. public const String DISPLAYNAME = "displayName";
  140. public const String USNCREATED = "uSNCreated";
  141. public const String MEMBEROF = "memberOf";
  142. public const String USNCHANGED = "uSNChanged";
  143. public const String COUNTRY = "co";
  144. public const String DEPARTMENT = "department";
  145. public const String COMPANY = "company";
  146. public const String PROXYADDRESSES = "proxyAddresses";
  147. public const String STREETADDRESS = "streetAddress";
  148. public const String DIRECTREPORTS = "directReports";
  149. public const String NAME = "name";
  150. public const String OBJECTGUID = "objectGUID";
  151. public const String USERACCOUNTCONTROL = "userAccountControl";
  152. public const String BADPWDCOUNT = "badPwdCount";
  153. public const String CODEPAGE = "codePage";
  154. public const String COUNTRYCODE = "countryCode";
  155. public const String BADPASSWORDTIME = "badPasswordTime";
  156. public const String LASTLOGOFF = "lastLogoff";
  157. public const String LASTLOGON = "lastLogon";
  158. public const String PWDLASTSET = "pwdLastSet";
  159. public const String PRIMARYGROUPID = "primaryGroupID";
  160. public const String OBJECTSID = "objectSid";
  161. public const String ADMINCOUNT = "adminCount";
  162. public const String ACCOUNTEXPIRES = "accountExpires";
  163. public const String LOGONCOUNT = "logonCount";
  164. public const String LOGINNAME = "sAMAccountName";
  165. public const String SAMACCOUNTTYPE = "sAMAccountType";
  166. public const String SHOWINADDRESSBOOK = "showInAddressBook";
  167. public const String LEGACYEXCHANGEDN = "legacyExchangeDN";
  168. public const String USERPRINCIPALNAME = "userPrincipalName";
  169. public const String EXTENSION = "ipPhone";
  170. public const String SERVICEPRINCIPALNAME = "servicePrincipalName";
  171. public const String OBJECTCATEGORY = "objectCategory";
  172. public const String DSCOREPROPAGATIONDATA = "dSCorePropagationData";
  173. public const String LASTLOGONTIMESTAMP = "lastLogonTimestamp";
  174. public const String EMAILADDRESS = "mail";
  175. public const String MANAGER = "manager";
  176. public const String MOBILE = "mobile";
  177. public const String PAGER = "pager";
  178. public const String FAX = "facsimileTelephoneNumber";
  179. public const String HOMEPHONE = "homePhone";
  180. public const String MSEXCHUSERACCOUNTCONTROL = "msExchUserAccountControl";
  181. public const String MDBUSEDEFAULTS = "mDBUseDefaults";
  182. public const String MSEXCHMAILBOXSECURITYDESCRIPTOR = "msExchMailboxSecurityDescriptor";
  183. public const String HOMEMDB = "homeMDB";
  184. public const String MSEXCHPOLICIESINCLUDED = "msExchPoliciesIncluded";
  185. public const String HOMEMTA = "homeMTA";
  186. public const String MSEXCHRECIPIENTTYPEDETAILS = "msExchRecipientTypeDetails";
  187. public const String MAILNICKNAME = "mailNickname";
  188. public const String MSEXCHHOMESERVERNAME = "msExchHomeServerName";
  189. public const String MSEXCHVERSION = "msExchVersion";
  190. public const String MSEXCHRECIPIENTDISPLAYTYPE = "msExchRecipientDisplayType";
  191. public const String MSEXCHMAILBOXGUID = "msExchMailboxGuid";
  192. public const String NTSECURITYDESCRIPTOR = "nTSecurityDescriptor";
  193. }
  194. private bool IsValidationForAD(string url, string Username, string Password, out string o_sMsg, out int i_diffDay)
  195. {
  196. o_sMsg = null;
  197. bool isSuccess = false;
  198. i_diffDay = 0;
  199. try
  200. {
  201. string srvr = url;
  202. srvr = "LDAP://" + srvr;
  203. PrincipalContext ctx = new PrincipalContext(ContextType.Domain, url, Username, Password);
  204. var user = UserPrincipal.FindByIdentity(ctx, Username);
  205. if (user != null)
  206. {
  207. DirectoryEntry entry = (DirectoryEntry)user.GetUnderlyingObject();
  208. List<string> lsPropName = (from x in typeof(ADUserProperties).GetFields()
  209. select x.GetValue(typeof(string)).ToString()).ToList();
  210. Dictionary<string, object> dicADInfo = new Dictionary<string, object>();
  211. foreach (string sPropName in lsPropName)
  212. {
  213. if (entry.Properties.Contains(sPropName))
  214. {
  215. dicADInfo.Add(sPropName, entry.Properties[sPropName].Value);
  216. }
  217. }
  218. var expiresDate = (DateTime)entry.InvokeGet("PasswordExpirationDate");
  219. i_diffDay = new TimeSpan(expiresDate.Ticks - DateTime.Now.Ticks).Days;
  220. isSuccess = true;//verify password is succeed!
  221. }
  222. }
  223. catch (DirectoryServicesCOMException ex)
  224. {
  225. if (ex.ExtendedErrorMessage.IndexOf("data 532,") > -1)
  226. {
  227. o_sMsg = @"您的AD 密碼已過期,請使用公司電腦設備到 eip.chipmos.com 網站更新密碼。<a href='http://eip.chipmos.com/' target='_blank'>eip.chipmos.com</a>
  228. Your AD password has expired. Please go to <a href='http://eip.chipmos.com/' target='_blank'>eip.chipmos.com</a> web site to change your password by using CHIPMOS computer equipment.";
  229. }
  230. else
  231. {
  232. o_sMsg = ex.Message;
  233. }
  234. Logger.Error(string.Format("sMsg={0},para={1} ex.StackTrace={2}, innerException={3} ", ex.Message, JsonConvert.SerializeObject(new { url = url, Username = Username, Password = Password, msg = ex.ExtendedErrorMessage }), ex.StackTrace, ex.InnerException));
  235. }
  236. return isSuccess;
  237. }
  238. private ActionResult RedirectToLocal(string returnUrl)
  239. {
  240. if (Url.IsLocalUrl(returnUrl))
  241. {
  242. return Redirect(returnUrl);
  243. }
  244. return RedirectToAction("Index", "Home");
  245. }
  246. //
  247. // POST: /Account/LogOff
  248. [HttpPost]
  249. [ValidateAntiForgeryToken]
  250. public ActionResult LogOff()
  251. {
  252. FormsAuthentication.SignOut();
  253. return RedirectToAction("Index", "Home");
  254. }
  255. public ActionResult GetUserData()
  256. {
  257. //todo
  258. return Content(CallRemote(""));
  259. }
  260. public ActionResult WriteUserData()
  261. {
  262. //todo
  263. // CallRemote("");
  264. return Content(CallRemote(""));
  265. }
  266. }
  267. }