Implement ASP.NET Identity IUserLockoutStore without IUserPasswordStore - c#

I have MVC5 project and I don't have direct access to user database instead I was provided with web services, for example:
bool register (string username, string password, string email) //password is plain text
bool login (string username, string password)
My problem is that I have no idea how to implement IUserPasswordStore because ASP Identity force me to use Hash while I'm not allowed to store hashed password because this web services will be used not just by me.
My UserStore.cs:
public Task<string> GetPasswordHashAsync(TUser user)
{
//I'm suppose to provide hashed password here, but since I don't have any hashed password stored, I have no idea how to implement this method
string passwordHash = userTable.GetPassword(user.Id);
return Task.FromResult<string>(passwordHash);
}
public Task<bool> HasPasswordAsync(TUser user)
{
var hasPassword = !string.IsNullOrEmpty(userTable.GetPassword(user.Id));
return Task.FromResult<bool>(Boolean.Parse(hasPassword.ToString()));
}
public Task SetPasswordHashAsync(TUser user, string passwordHash)
{
//do nothing since I don't need to hash the password
return Task.FromResult<Object>(null);
}
And I was told not to implement IUserPasswordStore because of this and just either use SignInAsync or override PasswordSignInAsync in SignInManager, this is working fine however I ran into another problem which is I need to lockout user if they failed several login attempt and it is not possible to implement IUserLockoutStore without implement IUserPasswordStore.

Found the answer: I create a new class that implements IPasswordHasher ...
public class CustomPasswordHasher : IPasswordHasher
{
public string HashPassword(string password)
{
return password; //return password as is
}
public PasswordVerificationResult VerifyHashedPassword(
string hashedPassword,
string providedPassword)
{
if (hashedPassword.Equals(providedPassword)) {
return PasswordVerificationResult.Success;
}
return PasswordVerificationResult.Failed;
}
}
... and register it in IdentityConfig:
manager.PasswordHasher = new CustomPasswordHasher();

Related

ASP.NET Identity 2.0: How to rehash password

I am migrating users from a legacy user store to ASP.NET Identity 2.0 in my ASP.NET 5.0 web application. I have a means of verifying legacy hashes, but I want to upgrade them at login-time to ASP.NET Identity 2.0 hashes.
I've created a custom IPasswordHasher that is able to detect and verify legacy hashes, and return PasswordVerificationResult.SuccessRehashNeeded at the appropriate time. (If it detects that the hash is not legacy, it simply falls through to the built-in ASP.NET Identity hash verification.)
However, returning PasswordVerificationResult.SuccessRehashNeeded doesn't seem to cause ASP.NET Identity to actually do anything. Is there a configuration option somewhere that would cause the system to re-hash the passwords when IPasswordHasher returns this result?
If the answer is no to the above, then is it recommended that I simply re-hash and update the user manually? Where would I do this? I don't see any place at the controller level where I can see the PasswordVerificationResult.
I'm new to ASP.NET Identity so I'm sure I'm missing something simple. Thank you in advance for any pointers.
It seems rehashing mechanism is not implemented in the built-in user manager. But hopefully you could easily implemented. consider this:
public class ApplicationUserManager : UserManager<ApplicationUser>
{
protected override async Task<bool> VerifyPasswordAsync(
IUserPasswordStore<ApplicationUser, string> store,
ApplicationUser user, string password)
{
var hash = await store.GetPasswordHashAsync(user);
var verifyRes = PasswordHasher.VerifyHashedPassword(hash, password);
if (verifyRes == PasswordVerificationResult.SuccessRehashNeeded)
await store.SetPasswordHashAsync(user, PasswordHasher.HashPassword(password));
return verifyRes != PasswordVerificationResult.Failed;
}
}
If you have implemented IPasswordHasher correctly, when returning a PasswordVerificationResult.SuccessRehashNeeded result, ASP.NET Core Identity will call the HashPassword method automatically for you, successfully authenticating the user and updating the hash in the database.
The class would look something like this:
public class PasswordHasherWithOldHashingSupport : IPasswordHasher<ApplicationUser>
{
private readonly IPasswordHasher<ApplicationUser> _identityPasswordHasher;
public PasswordHasherWithOldHashingSupport()
{
_identityPasswordHasher = new PasswordHasher<ApplicationUser>();
}
public string HashPassword(ApplicationUser user, string password)
{
return _identityPasswordHasher.HashPassword(user, password);
}
public PasswordVerificationResult VerifyHashedPassword(ApplicationUser user, string hashedPassword, string providedPassword)
{
var passwordVerificationResult = _identityPasswordHasher.VerifyHashedPassword(user, hashedPassword, providedPassword);
if (passwordVerificationResult == PasswordVerificationResult.Failed)
{
/* Do your custom verification logic and if successful, return PasswordVerificationResult.SuccessRehashNeeded */
passwordVerificationResult = PasswordVerificationResult.SuccessRehashNeeded;
}
return passwordVerificationResult;
}
}

