• No results found

Denna skall modifieras så att vi lägger användarna i applikationsdatabasen.

N/A
N/A
Protected

Academic year: 2022

Share "Denna skall modifieras så att vi lägger användarna i applikationsdatabasen."

Copied!
7
0
0

Loading.... (view fulltext now)

Full text

(1)

Lektion 22 – Övningar

Utgångspunkten för övningarna är v0.0 av Lektion 22 repot.

Vi kommer utgå från följande tutorial:

http://www.codeproject.com/Articles/165159/Custom-Membership-Providers

Denna skall modifieras så att vi lägger användarna i applikationsdatabasen.

Vi skall också använda bcrypt som krypteringsalgoritm, samt använda oss av en salt när lösenordet krypteras.

I v0.0 av kodbasen så är ett Repository/UserRepository samt EF Code First implementerat.

OBS!

I repot som ligger på Github är följande ändringar gjorda efter uppgifterna är incheckade:

Jag har lagt till

user.ID = Guid.NewGuid();

I AppUserRepository/Register. Detta eftersom användare kommer få defaultvärdet för Guid som ID annars. Detta kommer annars leda till att vi får exception för att flera användare har samma Primary Key efter vi har satt in första användaren.

Jag har även ändrat databas instance från SQLEXPRESS2 till SQLEXPRESS i entity-framework- sektionen i web.config.

Jag upptäckte precis innan lektionen började att jag har någon ytterligare bugg i det som är incheckat i repot. Jag har tyvärr inte hunnit lösa detta problem, men jag har en i stort sett identisk lösning som fungerar, så det bör vara något litet jag missat och lösningen är i grund och botten sund. Räkna med att det kommer upp en ”Buggfix – som nämdes på lektionen” i repot senare idag/ikväll.

Lösningar på ovanstående buggar:

Jag hade glömt av 2 st. saker:

Dels så behöver vi i Web.config i <membership>-taggen ange vilken MemberShipProvider som skall användas som default enligt följande:

<membership defaultProvider="CustomMembershipProvider">

Där namnet på defaultProvider måste överrensstämma med namnet på den provider som angavs i uppgift 3.

Sedan hade jag även angett fel namespace då jag lade till defaultProvider i uppgift 3. Detta anges efter type=”… i uppgift 3 (Se uppgiftsbeskrivning för hur det skall se ut när det är korrekt).

(2)

Custom Membership provider

1. Vi utgår från koden för klassen CustomMembershipProvider i den tutorial som länkades in ovan (Detta läggs t.ex. i klassen CustomMembershipProvider i en mapp ”Membership” i Domain). Lägg märke till att vi inte använder någonting från denna tutorial utöver just koden för CustomMembershipProvider (Lägg också märke till att vi använder den sista, mest fullständiga listningen av CustomMembershipProvider).

2. Vi lägger till BCrypt.Net mha NuGet (detta är en krypteringsalgoritm som är avsedd för att kryptera lösenord med – Jag väljer den som har Id: Bcrypt-official).

3. Vi gör följande ändingar i Web.Config. Först börjar vi med att ersätta den befintliga ConnectionSträngen för ApplicationServices. Detta eftersom vi vill spara data för membership-lösningarna i samma databas som vi har övrig applikationsdata:

<add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integra ted Security=True;Initial Catalog=Lektion22.Models.Contexts.EFDbContext;MultipleAc tiveResultSets=true;" providerName="System.Data.SqlClient" />

Ovanstående skall stå på en rad och Initial Catalog skall vara till databasen som ni använder till applikationsdata (Ni kan hitta den i t.ex. View -> Server Explorer).

Vi lägger även till följande i <membership><providers>-sektionen, för att ange att vi har skapat en egen MembershipProvider som vi namngett till CustomMembershipProvider:

<add name="CustomMembershipProvider"

type="CustomMembership.Models.Membership.CustomMembershipProvider"

connectionStringName="ApplicationServices"

enablePasswordRetrieval="false"

enablePasswordReset="true"

requiresQuestionAndAnswer="false"

requiresUniqueEmail="false"

maxInvalidPasswordAttempts="5"

minRequiredPasswordLength="6"

minRequiredNonalphanumericCharacters="0"

passwordAttemptWindow="10"

applicationName="/" />

