UWInfo Blog
發表新文章
[Join] | [忘記密碼] | [Login]
搜尋

搜尋意見
文章分類-#Author#
[所有文章分類]
所有文章分類
  • ASP.NET (48)
  • ASP.NET2.0 (15)
  • ASP.NET4.0 (34)
  • JavaScript (49)
  • jQuery (26)
  • FireFox (4)
  • UW系統設定 (3)
  • SQL (39)
  • SQL 2008 (25)
  • mirror (4)
  • SVN (4)
  • IE (9)
  • IIS (20)
  • IIS6 (1)
  • 閒聊 (7)
  • W3C (6)
  • 作業系統 (9)
  • C# (24)
  • CSS (12)
  • FileServer (1)
  • HTML 5 (11)
  • CKEditor (3)
  • UW.dll (13)
  • Visual Studio (16)
  • Browser (8)
  • SEO (1)
  • Google Apps (3)
  • 網站輔助系統 (4)
  • DNS (5)
  • SMTP (4)
  • 網管 (11)
  • 社群API (3)
  • SSL (4)
  • App_Inventor (1)
  • URLRewrite (2)
  • 開發工具 (6)
  • JSON (1)
  • Excel2007 (1)
  • 試題 (3)
  • LINQ (1)
  • bootstrap (0)
  • Vue (3)
  • IIS7 (3)
  • foodpanda (2)
  • 編碼 (2)
  • 資安 (3)
  • Sourcetree (1)
  • MAUI (1)
  • CMD (1)
  • my sql (1)
最新回應
  • Newtonsoft.Json.JsonConvert.DeserializeObject 失敗的情況
    test...more
  • dotnet ef dbcontext scaffold
    ...more
  • [ASP.NET] 利用 aspnet_regiis 加密 web.config
    ...more
  • IIS ARR (reverse proxy) 服務安裝
    ...more
  • [錯誤訊息] 請加入 ScriptResourceMapping 命名的 jquery (區分大小寫)
    ...more
  • 用 Javascript 跨網頁讀取 cookie (Cookie cross page, path of cookie)
    ...more
  • 線上客服 - MSN
    本人信箱被盜用以致資料外洩,是否可以請貴平台予以協助刪除該信箱之使用謝謝囉...more
  • 插入文字到游標或選取處
    aaaaa...more
  • IIS 配合 AD (Active Directory) 認証, 使用 .Net 6.0
    太感謝你了~~~你救了我被windows 認證卡了好幾天QQ...more
  • PostgreSQL 的 monitor trigger
    FOR EACH ROW 可能要改為 FOR EACH STATEMENT ...more
標籤
  • 不允許儲存
  • DxHizbmA
  • List.where
  • load
  • 網路名稱
  • javascript
  • eqO9Cn4f
  • client,
  • [t],
  • 1637
  • sql 變更
  • 15
  • �
  • server
  • SQL 授權
  • UserHostAd
  • 備份21211211
  • iis7 的設定匯
  • 找到的組件資訊清單定
  • SNMP
  • C
  • 日期
  • 376
  • 7082121121
  • drop
  • canvas
  • UwQOHbcP
  • 不允許使用預設的參數
  • 定義
  • 612
  • library
  • 636
  • 8473
  • windows
  • validation
  • for 212112
  • qGhEOvLk
  • 744
  • Lucene.Net
  • 88 order b
  • SQL
  • 348
  • images
  • 夢想家
  • lazyload
  • FB3
  • images2121
  • COLUMNS_UP
  • ARR
  • 248
頁數 2 / 11 上一頁 下一頁
搜尋 server 結果:
資安問題 -- ServerVariables
var ip =  HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

return Content("發生錯誤, 請連絡系統管理員. 並告知您的 IP 是: " + ip + ".");
More...
Bike, 2022/9/22 下午 03:07:01
IIS 讓網站 .svn 目錄不被讀取
若網站是使用 SVN update 方式更新網站,為了防止被外部讀取到 /.svn/  目錄內容
要在 web.config 片段加上以下內容

<configuration>
<system.webServer>
     <security>
         <requestFiltering>
            <hiddenSegments>
             <add segment=".svn" />
            </hiddenSegments>
         </requestFiltering>
     </security>
