C# - Egyszer használható jelszó

forráskód letöltése
Rendszerünk védelme sok esetben azon múlik, hogy a felhasználói nevünkről, jelszavunkról tud-e valaki más vagy sem. Ráadásul, ha megtartjuk az alapértelmezett Rendszergazda felhasználói nevet, akkor már csak jelszavunk védi a rendszerünket, hiszen a felhasználói név közismert.
Készítsünk most egy olyan web site-ot, melynél a bejelentkezés egy egyszer használható jelszóval történik. A jelszót a rendszer felhasználói nevünk alapján küldi el e-mail-ben, vagy akár mobil telefonunkra SMS-ben. Az így létrehozott jelszót a felhasználónak 10 percen belül fel kell használni, különben megszűnik annak érvényessége. Ezzel a védelemmel persze nem egy általánosan és nagy tömegek által használt web site-ot érdemes védeni, hanem egy olyan helyet, melyet csak rendszergazdák, vagy egyéb kiemelt felhasználók érhetnek el.
A megvalósításhoz készítünk egy komponenst, melyet bármely alkalmazásunkban könnyedén felhasználhatunk.
A melléket projekt lefordítása után a Password komponens felvehető a ToolBox-ra.
A példa használatához a WebForm1.aspx.cs forráskód 65. sorában lévő változóknak adjon valós értéket az alábbiak alapján.
A komponens használatához a MailServer property-ben adjunk meg egy levelező szervert, melyet az e-mail küldéshez használhatunk. A FromMail-be kerül a feladó e-mail címe, míg a ToMail-be a címzetté. Ha a címzett e-mail címe olyan mobil szolgáltatónál van, mely biztosítja azt, hogy új e-mail érkezése esetén egy SMS-t kap a felhasználó a mobil telefonjára, akkor ezzel megoldható a jelszó továbbítása SMS-ben is.
A komponenst ezek után a SendPassword függvény meghívásával működtethetjük. Ennek két paramétert kell megadnunk: az első a Cache osztály, mely a webes alkalmazásunkban rendelkezésre áll, a másik a felhasználói név, melyhez a jelszót kell generálni. A Cache-re azért lesz szükség, mert itt tároljuk el az adott felhasználóhoz létrehozott jelszót.
A jelszó generálását a GeneratePassword függvényünkre bízzuk. Ezt sztringként kapjuk meg.
    public void SendPassword(Cache cache, string username)
    {
      string password = GeneratePassword();
Az e-mail-t az SmtpMail osztály segítségével küldjük el.
      SmtpMail.SmtpServer = mailServer;
      SmtpMail.Send(fromMail, toMail, password, "");      
Ezt követően a jelszót eltároljuk a Cache-en Password_felhasználóinév megnevezéssel. A tárolást úgy tesszük meg, hogy 10 perc leteltével automatikusan törölve legyen a Cache-ről, így ha addig nem történik bejelentkezés, azután már nem lesz használható.
      cache.Add("Password_"+username, password, null, DateTime.Now.AddMinutes(10), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
    }
A jelszó generálását úgy végezzük, hogy véletlenszerű hosszúságú legyen a jelszó és annak karakterei is véletlenszerűek legyenek. A jelszó csupa kisbetűből és csak az angol ABC betűiből áll.
    public string GeneratePassword()
    {
      Random r = new Random(DateTime.Now.Millisecond);
      int max = r.Next(6)+6;
      string s = "";
      for (int i=0; i<max; i++)
      {
        s += (char)(r.Next(26)+97);
      }
      return s;
    }
Nézzük most a felhasználást. A komponens property-jeit feltöltjük, majd meghívjuk a SendPassword függvényt. A ToMail property-t egy GetUserMail függvényen keresztül töltjük fel, melynek paraméterként megadjuk a felhasználói nevet.
    private void Button1_Click(object sender, System.EventArgs e)
    {
      string username=TextBox1.Text;
      password1.MailServer=MailServer;
      password1.FromMail=FromMail;
      password1.ToMail=GetUserMail(username);
      password1.SendPassword(Cache, username);
    }
A GetUserMail függvényben tetszőleges algoritmus alapján rendelhetünk felhasználói névhez e-mail címet. Ez történhet akár SQL adatbázisból, vagy bármi egyéb helyről. Az egyszerűség kedvéért most csak a Rendszergazda felhasználót azonosítjuk és ehhez egy konstans e-mail címet rendelünk.
    private string GetUserMail(string username)
    {
      if (username=="Rendszergazda")
      {
        return ToMail;
      }
      else
      {
        return "";
      }
    }
Amikor a felhasználó megpróbál bejelentkezni, akkor a Cache-ről vesszük a jelszót, ha egyáltalán megtaláljuk ott. Ha igen, akkor ellenőrizzük, hogy egyezik-e azzal, amit a felhasználó megadott. Ha ez is megfelelő, akkor tekinthetjük a bejelentkezést elfogadottnak.
    private void Button2_Click(object sender, System.EventArgs e)
    {
      string password;
      try
      {
        password = Cache["Password_"+TextBox1.Text].ToString();
        if (password==TextBox2.Text)
        {
          Label3.Text="A bejelentkezés sikeres!";
        }
        else
        {
          Label3.Text="Hibás a jelszó!";
        }
      }
      catch
      {
        Label3.Text="A felhasználói névhez nincs jelszó tárolva!";
      }
    }