Membuat Custom Login Owin pada ASP.NET Web Form

Custom Login Owin pada ASP.NET Web Form

Tutorial ini merupakan pengembangan dari tutorial sebelumnya tentang cara membuat custom login pada ASP.NET MVC. Kali ini admin akan menerapkan teknik ini pada ASP.NET Web Form. Langkah-langkah yang dilakukan kurang lebih sama seperti tutorial sebelumnya. Hanya saja, terdapat sedikit perbedaan.

Pada ASP.NET Web Form, kita tidak dapat menambahkan atribut controller [Authorize] seperti halnya pada ASP.NET MVC. Sebagai gantinya kita dapat memakai teknik pemanggilan perintah User.Identity.IsAuthenticated untuk melakukan redirect ke halaman login.

Mengulas sedikit terkait artikel sebelumnya, pada dasarnya baik ASP.NET MVC maupun ASP.NET Web Form telah menyediakan service tersendiri untuk melakukan autentifikasi user pada aplikasi yang berjalan. Caranya yaitu pada saat membuat project baru kamu bisa ubah Authentification-nya menjadi Individual User Account atau yang lainnya. Lihat gambar dibawah.

ASP.NET Change Authentification

Maka secara otomatis table User seperti field username, password, dan field-field lainnya akan terbuat otomatis pada database, juga fungsi-fungsi lain seperti halaman registrasi user, halaman my profile, halaman login , ubah password, dan lain sebagainya yang berhubungan dengan aktivitas user.

Tapi seringkali kita memerlukan style tersendiri dalam membuat user account. Seperti penamaan table pada database, alur login, dan lain sebagainya. Karena secara default jika kita mengikuti langkah-langkah diatas, maka nama table tidak akan dapat diubah sesuai dengan kebutuhan karena harus mengikuti standar baku dari service yang ada.

ASP.NET menyediakan support terhadap middleware Open Web Interface for .NET atau disingkat OWIN. Owin memiliki banyak fitur diantaranya login menggunakan eksternal user akun seperti akun Microsoft, Google, Facebook dan sebagainya.

Dalam tutorial ini admin hanya akan membahas cara membuat custom login saja dengan menggunakan service dari Microsoft.Owin.

[ads id="ads1"] Tutorial dibawah ini menjelaskan langkah-langkah membuat custom login pada ASP.NET Web Form. Pada tutorial ini admin menggunakan Microsoft Visual Studio 2017 dan IIS Server 10, jadi mungkin akan berbeda bagi yang menggunakan versi Visual Studion dibawah 2017.

Dalam tutorial ini juga admin menggunakan service/library yang sama yang digunakan oleh ASP.NET untuk autentifikasi user yaitu Microsoft.Owin dan Microsoft.AspNet.Identity.

Berikut library yang dibutuhkan, Kalian bisa download langsung melalui menu Manage Nuget Packages pada Visual Studio :
  • Microsoft.Owin
  • Microsoft.Owin.Security
  • Microsoft.Owin.Security.Cookies
  • Microsoft.Owin.Security.OAuth
  • Microsoft.Owin.Host.SystemWeb
  • Microsoft.AspNet.Identity.Core
  • Microsoft.AspNet.Identity.Owin

Langkah-Langkah Pengerjaan

Buatlah sebuah project baru dengan nama "Custom Login".
Pilih Web Forms untuk pattern yang digunakan, dan Authentification : No Authentification.
Setelahnya, tambahkan library diatas melalui menu Manage Nuget Packages.

Create new project ASP.NET

Menu Manage NuGet Package

Startup.Auth.cs

Setelah selesai dengan langkah diatas, tambahkan class baru dengan nama Startup.Auth.cs pada direktori App_Start. Fungsinya adalah untuk konfigurasi awal Owin saat startup aplikasi/saat aplikasi pertama kali dijalankan.

Disini kalian bisa menambahkan session time/expire time, login url, dan sebagainya yang berguna untuk membuat batas expired login dan halaman login yang digunakan.

Owin Startup Attribute

Kode lengkapnya dapat dilihat dibawah :

Startup.Auth.cs
using Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.AspNet.Identity;

namespace Custom_Login
{
    public partial class Startup
    {
        public void ConfigureAuth(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("~/login.aspx")
            });

            app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
        }
    }
}

Konfigurasi Owin Startup (Startup.cs)

Lalu selanjutnya tambahkan lagi class baru dengan nama Startup.cs pada root directory aplikasi dengan menambahkan atribut assembly:OwinStartupAttribute() diatas namespace.

ASP.NET akan membaca file ini untuk pertama kali ketika aplikasi dijalankan, lalu selanjutnya akan mengeksekusi perintah ConfigureAuth().

Startup.cs
using Owin;
using Microsoft.Owin;

[assembly:OwinStartupAttribute(typeof(Custom_Login.Startup))]
namespace Custom_Login
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }
    }
}

Sampai pada langkah ini Owin telah dapat digunakan untuk autentifikasi User. Kalian dapat mencobanya dengan perintah mengetikkan perintah <%= User.Identity.IsAuthenticated %> pada Site.master atau halaman lainnya. Untuk user yang belum melakukan autentifikasi maka akan bernilai False.

Langkah selanjutnya adalah membuat beberapa model yang nantinya akan digunakan oleh Owin untuk menjalin komunikasi data dengan server dan sebagainya.

Membuat Model User

Model User digunakan sebagai identitas (data user) yang dibutuhkan oleh class UserManager (Microsoft.AspNet.Identity.UserManager) sebagai media autentifikasi ke dalam sistem.

Model User ini wajib mengikuti ketentuan yang digunakan oleh class UserManager yaitu memiliki field/property Id dan UserName. Kedua property ini tidak dapat diubah penamaannya.

Selanjutnya Model User ini harus diinheritkan kepada interface IUser (Microsoft.AspNet.Identity.IUser) sebagai syarat yang diberikan oleh UserManager untuk dapat melakukan autentifikasi user.

Buatlah sebuah folder baru dengan nama "Models" lalu buatlah class baru didalamnya dan beri nama UserModel.cs. Kode selengkapnya dapat dilihat dibawah :

UserModel.cs
using Microsoft.AspNet.Identity;
namespace Custom_Login.Models
{
    public class UserModel : IUser
    {
        public string Id { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
    }
}

Membuat CustomUserStore

Selanjutnya membuat class CustomUserStore, CustomUserStore digunakan UserManager untuk menangani User seperti membuat User, menghapus User, dan sebagainya yang berkaitan langsung dengan aktivitas UserManager.

Buatlah sebuah class baru didalam folder "Models" dan beri nama CustomUserStore.cs. Kode selengkapnya dapat dilihat dibawah :

CustomUserStore.cs
using Microsoft.AspNet.Identity;
using System;
using System.Threading.Tasks;

namespace Custom_Login.Models
{
    public class CustomUserStore<T> : IUserStore<T> where T : UserModel
    {
        public Task CreateAsync(T user)
        {
            throw new NotImplementedException();
        }

        public Task DeleteAsync(T user)
        {
            throw new NotImplementedException();
        }

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public Task<T> FindByIdAsync(string userId)
        {
            throw new NotImplementedException();
        }

        public Task<T> FindByNameAsync(string userName)
        {
            throw new NotImplementedException();
        }

        public Task UpdateAsync(T user)
        {
            throw new NotImplementedException();
        }
    }
}


Membuat CustomUserManager

Selanjutnya membuat CustomUserManager, CustomManager ini bertugas untuk mengatur User yang telah terdaftar (registered) maupun yang belum terdaftar(anonymous) pada CustomUserStore. Tugas CustomUserManager memegang peranan untuk melakukan autentifikasi pada server, logout, claim, dan masih banyak lagi.

Buatlah sebuah class baru didalam folder "Models" dan beri nama dengan CustomUserManager.cs.

Kode selengkapnya dapat dilihat dibawah :

CustomUserManager.cs
using Microsoft.AspNet.Identity;

namespace Custom_Login.Models
{
    public class CustomUserManager : UserManager<UserModel>
    {
        public CustomUserManager() : base (new CustomUserStore<UserModel>()) { }
    }
}


Membuat Halaman Login

Setelah selesai dengan konfigurasi dan pembuatan beberapa class diatas, selanjutnya kita akan membuat halaman login yang digunakan untuk login sesuai konfigurasi Owin diatas.

Langkah-langkahnya :
  1. Buatlah sebuah halaman Web Form baru dan beri nama "Login.aspx" dan desain halaman login sesuai kebutuhan.

