Is there any login api for nopcommerce - nopcommerce

In nopcommerce how to create api which will post username and password to system and on return give response true or false, if logged in then true else false

You can send in a json item the password and user name and catch them in a function like:
public JsonResult Login(){
var key = Request.Params[0];
}
Then in "key" you will have the username and password. But you should have a read about how to create a login and use bearers tokens to create a secure login page.

Related

Plain password in .net core SignInManager Identity

I have user table with plain passwords. I need connect the table into .net core web's AspNetUsers table.How to hash my user table's plain passwords like AspNetUsers's PasswordHash.
How can login with SignInManger plain-text password?
I recently did something like this. Our legacy system had its own password hashing method. I needed to covert everything over to asp.net users.
First thing I did was add two new columns to the Application user. These contain my legacy user password and that hash that was used to create it.
public string LegacyPasswordHash { get; set; }
public string LegacyPasswordSalt { get; set; }
Then i ran my sql script that copied all of the users in including their legacy password hash and salt.
Then i created a custom SignInManager.
public class ApplicationSignInManager : SignInManager<ApplicationUser> {}
In the password check method I test if its a legacy password user and if it is i covert the password that they just sent me over to a asp.net users password and delete their legacy password. Tip: is to remember to set the user security token on the user table as well this can not be null. You will have major issues with resting password if it is. As there is a bug in the token validation 2022
This is the section of the code i use for testing and resetting the password.
if (_password.EncodePassword(_user.LegacyPasswordSalt) == _user.LegacyPasswordHash)
{
_logger.LogInformation(LoggingEvents.LegacyUserCommand, "Legacy User {_user.Id} migrating password.", _user.Id);
await _userManager.AddPasswordAsync(_user, _password);
_user.SecurityStamp = Guid.NewGuid().ToString();
_user.LegacyPasswordHash = null;
_user.LegacyPasswordSalt = null;
await _userManager.UpdateAsync(_user);
return await new CheckTwoFactorCommand(_logger, _userManager, _user).Execute();
}
if (_shouldLockout)
{
_user.SecurityStamp = Guid.NewGuid().ToString();
await _userManager.UpdateAsync(_user);
_logger.LogInformation(LoggingEvents.LegacyUserCommand, "Login failed for Legacy user {_user.Id} invalid password. (LockoutEnabled)", _user.Id);
await _userManager.AccessFailedAsync(_user);
if (await _userManager.IsLockedOutAsync(_user))
return SignInResult.LockedOut;
}
_logger.LogInformation(LoggingEvents.LegacyUserCommand, "Login failed for Legacy user {_user.Id} invalid password", _user.Id);
return SignInResult.Failed;

Kentor AuthServices/Owin - handling the response from the identity provider

I have a working configuration to authenticate against Azure AD using KentorAuthServices & Owin, but I need to know some basic information about the user that has just logged in. When I used WSFed as the authentication service I could simply handle the SecurityTokenValidated notification as per below. How do I do similarly with KentorAuthServices? I don't see an appropriate notification to pull this information. All I need is the username/email address the user logged in with.
Notifications = new WsFederationAuthenticationNotifications
{
SecurityTokenValidated = context =>
{
string username = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.Name).Value;
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, username, DateTime.Now, DateTime.Now.AddMinutes(60), true, "");
String encryptedTicket = FormsAuthentication.Encrypt(authTicket);
context.Response.Cookies.Append(FormsAuthentication.FormsCookieName, encryptedTicket);
return Task.FromResult(0);
}
}
ETA: Doing some more digging I believe AcsCommandResultCreated is the notification that I want to hook into - but this never fires?
All the information in the SAML Response is converted to claims in the resulting identity. If you are using the default template with ASP.Net Identity you can access the external identity in the ExternalLoginCallback action on the AccountController.
The AcsCommandResultCreated notification should definitely be fired on a sucessful login. Try enable the Katana logging and see if the login sequence is aborted due to an error.

asp.net core identity extract and save external login tokens and add claims to local identity

