來吧學學.Net Core之登錄認證與跨域資源使用


序言

學習core登錄認證與跨域資源共享是越不過的砍,所以我在學習中同樣也遇到啦這兩個問題,今天我們就用示例來演示下使用下這2個技術點吧.

本篇主要內容如下:

1、展示一個登錄認證的簡單示例

2、跨域資源訪問

3、跨域獲取登錄認證的用戶信息

.Net Core使用身份認證(Authentication,Identity)制作登錄認證功能

首先我們實現登錄這個功能,代碼如下

    [Authorize]
    public class AccountController : Controller
    {
        [HttpGet]
        [AllowAnonymous]
        public IActionResult Login(string returnUrl = null)
        {
            ViewData["ReturnUrl"] = returnUrl;
            if (this.User.Identity.IsAuthenticated)
            {
                return RedirectPermanent(returnUrl);
            }
            return View();
        }
        [HttpPost]
        [AllowAnonymous]
        public async Task<IActionResult> Login(string userName, string password,string returnUrl=null)
        {
            ViewData["ReturnUrl"] = returnUrl;          
            if (!string.IsNullOrEmpty(userName) && userName == password)
            {
                var claims = new List<Claim>(){
                              new Claim(ClaimTypes.Name,userName),new Claim("password",password),new Claim("realname","張龍豪")
                           };
                //init the identity instances 
                var userPrincipal = new ClaimsPrincipal(new ClaimsIdentity(claims, "Customer"));
                //signin 
                await HttpContext.Authentication.SignInAsync("CookieAuth", userPrincipal, new AuthenticationProperties
                {
                    ExpiresUtc = DateTime.UtcNow.AddMinutes(20),
                    IsPersistent = false,
                    AllowRefresh = false
                });
                return RedirectPermanent(returnUrl);
            }
            else
            {
                ViewBag.ErrMsg = "UserName or Password is invalid";
                return View();
            }
        }

前台代碼如下

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Login</title>
</head>
<body>
    <form asp-controller="Account" asp-action="Login" method="post" class="form-horizontal" asp-route-returnurl="@ViewData["ReturnUrl"]" role="form">
        <div class="form-group">
            <label class="col-md-2 control-label">UserName</label>
            <div class="col-md-10">
                <input type="text" name="username" />
            </div>
        </div>
        <div class="form-group">
            <label class="col-md-2 control-label">Password</label>
            <div class="col-md-10">
                <input type="password" name="password" />
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <button type="submit" class="btn btn-default">Log in</button>
            </div>
        </div>
    </form>
</body>
</html>

在Startup文件的Configure方法中加入下面代碼

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {          
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationScheme = "CookieAuth",   //認證方案:這是一個已知中間件的值,當有多個實例的中間件如果你想限制授權到一個實例時這個選項將會起作用。
                LoginPath = new PathString("/Account/Login"), //登錄路徑:這是當用戶試圖訪問資源但未經過身份驗證時,程序將會將請求重定向到這個相對路徑。
                AccessDeniedPath = new PathString("/Account/Forbidden"),  //禁止訪問路徑:當用戶試圖訪問資源時,但未通過該資源的任何授權策略,請求將被重定向到這個相對路徑。
                AutomaticAuthenticate = true,  //自動認證:這個標志表明中間件應該會在每個請求上進行驗證和重建他創建的序列化主體。                
                AutomaticChallenge = true,  //自動挑戰:這個標志標明當中間件認證失敗時應該重定向瀏覽器到登錄路徑或者禁止訪問路徑。
                SlidingExpiration = true,  //Cookie可以分為永久性的和臨時性的。 臨時性的是指只在當前瀏覽器進程里有效,瀏覽器一旦關閉就失效(被瀏覽器刪除)。 永久性的是指Cookie指定了一個過期時間,在這個時間到達之前,此cookie一直有效(瀏覽器一直記錄着此cookie的存在)。 slidingExpriation的作用是,指示瀏覽器把cookie作為永久性cookie存儲,但是會自動更改過期時間,以使用戶不會在登錄后並一直活動,但是一段時間后卻自動注銷。也就是說,你10點登錄了,服務器端設置的TimeOut為30分鍾,如果slidingExpriation為false,那么10:30以后,你就必須重新登錄。如果為true的話,你10:16分時打開了一個新頁面,服務器就會通知瀏覽器,把過期時間修改為10:46。 更詳細的說明還是參考MSDN的文檔。
                CookieHttpOnly = false  //默認為true
            });