    Add new web form ASP.NET

    Desain halaman :
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="Custom_Login.Login" %>
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Login</title>
        <link rel="stylesheet" type="text/css" href="https://colorlib.com/etc/lf/Login_v10/vendor/bootstrap/css/bootstrap.min.css">
        <link rel="stylesheet" type="text/css" href="https://colorlib.com/etc/lf/Login_v10/fonts/font-awesome-4.7.0/css/font-awesome.min.css">
        <link rel="stylesheet" type="text/css" href="https://colorlib.com/etc/lf/Login_v10/fonts/Linearicons-Free-v1.0.0/icon-font.min.css">
        <link rel="stylesheet" type="text/css" href="https://colorlib.com/etc/lf/Login_v10/vendor/animate/animate.css">
        <link rel="stylesheet" type="text/css" href="https://colorlib.com/etc/lf/Login_v10/vendor/css-hamburgers/hamburgers.min.css">
        <link rel="stylesheet" type="text/css" href="https://colorlib.com/etc/lf/Login_v10/vendor/animsition/css/animsition.min.css">
        <link rel="stylesheet" type="text/css" href="https://colorlib.com/etc/lf/Login_v10/vendor/select2/select2.min.css">
        <link rel="stylesheet" type="text/css" href="https://colorlib.com/etc/lf/Login_v10/vendor/daterangepicker/daterangepicker.css">
        <link rel="stylesheet" type="text/css" href="https://colorlib.com/etc/lf/Login_v10/css/util.css">
        <link rel="stylesheet" type="text/css" href="https://colorlib.com/etc/lf/Login_v10/css/main.css">
    </head>
    <body>
        <div class="limiter">
            <div class="container-login100">
                <div class="wrap-login100 p-t-50 p-b-90">
                    <form class="login100-form validate-form flex-sb flex-w" action="/login" method="post" runat="server">
                        <span class="login100-form-title p-b-51">
                            Login
                        </span>
                        <div class="wrap-input100 validate-input m-b-16" data-validate="Username is required">
                            <asp:TextBox CssClass="input100" ID="txtUsername" placeholder="Username" runat="server" />
                            <span class="focus-input100"></span>
                        </div>
                        <div class="wrap-input100 validate-input m-b-16" data-validate="Password is required">
                            <asp:TextBox CssClass="input100" ID="txtPassword" TextMode="Password" placeholder="Password" runat="server" />
                            <span class="focus-input100"></span>
                        </div>
                        <div class="flex-sb-m w-full p-t-3 p-b-24">
                            <div class="contact100-form-checkbox">
                                <asp:CheckBox ID="RememberMe" CssClass="input-checkbox100" runat="server" />
                                <%--<input class="input-checkbox100" id="ckb1" type="checkbox" name="RememberMe">--%>
                                <label class="label-checkbox100" for="RememberMe">
                                    Remember me
                                </label>
                            </div>
                            <div>
                                <a href="#" class="txt1">
                                    Forgot?
                                </a>
                            </div>
                        </div>
                        <div class="container-login100-form-btn m-t-17">
                            <button class="login100-form-btn">
                                Login
                            </button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
        <div id="dropDownSelect1"></div>
        <script src="https://colorlib.com/etc/lf/Login_v10/vendor/jquery/jquery-3.2.1.min.js" type="text/javascript"></script>
        <script src="https://colorlib.com/etc/lf/Login_v10/vendor/animsition/js/animsition.min.js" type="text/javascript"></script>
        <script src="https://colorlib.com/etc/lf/Login_v10/vendor/bootstrap/js/popper.js" type="text/javascript"></script>
        <script src="https://colorlib.com/etc/lf/Login_v10/vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
        <script src="https://colorlib.com/etc/lf/Login_v10/vendor/select2/select2.min.js" type="text/javascript"></script>
        <script src="https://colorlib.com/etc/lf/Login_v10/vendor/daterangepicker/moment.min.js" type="text/javascript"></script>
        <script src="https://colorlib.com/etc/lf/Login_v10/vendor/daterangepicker/daterangepicker.js" type="text/javascript"></script>
        <script src="https://colorlib.com/etc/lf/Login_v10/vendor/countdowntime/countdowntime.js" type="text/javascript"></script>
        <script src="https://colorlib.com/etc/lf/Login_v10/js/main.js" type="text/javascript"></script>
        <script src="https://ajax.cloudflare.com/cdn-cgi/scripts/7089c43e/cloudflare-static/rocket-loader.min.js"></script>
        <script>$(".input-checkbox100 input").unwrap().addClass("input-checkbox100");</script>
    </body>
    </html>
    
  2. Pada file Login.aspx.cs, buatlah beberapa variabel CustomUserManager dan IAuthenticationManager yang nantinya digunakan untuk inisiasi objek UserManager saat halaman pertama kali di load dan untuk pengecekan autentifikasi user.

    Kode lengkapnya seperti berikut ini :
    private CustomUserManager _customUserManager { get; set; }
    private IAuthenticationManager AuthenticationManager => HttpContext.Current.GetOwinContext().Authentication;
  3. Buatlah juga sebuah fungsi/method untuk melakukan Login ke aplikasi.
    private async Task SignInAsync(UserModel user, bool isPersistent)
    {
        AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
        var identity = await _customUserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
        AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
    }
    
  4. Hasil akhir dari file Login.aspx.cs menjadi seperti berikut :

    Login.aspx.cs
    using Custom_Login.Models;
    using Microsoft.Owin.Security;
    using Microsoft.AspNet.Identity;
    using System;
    using System.Web;
    using System.Threading.Tasks;
    
    namespace Custom_Login
    {
        public partial class Login : System.Web.UI.Page
        {
            private CustomUserManager _customUserManager { get; set; }
            private IAuthenticationManager AuthenticationManager => HttpContext.Current.GetOwinContext().Authentication;
    
            private async Task SignInAsync(UserModel user, bool isPersistent)
            {
                AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
                var identity = await _customUserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
                AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
            }
    
            protected void Page_Load(object sender, EventArgs e)
            {
                _customUserManager = new CustomUserManager();
    
                if (IsPostBack)
                {
                    string username = txtUsername.Text.Trim();
                    string password = txtPassword.Text.Trim();
    
                    if(username == "admin" && password == "admin")
                    {
                        UserModel user = new UserModel();
                        user.Id = "1";
                        user.UserName = username;
    
                        try
                        {
                            Task task = SignInAsync(user, RememberMe.Checked);
                            task.Wait();
                        }catch(Exception ex)
                        {
                            ex.Message.ToString();
                        }
    
                        Response.Redirect("~/");
                    }
                }
            }
        }
    }

    Pada baris yang ditandai diatas seperti username dan password hanyalah sebagai contoh login saja (username dan password diambil dari database).

Untuk memastikan autentifikasi Owin telah bekerja, kita dapat melakukan pengecekan identitas username dengan cara memanggil langsung melalui perintah HttpContext.Current.User.Identity.Name atau User.Identity.Name untuk mendapatkan username.

Kita juga dapat memanggil informasi user lainnya (current user) seperti ID user, jenis kelamin, alamat, no telepon dan lain sebagainya yang berkaitan dengan user. Informasi terkait user selain username, dapat disimpan menggunakan Claim (semacam session). Tutorial tentang Claim dapat dibaca di artikel mengenal Claim Identity pada ASP.NET.

[ads id="ads2"] Terima kasih sudah membaca dan untuk yang membutuhkan source code sebagai panduan atau sekedar pembelajaran lebih lanjut, dapat kalian download di https://drive.google.com/file/d/1jBjjB4L32b1TRtu3nQyCVOhC4lRgBF4b/view?usp=sharing

Semoga bermanfaat.

0/Post a Comment/Comments

Lebih baru Lebih lama