ASP.NET Identity change password

I need ability to change password for user by admin. So, admin should not enter a current password of user, he should have ability to set a new password. I look at ChangePasswordAsync method, but this method requires to enter old password. So, this method is not appropriate for this task. Therefore I have made it by the following way:
[HttpPost]
public async Task<ActionResult> ChangePassword(ViewModels.Admin.ChangePasswordViewModel model)
{
var userManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
var result = await userManager.RemovePasswordAsync(model.UserId);
if (result.Succeeded)
{
result = await userManager.AddPasswordAsync(model.UserId, model.Password);
if (result.Succeeded)
{
return RedirectToAction("UserList");
}
else
{
ModelState.AddModelError("", result.Errors.FirstOrDefault());
}
}
else
{
ModelState.AddModelError("", result.Errors.FirstOrDefault());
}
return View(model);
}
it works, but theoretically we can receive error on AddPasswordAsync method. So, old password will be removed but new is not set. It's not good. Any way to do it in "one transaction"?
PS. I seen ResetPasswordAsync method with reset token, seems, it's more safe (because can't be unstable situation with user) but in any case, it does by 2 actions.
EDIT: I know the OP requested an answer which performs the task in one transaction but I think the code is useful to people.
All the answers use the PasswordHasher directly which isn't a good idea as you will lose some baked in functionality (validation etc).
An alternative (and I would assume the recommended approach) is to create a password reset token and then use that to change the password. Example:
var user = await UserManager.FindByIdAsync(id);
var token = await UserManager.GeneratePasswordResetTokenAsync(user);
var result = await UserManager.ResetPasswordAsync(user, token, "MyN3wP#ssw0rd");
This method worked for me:
public async Task<IHttpActionResult> changePassword(UsercredentialsModel usermodel)
{
ApplicationUser user = await AppUserManager.FindByIdAsync(usermodel.Id);
if (user == null)
{
return NotFound();
}
user.PasswordHash = AppUserManager.PasswordHasher.HashPassword(usermodel.Password);
var result = await AppUserManager.UpdateAsync(user);
if (!result.Succeeded)
{
//throw exception......
}
return Ok();
}
ApplicationUserManager is the class generated by the ASP.NET Template.
Which means, you can edit it and add any functionality it doesn't have yet. The UserManager class has a protected property named Store which stores a reference to the UserStore class (or any subclass of it, depending on how you configured your ASP.NET Identity or if you use custom user store implementations, i.e. if you use different database engine like MySQL).
public class AplicationUserManager : UserManager<....>
{
public async Task<IdentityResult> ChangePasswordAsync(TKey userId, string newPassword)
{
var store = this.Store as IUserPasswordStore;
if(store==null)
{
var errors = new string[]
{
"Current UserStore doesn't implement IUserPasswordStore"
};
return Task.FromResult<IdentityResult>(new IdentityResult(errors) { Succeeded = false });
}
if(PasswordValidator != null)
{
var passwordResult = await PasswordValidator.ValidateAsync(password);
if(!password.Result.Success)
return passwordResult;
}
var newPasswordHash = this.PasswordHasher.HashPassword(newPassword);
await store.SetPasswordHashAsync(userId, newPasswordHash);
return Task.FromResult<IdentityResult>(IdentityResult.Success);
}
}
The UserManager is nothing else than a wrapper to the underlying UserStore. Check out IUserPasswordStore interface documentation at MSDN on available Methods.
Edit:
The PasswordHasher is also a public property of the UserManager class, see interface definition here.
Edit 2:
Since some people naively believe, you can't do password validation this way, I've updated it. The PasswordValidator property is also a property of UserManager and its as simple as adding 2 lines of code to add password validation too (which wasn't an requirement of the original question though).
In .net core 3.0
var token = await UserManager.GeneratePasswordResetTokenAsync(user);
var result = await UserManager.ResetPasswordAsync(user, token, password);
I think that the solution is much easier
Generate the passwordToken,
Reset the password with the generated Token...
public async Task<IdentityResult> ResetPasswordAsync(ApplicationUser user, string password)
{
string token = await userManager.GeneratePasswordResetTokenAsync(user);
return await userManager.ResetPasswordAsync(user, token, password);
}
This is just a refinement on the answer provided by #Tseng. (I had to tweak it to get it to work).
public class AppUserManager : UserManager<AppUser, int>
{
.
// standard methods...
.
public async Task<IdentityResult> ChangePasswordAsync(AppUser user, string newPassword)
{
if (user == null)
throw new ArgumentNullException(nameof(user));
var store = this.Store as IUserPasswordStore<AppUser, int>;
if (store == null)
{
var errors = new string[] { "Current UserStore doesn't implement IUserPasswordStore" };
return IdentityResult.Failed(errors);
}
var newPasswordHash = this.PasswordHasher.HashPassword(newPassword);
await store.SetPasswordHashAsync(user, newPasswordHash);
await store.UpdateAsync(user);
return IdentityResult.Success;
}
}
Note: this applies specifically to a modified setup that uses int as the primary keys for users and roles. I believe it would simply be a matter of removing the <AppUser, int> type args to get it to work with the default ASP.NET Identity setup.
public async Task<IActionResult> ChangePassword(ChangePwdViewModel usermodel)
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
var user = await _userManager.FindByIdAsync(userId);
var result = await _userManager.ChangePasswordAsync(user, usermodel.oldPassword, usermodel.newPassword);
if (!result.Succeeded)
{
//throw exception......
}
return Ok();
}
public class ChangePwdViewModel
{
[DataType(DataType.Password), Required(ErrorMessage ="Old Password Required")]
public string oldPassword { get; set; }
[DataType(DataType.Password), Required(ErrorMessage ="New Password Required")]
public string newPassword { get; set; }
}
Note : here UserId i am retrieving from Current logged User.
For ASP.NET Core 3.1 users, this is a modernized iteration of the excellent answers provided by #Tseng and #BCA.
PasswordValidator is no longer a property on UserManager - instead, the property is an IList PasswordValidators. Furthermore, Identity now has a protected UpdatePasswordHash method that changes the password for you without needing to directly access the UserStore, which eliminates the need to manually hash and save the password anyway.
UserManager also has a public property, bool SupportsUserPassword, which replaces the need to test if Store implements IUserPasswordStore (internally, this is exactly what UserManager does in the SupportsUserPassword getter).
Since UpdatePasswordHash is protected, you do still need to extend the base UserManager. Its signature is:
protected Task<IdentityResult> UpdatePasswordHash(TUser user, string newPassword, bool validatePassword)
where validatePassword represents whether or not to run password validation. This does not default to true, unfortunately, so it needs to be supplied. The implementation looks like this:
public async Task<IdentityResult> ChangePasswordAsync(ApplicationUser user, string newPassword)
{
if (!SupportsUserPassword)
{
return IdentityResult.Failed(new IdentityError
{
Description = "Current UserStore doesn't implement IUserPasswordStore"
});
}
var result = await UpdatePasswordHash(user, newPassword, true);
if (result.Succeeded)
await UpdateAsync(user);
return result;
}
As before, the first order of business is to ensure the current UserStore supports passwords.
Then, simply call UpdatePasswordHash with the ApplicationUser, the new password, and true to update that user's password with validation. If the update was successful, you still have to save the user so call UpdateAsync.
If you don't have user's current password and still want to change the password. What you could do instead remove user's password first and then add the new password. This way you will be able to change user's password without needing current password of that user.
await UserManager.RemovePasswordAsync(user);
await UserManager.AddPasswordAsync(user, model.Password);
public async Task<ActionResult> ResetUserPassword(string id, string Password)
{
// Find User
var user = await context.Users.Where(x => x.Id == id).SingleOrDefaultAsync();
if (user == null)
{
return RedirectToAction("UserList");
}
await UserManager.RemovePasswordAsync(id);
// Add a user password only if one does not already exist
await UserManager.AddPasswordAsync(id, Password);
return RedirectToAction("UserDetail", new { id = id });
}
Yes, you are correct. ResetPassword through token is a preferred approach.
Sometime back, I created a complete wrapper over .NET Identity and code can be found here. It might be helpful for you. You can also find nuget here. I also explained the library in a blog here. This wrapper is easily consumable as nuget and create all required configs during installation.

MVC5 'link login' to external site losing the current identity

I'm using an MVC system where I use OWIN authentication, implementing my own IUserStore/etc and that all works great. I'm not looking into linking my logins with external logins, and i'm having trouble using the code that comes with MVC5. In particular:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LinkLogin(string provider)
{
// Request a redirect to the external login provider to link a login for the current user
return new ChallengeResult(provider, Url.Action("LinkLoginCallback", "Manage",), User.Identity.GetUserId());
}
and
public class ChallengeResult : HttpUnauthorizedResult
{
// Used for XSRF protection when adding external logins
internal const string XsrfKey = "XsrfId";
public ChallengeResult(string provider, string redirectUri)
: this(provider, redirectUri, null)
{
}
public ChallengeResult(string provider, string redirectUri, string userId)
{
LoginProvider = provider;
RedirectUri = redirectUri;
UserId = userId;
}
public string LoginProvider { get; set; }
public string RedirectUri { get; set; }
public string UserId { get; set; }
public override void ExecuteResult(ControllerContext context)
{
context.RequestContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
var properties = new Microsoft.Owin.Security.AuthenticationProperties() { RedirectUri = RedirectUri };
if (UserId != null)
{
properties.Dictionary[XsrfKey] = UserId;
}
Container.GetInstance<Microsoft.Owin.Security.IAuthenticationManager>().Challenge(properties, LoginProvider);
}
}
I have only changed the challenge result so that it uses my structuremap DI instead of GetOwinContext for the authenticationmanager. The problem is that i have all of my controllers set with a [CustomAuthorize] attribute, and when i reach the LinkLogin method, it works fine. The context.user.identity variable is of AuthenticationType 'ApplicationCookie', which is good and what i want.
However when it goes through the challegeresult part of 'LinkLogin', i hit my CustomAuthorize code again and now the user is no longer the same. The Context.User.Identity variable is now of AuthenticationType 'Negotiate', and it has my windows login as the username instead.
This doesn't work with my application at all, and i end up getting a 403 error because it can't resolve that user to the correct Cookie user.
Is there something that i'm doing wrong here? I've tried to put AllowAnonymous above LinkLogin, but that doesn't seem to help at all. Not sure if i need to modify ChallengeResult somehow to fit my needs better. Any help would be great, thanks!
turns out i was passing a null value as the 'provider' by accident. once i fixed that, it worked correctly