</system.webServer>
</configuration>


git 也是一樣的方式
可以參考此網址
https://www.petefreitag.com/item/823.cfm
 
More...
darren, 2022/7/20 下午 04:58:58
.Net Framework 的檔案檢查機制 Web API 和 MVC 5
我們的目標是在啟動時,掛一個 global filter 來檢查上傳的檔案附檔名,避免上傳未預期的可執行檔。使用 global filter 可以防止程式設計師忘了做檔案檢查,發生危險。我們目前用到的 .Net Framework 有兩個類別,一個是 System.Web.Http.ApiController,另一個是 System.Web.Mvc.Controller,兩個要分開處理。

1. Web API (System.Web.Http.ApiController)
.Net Framework 的 Web API 2 在接收檔案時,必需使用 Request.Content.ReadAsMultipartAsync 把上傳的資料存入 MultipartMemoryStreamProvider 之後再來處理。
範例如下: 
    public class UploadController : ApiController
    {
        public async Task<object> PostFormData()
        {
            var provider = new MultipartMemoryStreamProvider();

            if (! Request.Content.IsMimeMultipartContent())
            {
                return "no file";
            }

            //要注意這裡的 await
            await Request.Content.ReadAsMultipartAsync(provider);

            foreach (var content in provider.Contents)
            {
                if (content.Headers.ContentDisposition.FileName != null)
                {
                    string localFilename = content.Headers.ContentDisposition.FileName.Replace("\"", "");
                    System.IO.Directory.CreateDirectory(HttpContext.Current.Server.MapPath(@"~/App_Data/Temp/"));
                    string filename = HttpContext.Current.Server.MapPath(@"~/App_Data/Temp/" + localFilename);
                    if (System.IO.File.Exists(filename))
                    {
                        System.IO.File.Delete(filename);
                    }

                    using (var fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write))
                    {
                        var contentStream = await content.ReadAsStreamAsync();
                        await contentStream.CopyToAsync(fileStream);
                        Trace.WriteLine("Save To" + filename);
                    }
                }
            }
            return "OK";
        }
    }


程式碼中有個地方我沒有注意到。我一開始是用 Request.Content.ReadAsMultipartAsync(provider); 把資料讀進 provider,但前方沒有加上 await,造成有時讀不到檔案的情況,再次提醒自己 Async 和 Await 的關係。

直覺的想法是在 filter 中執行一樣的程式碼,不存檔,只要抓出檔名來檢查即可。但這時遇到一個問題 Request.Content.ReadAsMultipartAsync 不能執行兩次,Google 了一陣子,也沒找不到類似 seek(0) 的操作。所以只好自己寫一個暫存的機製。

這裡決定使用 System.Web.HttpContext.Current.Items 來暫存 provider,最後的 OnActionExecutingAsync 結果如下:

        /// <summary>
        /// 檔案檢查
        /// </summary>
        /// <param name="actionContext"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public override async Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
        {
            Trace.WriteLine("ApiCheckFile OnActionExecutingAsync");

            var request = actionContext.Request;
            if (!request.Content.IsMimeMultipartContent())
            {
                return;
            }

            var provider = new MultipartMemoryStreamProvider();
            await request.Content.ReadAsMultipartAsync(provider);

            //把 provider 存入 System.Web.HttpContext.Current.Items 之中,以便在 controller 中再度使用
            System.Web.HttpContext.Current.Items["MimeMultipartContentProvider"] = provider;

            foreach (var content in provider.Contents)
            {
                if (content.Headers.ContentDisposition.FileName != null)
                {
                    var filename = content.Headers.ContentDisposition.FileName.Replace("\"", "");
                    Trace.WriteLine(filename);

                    var ext = System.IO.Path.GetExtension(filename);
                    if (!".jpg,.jpeg,.png".Contains(ext.ToLower()))
                    {
                        throw new Exception("file format error.");
                    }
                }
            }

            return;
        }


而 controller 中的 Action 則改為以下的版本;本版本中,除了把上傳的檔案存檔以外,還有讀取 form data 中其它欄位的範例:

        public async Task<object> PostFormData()
        {
            //改由 HttpContext.Current.Items 中,讀取資料。
            MultipartMemoryStreamProvider provider = (MultipartMemoryStreamProvider)System.Web.HttpContext.Current.Items["MimeMultipartContentProvider"];

            //如果沒有經過 filter,provider會是 null, 這時就要直接由 Request.Content 讀入 provider
            if (provider == null)
            {
                provider = new MultipartMemoryStreamProvider();
                Request.Content.ReadAsMultipartAsync(provider);
            }

            foreach (var content in provider.Contents)
            {
                if (content.Headers.ContentDisposition.FileName != null)
                {
                    string localFilename = content.Headers.ContentDisposition.FileName.Replace("\"", "");
                    Trace.WriteLine("FileName: " + localFilename);
                    Trace.WriteLine("FileName: " + @"~/App_Data/Temp/" + localFilename);
                    System.IO.Directory.CreateDirectory(HttpContext.Current.Server.MapPath(@"~/App_Data/Temp/"));
                    string filename = HttpContext.Current.Server.MapPath(@"~/App_Data/Temp/" + localFilename);
                    if (System.IO.File.Exists(filename))
                    {
                        System.IO.File.Delete(filename);
                    }

                    using (var fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write))
                    {
                        var contentStream = await content.ReadAsStreamAsync();
                        await contentStream.CopyToAsync(fileStream);
                        Trace.WriteLine("Save To" + filename);
                    }
                }
                else
                {
                    var contentStream = await content.ReadAsStreamAsync();
                    var reader = new System.IO.StreamReader(contentStream);
                    var data = reader.ReadToEnd();
                    Trace.WriteLine("data: " + data);
                }
            }
            return "OK";
        }


以上是展示 Web Api 的 Filter。

如果是 MVC 的 Controller,就簡單多了,直接讀取 actionContext.HttpContext.Request.Files 裡面各檔案的 FileName 即可。不過也遇到了一個和直覺不同的地方,對 actionContext.HttpContext.Request.Files 居然不能用 foreach 請見下方註解掉的地方。也許是我的用法有問題,如果有人找到可以使用的方法也麻煩告知。

        public override void OnActionExecuting(ActionExecutingContext actionContext)
        {
            Debug.WriteLine("MvcCheckFileFilter OnActionExecuting");
            if (actionContext.HttpContext.Request.Files.Count > 0)
            {
                for (int i = 0; i < actionContext.HttpContext.Request.Files.Count; i++)
                {
                    System.Web.HttpPostedFileBase file = actionContext.HttpContext.Request.Files[i];
                    if (System.IO.Path.GetExtension(file.FileName) != ".jpg")
                    {
                        throw new Exception("file format error.");
                    }
                    Debug.WriteLine(i + "MvcCheckFileFilter OnActionExecuting File type: " + file.FileName.ToString());
                }
            }

            //以下寫法會發生錯誤: 無法將類型 'System.String' 的物件轉換為類型 'System.Web.HttpPostedFileBase'。
            //foreach (HttpPostedFileBase file in actionContext.HttpContext.Request.Files)
            //{
            //    if (System.IO.Path.GetExtension(file.FileName) != ".jpg")
            //    {
            //        throw new Exception("file format error.");
            //    }
            //}
        }


最後是把 filter 掛在 global filter 裡,如下:
Web API Controller 的部份:
在 WebApiConfig.cs 裡加上 config.Filters.Add(new ApiCheckFile()); 見下圖:
 

附帶一提,Register 是在 global.asax 裡被叫用的。微軟的架構常常這樣,硬是拉到另一個目錄的獨立檔案裡,如果 global.asax 沒有這一行,不知所以的人,在 App_Start 裡,建立了一個 WebApiConfig.cs 然後會發現完全沒做用... 見下圖

 
MVC Controller 的部份,
在 FilterConfig.cs 中,加上 filters.Add(new MvcCheckFileFilter()); 如下圖
 

一樣是在 global.asax 中呼叫  FilterConfig.RegisterGlobalFilters,見下圖:

 
不過有趣的地方是,在 global.asax 裡, WebApiConfig.Register 和 FilterConfig.RegisterGlobalFilters 的叫用方法不同,一個是把 function 當作變數,一個是直接呼叫 function, 大家可以比較一下。

附註 1, 關於 OnActionExecutingAsync 和 OnActionExecuting:

Web API 的 filter 中,提供了 OnActionExecutingAsync 和 OnActionExecuting 兩個 method 可以 override ,我實驗的結果是如果兩個 method 都 override 了,只有 OnActionExecutingAsync 會被呼叫。

MVC 的 filter 中,只有 OnActionExecuting 可以 override。
 
More...
Bike, 2022/5/15 上午 10:01:11
快速設定 SSL 協定的工具
文章參考: https://windowsreport.com/windows-server-enable-tls/

工具下載: https://www.nartac.com/Products/IISCrypto/Download
More...
Bike, 2022/5/5 下午 10:32:11
無法把主機加入 Active Directory, SRV 記錄的問題
第一步,把 PC 加入 AD

在嘗試把 PC110 加入 Active Directory 時,發生了找不到 SRV 記錄的問題。

最後發現是因為在 AD 的 DNS Server 中沒有 _msdcs 這個網域.

所以手動建立 _msdcs.shop.eva 這個網域 (記得要允許安全的動態更新),並且讓 AD 重新建立相對應的記錄。

建立網域後,執行以下的指令
ipconfig/flushdns
ipconfig/registerdns
net stop netlogon
net start netlogon

可以參考以下文件
https://polinwei.com/dns-recreate-_msdcs/
More...
Bike, 2022/3/21 下午 03:55:44
IIS 配合 AD (Active Directory) 認証, 使用 .Net 6.0
環境說明:

AD Server: dc1 (192.168.101.109)
PC: pc110 (192.168.101.110)
PC: pc111 (192.168.101.111)

第一步,把 PC 加入 AD, 這個算是基本操作,網路上說明很多, 就不再截圖了。不過在這裡還是遇到了第一個問題,解決過程請參考另一份文件: https://blog.uwinfo.com.tw/Article.aspx?Id=486

第二步,在 Visual Studio 的測試環境中測試:
一開始是使用 .Net 6.0 來實作,沒想到找到的文件都是 .Net Core 3.1 的,所以先用 .Net Core 3.1 實做了一次,後來改用 .Net 6.0 實作才成功。使用 .Net 6.0 實作的過程如下:

1. 建立一個 MVC 的標準專案: 
 
為了避免憑証問題,所以拿掉了 HTTPS 的設定


2. 改寫 launchSettings.json:
iisSettings 中的 windowsAuthentication 改為 True, anonymousAuthentication 改為 false。如下圖:
 
3. 修改 Program.cs, 加入以下四行指令:
builder.Services.AddAuthentication(IISDefaults.AuthenticationScheme);
builder.Services.AddAuthorization();
app.UseAuthentication();
app.UseAuthorization();
(注意: UseAuthentication 要加在 UseAuthentication 之後, VS 2022 應該會提示要新增 using Microsoft.AspNetCore.Server.IISIntegration;)
 
4. 在 HomeController 增加一個 Action, 以讀取驗証資料:

        [Route("GetAuthenticatedUser")]
        [HttpGet("[action]")]
        public IdentityUser GetUser()
        {
            return new IdentityUser()
            {
                Username = User.Identity?.Name,
                IsAuthenticated = User.Identity != null ? User.Identity.IsAuthenticated : false,
                AuthenticationType = User.Identity?.AuthenticationType
            };
        }

        public class IdentityUser
        {
            public string Username { get; set; }
            public bool IsAuthenticated { get; set; }
            public string AuthenticationType { get; set; }
        }
 
5. 啟動時記得要改用 IIS Express (感覺早上花了兩三個小時在為了這個問題打轉):


6. 執行結果:

第三步,在 IIS 中安裝網站:
1. 在安裝 IIS 時,記得要勾選 windows 驗證


2. 安裝 .Net 6.0 的 Hosting Bundle
https://dotnet.microsoft.com/en-us/download/dotnet/6.0
 
3. 新增網站:
主機名稱留空白 (AD 驗証在網域內好像不會使用指定的主機名稱,這個有待後續再做確認)


如果沒有刪除預設網站,會遇到警告,直接確認即可.


要把 Default Web Site 關閉,再啟動測試站
 
要啟動 windows 驗証: 
在 web.config 中增加 
      <security>
        <authentication>
          <anonymousAuthentication enabled="false" />
          <windowsAuthentication enabled="true" />
        </authentication>
      </security>



修改 applicationHost.config:

檔案位置: %windir%\system32\inetsrv\config\applicationHost.config
這兩地方的 Deny 改為 Allow
<section name="anonymousAuthentication" overrideModeDefault="Deny" />
<section name="windowsAuthentication" overrideModeDefault="Deny" />

 
參考文件: https://docs.microsoft.com/zh-tw/iis/get-started/planning-for-security/how-to-use-locking-in-iis-configuration

3. 可以取得登入資訊如下:

4. 從 Domain 中另一台主機來存取,不用登入,自動取得目前登入者的資訊。
 
5. 從非網域主機連線: 會要求認証
 

目前遇到問題: 在網域中的電腦只能用主機名稱登入,非網域的電腦,才能夠使用網址登入。

測試專案下載: https://github.com/bikehsu/AD60
 
More...
Bike, 2022/3/19 下午 09:10:08
使用 Gmail 發送信件 -- 待補
https://blog.no2don.com/2021/01/c-gmail-smtp-server-requires-secure.html
More...
Bike, 2022/2/12 下午 09:16:02
Blog 待修改項目
1. 建立 API Server
     .Net 6.0
     .Cross Site
     .無 Session
     .評分機制

2. 前端修改
    . 改寫內容頁及編輯頁
    . 使用 Vue 及 API
    . 增加評分功能
    . 上傳圖片問題處理
    . 搜尋改用 Google Site Sarch

 
More...
Bike, 2022/1/11 下午 12:05:09
匯出 let's encryption的憑証
https://www.alitajran.com/export-lets-encrypt-certificate-in-windows-server/

private 憑証所在位置:
C:\ProgramData\win-acme\acme-v02.api.letsencrypt.org\Certificates

憑証要安裝在"本機", 並記得允許匯出

Select A to manage renewals
Select D to show the renewal details
 
More...
Bike, 2021/12/20 上午 01:47:40
CORS 實做 (jQuery + ASP.NET Core Web API)
加構獨立的 API Server 時, 要使用 Cookie 認証必需有以下條件:

1. Web Server 和 API Server 有相同的父網域.
2. Cookie 的網域指定到相同的父網域.
3. 在 API 的 Application 中允許 CORS Request, 需要修改 Startup.cs

3.1 在 ConfigureServices 中要加入  AddCors, 而且要記得 AllowCredentials()
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddPolicy(name: "Cors(PolicyName",
                                 builder =>
                                 {
                                     builder.WithOrigins("https://web1.yourdomain.com",
                                                         "https://web2.yourdomain.com")
                                     .AllowCredentials();
                                 });
            });

            services.AddControllers()
                .AddNewtonsoftJson(opt =>
                 opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver());


3.2 在 Configure 中, 要加入 app.UseCors("Cors(PolicyName"), 記得要在  UseAuthorization() 之前.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseExceptionMiddleware();

            app.UseHttpsRedirection();

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseCors(MyAllowSpecificOrigins);

            app.UseAuthorization();



4. 在 Client 端要加上 withCredentials: true
                            $.ajax({
                                url: apiRoot + "apiurl",
                                type: 'GET',
                                dataType: 'json', // 預期從server接收的資料型態
                                success: function (res) {
                                    console.log("success: ");
                                    console.log(res);                                    
                                },
                                xhrFields: {
                                    withCredentials: true
                                },
                                error: function (XMLHttpRequest, textStatus, errorThrown) {
                                    alert("發生錯誤");
                                }
                            });
More...
Bike, 2021/10/24 下午 05:17:54
|< 12345678910… >|
頁數 2 / 11 上一頁 下一頁
~ Uwinfo ~