I am a stackoverflow noob so please go easy if I am doing this wrong.
I am using asp.net core with the default core identity template (local accounts).
I have accertained how to add claims to user principal when they login locally like so
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginInputModel model)
{
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var user = await _userManager.FindByNameAsync(model.Email);
await _userManager.AddClaimAsync(user, new Claim("your-claim", "your-value"));
And I have figured out how to get claims returned from the external login but I cannot figure out how I would add these before the user principal gets created in the ExternalLoginCallback function
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
if (remoteError != null)
{
ModelState.AddModelError(string.Empty, $"Error from external provider: {remoteError}");
return View(nameof(Login));
}
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
return RedirectToAction(nameof(Login));
}
else {
// extract claims from external token here
}
// assume add claims to user here before cookie gets created??
// Sign in the user with this external login provider if the user already has a login.
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
if (result.Succeeded)
I am assuming the the _signInManager.ExternalLoginSignInAsync function works similar to the local login _signInManager.PasswordSignInAsync in the sense that once it is called, the cookie will be created. But I am just not sure.
Essentially what I am hoping to achieve, is understanding of how to add custom claims into the cookie that gets created regardless of how to user logins in (local or external), and how to persist these claims to the database if required.
I am planning on doing some work where if I have a user login using say google auth, I need to save that access_token from google, because I wish to call into the Google APIs later with it. So I need to be able to include this access_token in with the User Principal that gets created, and I would hope the cookie would have a claim on it I could use at the front end as well.
This might be out of scope on this question but I would also like when the google token expires, for some-how it to use the refresh token and go get a new one, or force the user to relogin.
Any help on this would be super appreciated, I have really tried hard to understand this without posting this question to stackoverflow. I have read many articles with lots of useful info, but does not provide the answers this specific question is asking. So Thank you very much in advance.
cheers
When you use await _userManager.AddClaimAsync(user, new Claim("your-claim", "your-value")); that actually updates the Identity's aspnetuserclaims table.
Whenever you sign in (by using _signInManager.PasswordSignIn or _signInManager.ExternalLoginSignInAsync) the claims from that table are read and added to the cookie that on every request becomes the Principal.
So you probably don't want to be calling the AddClaimAsync method from UserManager on every login.
Regarding external login providers, you have access to the claims when you call (in ExternalCallback and ExternalCallbackConfirmation if you are using the default templates) here:
var info = await _signInManager.GetExternalLoginInfoAsync();
The claims are in info.Principal.Claims.
The access token is not included by default. When it is, it will be here (along with the type and expiry date):
var accessToken = info.AuthenticationTokens.Single(f => f.Name == "access_token").Value;
var tokenType = info.AuthenticationTokens.Single(f => f.Name == "token_type").Value;
var expiryDate = info.AuthenticationTokens.Single(f => f.Name == "expires_at").Value;
To have the access token be included in the AuthenticationTokens collection, when you are configuring the GoogleAuthentication middleware set the SaveTokens flag to true:
app.UseGoogleAuthentication(new GoogleOptions{
ClientId = "...",
ClientSecret = "...",
SaveTokens = true
Now, if you want to have control over which claims go in the cookie you have to "take over" the process of creating the claims principal.
This is done for you when you use _signInManager.PasswordSignIn/ExternalLoginSignInAsync.
So, for example, for ExternalLoginSignInAsync replace:
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
With:
var user = await this._userManager.FindByLoginAsync(info.LoginProvider, info.ProviderKey);
var claimsPrincipal = await this._signInManager.CreateUserPrincipalAsync(user);
((ClaimsIdentity)claimsPrincipal.Identity).AddClaim(new Claim("accessToken", info.AuthenticationTokens.Single(t => t.Name == "access_token").Value));
await HttpContext.Authentication.SignInAsync("Identity.Application", claimsPrincipal);
"Identity.Application" is the default cookie name. You can change it in Startup's ConfigureServices method, for example to MainCookie:
services.Configure<IdentityOptions>(options => {
options.Cookies.ApplicationCookie.AuthenticationScheme = "MainCookie";
});
You still need to handle the ExternalCallbackConfirmation action in the AccountController. It will be similar to the example above.

Web app protected by single password for all clients

I was wondering if there is a standard way of protecting a ASP.Net web application with just a single password? In other words no username needed and all clients use the same password for authentication.
Or does anyone have their own solution?
You simply could use Identity framework to aim this propose. Actually you don't need any user or password to authenticate.
[HttpPost]
public ActionResult Login(string password)
{
if (password=="MyVerySecretPassword")
{
var ident = new ClaimsIdentity(
new[] {
// adding following 2 claim just for supporting default antiforgery provider
new Claim(ClaimTypes.NameIdentifier, "JustAnuniqueName"),
new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"),
new Claim(ClaimTypes.Name,"JustAnuniqueName"),
},
DefaultAuthenticationTypes.ApplicationCookie);
HttpContext.GetOwinContext().Authentication.SignIn(
new AuthenticationProperties { IsPersistent = false }, ident);
return RedirectToAction("MyAction"); // auth succeed
}
// invalid password
ModelState.AddModelError("", "invalid username or password");
return View();
}
But it would be much better if you hash the password and check the hashed password instead of above simple if statement. To aim this you could use PasswordHasher class to hash and verify the password.
First hash your desired password and save it in preferred storage (DB, file, hard coded in code or everywhere else):
string hashedPassword = new PasswordHasher().HashPassword("MyVerySecretPassword");
Now since you have the hashed one. You could use VerifyHashedPassword() method to verify it.
if(new PasswordHasher()
.VerifyHashedPassword("myHashedPassword",password)==PasswordVerificationResult.Success)
{
// the password is correct do whatever you want
}
Also you could see my simple working example which I made to demonstrate it.

Remote authentication and local authorization in MVC5

My web site authentication is centralized and I authenticate my users with a web service and I don't store usernames and passwords. Web service returns details of valid user that I insert in my local db once user logins. I need authorize valid users in my web site and want to use ASP.NET Identity. I was confused how to use this method for authorization users. Can I use Identity without any code first authentication?
As far as I understand you want send user credential to remote server and if remote server accept it authorize the user in your MVC application. It this kind of scenario you don't need user manager or user store. You could simply generate an Identity object with proper claims and sign in the user with the generated Identity object. Consider this simply example as clue:
[HttpPost]
public ActionResult Login(string username, string password)
{
if (_remoteServer.IsValid(username, password))
{
var ident = new ClaimsIdentity(
new[]
{
// adding following 2 claim just for supporting default antiforgery provider
new Claim(ClaimTypes.NameIdentifier, username),
new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"),
new Claim(ClaimTypes.Name, username),
// you could add extra claims like role or even custom one
new Claim(ClaimTypes.Role, "UserRoleName"),
new Claim("MyCustomClaim", "MyValue"),
},
DefaultAuthenticationTypes.ApplicationCookie);
HttpContext.GetOwinContext().Authentication.SignIn(
new AuthenticationProperties { IsPersistent = false }, ident);
return RedirectToAction("MyAction"); // auth succeed
}
// invalid username or password
ModelState.AddModelError("", "invalid username or password");
return View();
}
Now user is authenticated and injected in Identity's pipeline.
[Authorize]
public ActionResult Foo()
{
}
// since we injected user roles to Identity we could do this as well
[Authorize(Roles="UserRoleName")]
public ActionResult Foo()
{
// since we injected our authentication mechanism to Identity pipeline
// we have access current user principal by calling also
// HttpContext.User
}

Resources