好啦,你可以看到有[Authorize]屬性的方法或者控制器都需要登錄才能訪問,如果沒有登錄是不允許訪問的.

接下來你可能需要獲取當前登錄用戶的用戶信息,代碼如下:

        [HttpPost]
        public string GetCurrUserRealname()
        {
            var s = this.User.Identities.First(u => u.IsAuthenticated).FindFirst("realname").Value;
            var ss = this.User.Identity.Name;
            return ss + ":" + s;
        }
 $.post("/Account/GetCurrUserRealname", null, function (data) { $("#content").html(data); });

ok,這樣就能獲取到當前登錄的用戶信息

那如何退出呢?代碼如下:

        public async Task<JsonResult> Logout()
        {
            await HttpContext.Authentication.SignOutAsync("CookieAuth");
            return Json(new { data = "驗證方案:CookieAuth退出成功" });
        }

這樣看來完整的登錄驗證就完成啦,但是目前位置,我的代碼都還簡單的要命,只能初學者拿來入手,具體還有很多東西可以擴展.我們需要自己思考學習.

.Net Core跨域資源訪問

那這個跨域的環境呢,需要我們自己搞一下.怎么搞,如下

本地測試前期准備

1.首先我們搞兩個core的站點

 

2.本地host配置兩個域名,並在項目中做如下設置

hosts如下:

網站的launchSettings.json文件中配置項目CoreCorsATest為 "applicationUrl": "http://b.local.com:63455/",  項目AuthentiactionTest為 "applicationUrl": "http://a.local.com:50307/".

3. 實驗約定:

我們在項目AuthentiactionTest中寫接口,項目CoreCorsATest中調用AuthentiactionTest中的接口.

不做任何處理寫接口跨域調用

AuthentiactionTest中寫下如下接口

 public class HomeController : Controller
    {
        public string GetName()
        {
            return "張龍豪";
        }

CoreCorsATest中如下調用

$.post("http://a.local.com:50307/Home/GetName", null, function (data) { $("#content").html(data); });

結果如下:接口調用成功,但是跨域資源不允許使用

解決問題

設置跨域的域名

 public void ConfigureServices(IServiceCollection services)
        {
            //services.AddAuthorization();
            // Add framework services.
            services.AddMvc();
            services.AddCors(options => options.AddPolicy("AllowSameDomain", builder => builder.WithOrigins("http://a.local.com:50307", "http://b.local.com:63455")));
        }

下面的兩種調用方式

  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
           app.UseCors("AllowSameDomain");
 public class HomeController : Controller
    {
        [EnableCors("AllowSameDomain")]
        public string GetName()
        {
            return "張龍豪";
        }

.Net Core跨域訪問需要登錄認證的資源

這個問題就是上面跨域訪問的資源如果出現 [Authorize]特性,或者是訪問當前用戶的登錄信息,用剛才的方法是不行的.

登錄使用,上述的登錄功能,接口如下

        [HttpPost]
        public string GetCurrUserRealname()
        {
            var s = this.User.Identities.First(u => u.IsAuthenticated).FindFirst("realname").Value;
            var ss = this.User.Identity.Name;
            return ss + ":" + s;
        }

那在b.local.com 這個域名下怎么訪問才是有效的呢?

需要下面兩部操作

1.設置接口服務項目配置,如下操作

services.AddCors(options => options.AddPolicy("AllowSameDomain", builder => builder.WithOrigins("http://a.local.com:50307", "http://b.local.com:63455").AllowCredentials()));

2.ajax訪問接口時

 $.ajax({
            type: 'POST',
            url: "http://a.local.com:50307/Account/GetCurrUserRealname",
            data: null,
            dataType: "json",
            xhrFields: {
                withCredentials: true
            },
            success: function (result) {
                $("#message").html(result);
            }
        });

ok,這樣就可以訪問到當前登錄用戶的信息啦

總結

本篇呢,寫的都是用例,理論原理,沒有涉及,也有一些其他常用額擴展點,都沒有涉及到.

這里我只是把一些的點,貼出來,希望對想入手core的同學有所幫助.如有志同道合者,歡迎加左上方群,一起學習進步.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM