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.

116 lines
5.0 KiB

2 years ago
  1. using Microsoft.Identity.Client;
  2. using Microsoft.IdentityModel.Protocols.OpenIdConnect;
  3. using Microsoft.IdentityModel.Tokens;
  4. using Microsoft.Owin;
  5. using Microsoft.Owin.Security;
  6. using Microsoft.Owin.Security.Cookies;
  7. using Microsoft.Owin.Security.Notifications;
  8. using Microsoft.Owin.Security.OpenIdConnect;
  9. using Owin;
  10. using System;
  11. using System.IdentityModel.Claims;
  12. using System.Net;
  13. using System.Net.Security;
  14. using System.Threading.Tasks;
  15. using System.Web;
  16. using WebApp.Outlook;
  17. using WebApp.Outlook.TokenStorage;
  18. [assembly: OwinStartup(typeof(WebApp.Startup))]
  19. namespace WebApp
  20. {
  21. public partial class Startup
  22. {
  23. // Properties used to get and manage an access token.
  24. private string redirectUri = ServiceHelper.RedirectUri;
  25. private string appId = ServiceHelper.AppId;
  26. private string appPassword = ServiceHelper.AppSecret;
  27. private readonly string scopes = ServiceHelper.Scopes;
  28. public void Configuration(IAppBuilder app)
  29. {
  30. //憑證問題的網站出現遠端憑證是無效的錯誤問題,特定網站可以不檢查
  31. ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) =>
  32. {
  33. if (sslPolicyErrors == SslPolicyErrors.None)
  34. {
  35. return true;
  36. }
  37. var request = sender as HttpWebRequest;
  38. if (request != null)
  39. {
  40. var result = request.RequestUri.Host == "data.gcis.nat.gov.tw";
  41. return result;
  42. }
  43. return false;
  44. };
  45. //允许CORS跨域
  46. //app.UseCors(CorsOptions.AllowAll);
  47. app.MapSignalR();
  48. app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
  49. app.UseCookieAuthentication(new CookieAuthenticationOptions());
  50. app.UseOpenIdConnectAuthentication(
  51. new OpenIdConnectAuthenticationOptions
  52. {
  53. // The `Authority` represents the Microsoft v2.0 authentication and authorization
  54. // service. The `Scope` describes the permissions that your app will need. See https://azure.microsoft.com/documentation/articles/active-directory-v2-scopes/
  55. ClientId = appId,
  56. Authority = "https://login.microsoftonline.com/common/v2.0",
  57. Scope = "openid offline_access profile email " + scopes,
  58. RedirectUri = redirectUri,
  59. PostLogoutRedirectUri = redirectUri,
  60. TokenValidationParameters = new TokenValidationParameters
  61. {
  62. // For demo purposes only, see below
  63. ValidateIssuer = false
  64. },
  65. Notifications = new OpenIdConnectAuthenticationNotifications
  66. {
  67. AuthorizationCodeReceived = OnAuthorizationCodeReceivedAsync,
  68. AuthenticationFailed = OnAuthenticationFailedAsync
  69. }
  70. }
  71. );
  72. }
  73. private async Task OnAuthorizationCodeReceivedAsync(AuthorizationCodeReceivedNotification notification)
  74. {
  75. System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
  76. // Get the signed in user's id and create a token cache
  77. var signedInUserId = notification.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
  78. var tokenCache = new SessionTokenCache(
  79. signedInUserId, notification.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase).GetMsalCacheInstance();
  80. var cca = new ConfidentialClientApplication(appId, redirectUri, new ClientCredential(appPassword), tokenCache, null);
  81. try
  82. {
  83. var saScopes = scopes.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
  84. var result = await cca.AcquireTokenByAuthorizationCodeAsync(notification.Code, saScopes);
  85. }
  86. catch (MsalException ex)
  87. {
  88. var message = "AcquireTokenByAuthorizationCodeAsync threw an exception";
  89. var debug = ex.Message;
  90. notification.HandleResponse();
  91. notification.Response.Redirect("/Login/Error?message=" + message + "&debug=" + debug);
  92. }
  93. }
  94. private static Task OnAuthenticationFailedAsync(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
  95. {
  96. notification.HandleResponse();
  97. var redirect = "/Login/Error?message=" + notification.Exception.Message;
  98. if (notification.ProtocolMessage != null && !string.IsNullOrEmpty(notification.ProtocolMessage.ErrorDescription))
  99. {
  100. redirect += "&debug=" + notification.ProtocolMessage.ErrorDescription;
  101. }
  102. notification.Response.Redirect(redirect);
  103. return Task.FromResult(0);
  104. }
  105. }
  106. }