4. I CustomMembershipProvider lägger vi till följande metoder:

(3)

// Change these?

public override MembershipPasswordFormat PasswordFormat

{ get { return MembershipPasswordFormat.Hashed; } } public override string ApplicationName { get; set; }

public override bool EnablePasswordReset { get { return false; } } public override bool EnablePasswordRetrieval { get { return false; } } public override int MaxInvalidPasswordAttempts { get { return 15; } } public override int MinRequiredNonAlphanumericCharacters

{ get { return 0; } }

public override int PasswordAttemptWindow { get { return 15; } }

public override bool RequiresQuestionAndAnswer { get { return false; } } public override bool DeleteUser(string username,

bool deleteAllRelatedData) {

IAppUserRepository userRepo = new AppUserRepository();

try {

userRepo.DeleteUserByUserName(username);

return true;

} catch {

return false;

} }

public override string GetUserNameByEmail(string email) {

IAppUserRepository userRepo = new AppUserRepository();

return userRepo.FindAll(u => u.UserEmailAddress == email)

.Select(u => u.UserName).FirstOrDefault();

}

Ovanstående metoder kanske ni behöver ändra på beroende på er implementation.

5. Därefter lägger vi även till följande:

(4)

// Not Implemented:

public override string PasswordStrengthRegularExpression { get { throw new NotImplementedException(); } }

public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) {

throw new NotImplementedException();

//IAppUserRepository userRepo = new AppUserRepository();

//return userRepo.FindAll().Select(u => new MembershipUser("CustomMemb ershipProvider",

// u.UserName, u.ID, u.UserEmailAddr ess,

// string.Empty, string.Empty, // true, false, DateTime.MinValue, // DateTime.MinValue,

// DateTime.MinValue,

// DateTime.Now, DateTime.Now));

}

public override MembershipUserCollection FindUsersByEmail(

string emailToMatch, int pageIndex, int pageSize, out int totalRecords) {

throw new NotImplementedException();

}

public override MembershipUserCollection FindUsersByName(

string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) {

throw new NotImplementedException();

}

public override bool ChangePassword(string username,

string oldPassword, string newPassword) {

throw new NotImplementedException();

}

public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) {

throw new NotImplementedException();

}

public override int GetNumberOfUsersOnline() {

throw new NotImplementedException();

}

public override string GetPassword(string username, string answer) {

throw new NotImplementedException();

}

public override string ResetPassword(string username, string answer) {

throw new NotImplementedException();

}

public override bool UnlockUser(string userName) {

throw new NotImplementedException();

}

(5)

public override void UpdateUser(MembershipUser user) {

throw new NotImplementedException();

}

public override MembershipUser GetUser(object providerUserKey , bool userIsOnline) {

throw new NotImplementedException();

}

// Not Used:

//protected virtual byte[] DecryptPassword(byte[] encodedPassword);

//[TargetedPatchingOptOut("Performance critical to inline this type of met hod across NGen image boundaries")]

//protected virtual byte[] EncryptPassword(byte[] password);

//protected virtual byte[] EncryptPassword(byte[] password, MembershipPass wordCompatibilityMode legacyPasswordCompatibilityMode);

Ovanstående metoder är inte implementerade – kanske behöver ni implementera någon av dem beroende på hur er lösning ser ut.

I tutorial-lösningen använder de MD5 för att kryptera lösenord. Detta är en allmän

krypteringsalgoritm som är konstruerad för att vara snabb, detta är inte lämpligt för att kryptera lösenord med. Lösenord krypteras med fördel med en långsam krypteringsalgoritm, vilket gör att det tar längre tid att knäcka lösenord. I uppgift 6-8 skall vi ändra krypteringsalgoritm till BCrypt istället. BCrypt är en långsam krypteringsalgoritm som är konstruerad för att kryptera lösenord.

6. Vi tar bort den gamla krypteringsalgoritmen i CustomMembershipProvider och lägger till följande:

public static string GetBcryptHash(string value, string salt)

{

return BCrypt.Net.BCrypt.HashPassword(value, salt);

}

7. I CreateUser i CustomMembershipProvider skall en if-sats ändras till följande:

(6)

if (user == null) {

AppUser appUser = new AppUser();

appUser.UserName = username;

appUser.Salt = BCrypt.Net.BCrypt.GenerateSalt();

appUser.PasswordHash = GetBcryptHash(password, appUser.Salt);

appUser.UserEmailAddress = email;

IAppUserRepository userRepo = new AppUserRepository();

userRepo.RegisterUser(appUser);

status = MembershipCreateStatus.Success;

return GetUser(username, true);

}

8. CustomMembershipProvider/ValidateUser ändras till följande:

IAppUserRepository userRepo = new AppUserRepository();

var user = userRepo.FindAll(u => u.UserName == username) .FirstOrDefault();

if (user == null || string.IsNullOrEmpty(user.Salt)) return false;

string bcryptHash = GetBcryptHash(password, user.Salt);

if (bcryptHash == user.PasswordHash) return true;

return false;

9. För att se till att vi använder vårat UserRepository så ändrar vi CustomMembershipProvider/GetUser ändras till följande:

IAppUserRepository userRepo = new AppUserRepository();

var user = userRepo.FindAll(u => u.UserName == username) .FirstOrDefault();

if (user != null) {

MembershipUser memUser = new MembershipUser(

"CustomMembershipProvider", username, user.ID,

user.UserEmailAddress,

string.Empty, string.Empty, true, false, DateTime.MinValue, DateTime.MinValue,

DateTime.MinValue,

DateTime.Now, DateTime.Now);

return memUser;

}

return null;

10. I AccountController lägger vi till följande för att få tillgång till den MembershipProvider vi definierat ovan:

private CustomMembershipProvider _membership;

public AccountController() {

_membership = new CustomMembershipProvider();

}

(7)

11. Därefter byter vi ut ”Membership.” Mot ”_membership.” I resten av AccountController.

Detta är för att vi inte vill använda Default Membership provider längre, utan vår egen Membership-provider (Det är även lämpligt att se till att CustomMembershipProvider initieras med DI och ninject).

12. Jag ändrar även Views/Account/register.cshtml från

@Membership.MinRequiredPasswordLength

till 6. (Detta värde bör eg. plockas ut från CustomMembershipProvider i er lösning).

Övrigt

Jag har inte testat av denna lösning ordentligt, så ni kanske behöver rätta några buggar. Gissningsvis är detta inga problem för er.

Jag har även lämnat en del metoder i CustomerMembershipProvider oimplementerade. Vissa av dessa vill ni ev. använda i er lösning, men om ni tittar på hur övriga delar är implementerade så bör ni kunna skriva dessa implementationer själva.

Det kan också vara värt att fundera över ifall de extra Repository-metoder vi implementerat i AppUserRepository är nödvändiga. Anledningen att jag implementerade de som jag gjorde var att med minimalt med ändringar få lösningen som presenteras på tutorial-sidan att fungera i vår lösning.

Avslutningsvis vill ni kanske ändra strukturen på denna lösning något – ifall ni tycker att en alternativ implementation för något av detta är lämpligt, kör på det.

Ifall ni stöter på något som är lurigt eller ifall ni har frågor på någonting så tveka inte att höra av er.

References

Related documents

10 stycken hinkar, de två hinkarna i mitten kan ha en skiftade får man mer poäng om man landar i

Huru det stod till med Fabian hade hennes gamla, kloka ögon för länge sedan kommit underfund med, han skulle rent gå och blifva olycklig för hela lifvet, om han ej fick Louise,

Skatta följande påståenden genom att ringa in den siffra som stämmer bäst med din egen uppfattning om hur det i allmänhet är

Vad ska du säga om någon ringer och vill att du ska logga in eller lämna ut siffror!.

På motorväg, motortrafikled eller annan väg med avfarter sätts märke H23 upp 1 – 2 km före den plats där märke F7 avfartsvisare satts upp. På motorväg bör avståndet normalt

Tina Thörner beslutade sig för att hennes team skulle sträva efter att vara till sinnes som när man är nykär.. – När man tänker på nykärlek mår det un- dermedvetna bra och

1) Artiklar: Fördjupade presentationer av nya forskningsresultat som offentliggörs för första gången. abstract och referenser). Kompletteras med abstract, referenser, summary och

Utöver vår revision av årsredovisningen har vi även utfört en revision av styrelsens och verkställande direktörens förvaltning för Motion Display Scandinavia AB för år 2017