active directory asp.net forms authentication in asp.net mvc 3

I have to implement an interface like this:
interface IMembershipWrapper
{
Guid GetUserId();
Guid GetUserId(string username, bool userIsOnline);
bool ValidateUser(string userName, string password);
…
}
against active directory and inject it using Unity.
I might get away with throwing a NotImplementedException exception for certain methods but do you think it is generally possible? What strategy do you recommend?
I understand that I can configure 'active directory asp.net forms authentication' via the web.config as described here. Unfortunately, this is not an option.
This should be completely possible without changing your authentication system in the web.config. Especially if you're using .NET 3.5+. Take a look at System.DirectoryServices.AccountManagement.
To implement GetUserId(string username, bool userIsOnline) you may want to try something like:
public Guid GetUserId(string username, bool userIsOnline) {
using(PrincipalContext pc = new PrincipalContext(ContextType.Domain, "[active directory domain here]")) {
var user = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, username);
if(user != null)
return user.Guid.Value;
else
return null;
}
}
To implement ValidateUser(string userName, string password) use ValidateCredentials() on the PrinicalContext
public bool ValidateUser(string userName, string password) {
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "[active directory domain here]"))
{
return pc.ValidateCredentials(userName, password);
}
}
Without more information about your implementation, I'm not sure how to go about implementing GetUserId(), since it seems like you wouldn't have enough information to go to Active Directory with.

How to Unit Test Asp.net Membership?

I am new to unit testing and I am trying to test some of my .NET membership stuff I been writing.
So I am trying to check my VerifyUser method that checks if the users credentials are valid or not.
So this is what it looks like:
public bool VerifyUser(string userName, string password)
{
bool valid = Membership.ValidateUser(userName, password);
return valid;
}
And now every time I run my unit test it fails. I know I am passing in the right credentials and stuff. Then it dawned on me that maybe my Test Project(that is under the same Solution as my real project) might need its own web.config file with the connection string and stuff. Or an app config file maybe since it is a Application Library project.
So do I just copy the web.config file from my real project and call it a day? Or should I only be taking parts from it? Or am I just way off.
My database is using a custom database with the .net membership merged with my database. So in my config file I had to specify a ManagerProvider and a roleProvider.
This is how my unit test looks like
[Test]
public void TestVerifyUser()
{
AuthenticateUser authenitcate = new AuthenticateUser();
bool vaild = authenitcate.VerifyUser("chobo3", "1234567");
Assert.That(vaild, Is.True);
}
Also later on I have in one of my asp.net mvc ActionResult Methods(the Login View to be exact) I have this:
FormsAuthentication.RedirectFromLoginPage(loginValidation.UserName, rememberMe);
So now how can I write a unit test that would do what a user would do. Say they start at the Home page then click on the login page and log in successfully. I want them to be redirect to the home page.
I am not sure how to represent that in code. I am pretty sure that the RedirectFromLoginPage works and thats now what I am really testing. I am testing the fact that I have 3 things that can happen in the login ActionResult method.
User logs in and gets sent back where they came from.
User fails to login and gets sent back to the LoginView and sees error messages.
User has tried to go to a secure and has been redirect to the login page. If the login successfully the will be redirect back to the secure page via the ReturnUrl.
So I want to do a test to see if these work as they should. So thats why I need to have the user coming from like the home page to see if they get redirected back to it later and if they come from a secure page they get redirect back to that later on.
I am also by the way using NUnit 2.5 and VS2008 Pro.
This is what I am trying to test. I am at the part where I am trying to see if the user is valid or not(the if statement). I have no clue how to test it.
public ActionResult Login(string returnUrl, FormCollection form, bool rememberMe)
{
LoginValidation loginValidation = new LoginValidation();
try
{
UpdateModel(loginValidation, form.ToValueProvider());
}
catch
{
return View("Login");
}
if (ModelState.IsValid == true)
{
bool valid = authenticate.VerifyUser(loginValidation.UserName, loginValidation.Password);
if (valid == false)
{
ModelState.AddModelError("frm_Login", "Either the Password or UserName is invalid");
}
else if (string.IsNullOrEmpty(returnUrl) == false)
{
/* if the user has been sent away from a page that requires them to login and they do
* login then redirect them back to this area*/
return Redirect(returnUrl);
}
else
{
FormsAuthentication.RedirectFromLoginPage(loginValidation.UserName, rememberMe);
}
}
return View("Login");
}
You can test your controllers and much of your custom provider by refactoring your custom membership code into a two layers: a data access repository that only interacts with the database, and a service layer that uses repository components to provide the Membership API. The service layer is where you would validate arguments, hold and enforce parameters like EnablePasswordReset and translate any database exceptions or status codes into a form suitable for controller consumption.
When you specify each layer with its own interface, consumers can write to that interface regardless of how its implemented. When your app is running your provider is of course talking to the database through these interfaces but for testing you can mock the repository or service interfaces. You can test your service layer by mocking the repository level without have to mess with the database or the web.config file, and you can test your controllers by mocking the service layer. If you don't want to refactor the whole provider, you can still test your controllers if you only create the service interface and have your controllers use it.
To be specific, if a little verbose, your repository and service interfaces might look something like:
namespace Domain.Abstract {
public interface IRepository {
string ConnectionString { get; }
}
}
namespace Domain.Abstract {
public interface IUserRepository : IRepository {
MembershipUser CreateUser(Guid userId, string userName, string password, PasswordFormat passwordFormat, string passwordSalt,
string email, string passwordQuestion, string passwordAnswer, bool isApproved,
DateTime currentTimeUtc, bool uniqueEmail);
MembershipUser GetUser(Guid userId, bool updateLastActivity, DateTime currentTimeUtc);
PasswordData GetPasswordData(Guid userId, bool updateLastLoginActivity, DateTime currentTimeUtc);
void UpdatePasswordStatus(Guid userId, bool isAuthenticated, int maxInvalidPasswordAttempts, int passwordAttemptWindow,
DateTime currentTimeUtc, bool updateLastLoginActivity, DateTime lastLoginDate, DateTime lastActivityDate);
//....
}
}
namespace Domain.Abstract {
public interface IUserService {
bool EnablePasswordRetrieval { get; }
bool EnablePasswordReset { get; }
bool RequiresQuestionAndAnswer { get; }
bool RequiresUniqueEmail { get; }
//....
MembershipUser CreateUser(string applicationName, string userName, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved);
MembershipUser GetUser(Guid userId, bool userIsOnline);
bool ValidateUser(Guid userId, string password);
//...
}
}
namespace Domain.Concrete {
public class UserService : IUserService {
private IUserRepository _userRepository;
public UserService(IUserRepository userRepository) {
_userRepository = userRepository;
}
//...
public bool ValidateUser(Guid userId, string password) {
// validate applicationName and password here
bool ret = false;
try {
PasswordData passwordData;
ret = CheckPassword(userId, true, true, DateTime.UtcNow, out passwordData);
}
catch (ObjectLockedException e) {
throw new RulesException("userName", Resource.User_AccountLockOut);
}
return ret;
}
private bool CheckPassword(Guid userId, string password, bool updateLastLoginActivityDate, bool failIfNotApproved,
DateTime currentTimeUtc, out PasswordData passwordData) {
passwordData = _userRepository.GetPasswordData(userId, updateLastLoginActivityDate, currentTimeUtc);
if (!passwordData.IsApproved && failIfNotApproved)
return false;
string encodedPassword = EncodePassword(password, passwordData.PasswordFormat, passwordData.PasswordSalt);
bool isAuthenticated = passwordData.Password.Equals(encodedPassword);
if (isAuthenticated && passwordData.FailedPasswordAttemptCount == 0 && passwordData.FailedPasswordAnswerAttemptCount == 0)
return true;
_userRepository.UpdatePasswordStatus(userId, isAuthenticated, _maxInvalidPasswordAttempts, _passwordAttemptWindow,
currentTimeUtc, updateLastLoginActivityDate,
isAuthenticated ? currentTimeUtc : passwordData.LastLoginDate,
isAuthenticated ? currentTimeUtc : passwordData.LastActivityDate);
return isAuthenticated;
}
}
The Asp.Net Membership system is designed to work in the context of an Asp.Net request. So, you have three options here.
Most people when faced with such a dependency would write a thin wrapper around it. The wrapper doesn't do anything, just redirects all calls to the underlying dependency. So, they just don't test it. Your AuthenticateUser is such a wrapper. You should probably make all methods virtual or extract an interface in order to make it mockable, but that's another story.
Use TypeMock Isolator and mock Membership.
Use the Ivonna framework and run your test in the Asp.Net context (that would be an integration test).
Unfortunately you can't just copy your web.config or your app.config and have it work that way. The reason is that your assembly is running inside of the NUnit process, not under your application.
To remedy your situation, you're probably going to have to Mock or Stub the Membership members you're calling, or follow a Convention over Configuration approach to the settings you have stored in your web.config.
There are many mocking frameworks out there, but here are a couple: Rhino Mocks, Moq
Also, to follow the Convention over Configuration approach, you could do something like this:
static ConfigurationSettings
{
static String SomeSetting
{
get
{
var result = "HARDCODEDVALUE";
if (ConfigurationManager.AppSettings["SOMEKEY"] != null)
result = ConfigurationManager.AppSettings["SOMEKEY"];
return result;
}
}
You could then use this code like this:
//this is how the old code might look
var mySetting = ConfigurationManager.AppSettings["SOMEKEY"];
//use the setting
//this is how the new code would look
var mySetting = ConfigurationSettings.SomeSetting;
//use the setting
This way your test will work, and when you run it under your application it will use whatever configuration settings you've stored.

Categories

Resources