I'm using OpenId on a new website and am trying to get some basic information about the user, see the code below. Why is the following allways null?
var myData = response.GetExtension<ClaimsResponse>();
And the main code
[System.Web.Mvc.AcceptVerbs(HttpVerbs.Get)]
public ActionResult LogOn()
{
var openid = new OpenIdRelyingParty();
IAuthenticationResponse response = openid.GetResponse();
if (response != null)
{
switch (response.Status)
{
case AuthenticationStatus.Authenticated:
FormsAuthentication.RedirectFromLoginPage(
response.ClaimedIdentifier, false);
var myData = response.GetExtension<ClaimsResponse>();
break;
case AuthenticationStatus.Canceled:
ModelState.AddModelError("loginIdentifier",
"Login was cancelled at the provider");
break;
case AuthenticationStatus.Failed:
ModelState.AddModelError("loginIdentifier",
"Login failed using the provided OpenID identifier");
break;
}
}
return View("Register");
}
[System.Web.Mvc.AcceptVerbs(HttpVerbs.Post)]
public ActionResult LogOn(string loginIdentifier)
{
if (!Identifier.IsValid(loginIdentifier))
{
ModelState.AddModelError("loginIdentifier",
"The specified login identifier is invalid");
return View();
}
else
{
var openid = new OpenIdRelyingParty();
IAuthenticationRequest request = openid.CreateRequest(
Identifier.Parse(loginIdentifier));
// Require some additional data
request.AddExtension(new ClaimsRequest
{
Email = DemandLevel.Request,
FullName = DemandLevel.Request
});
return request.RedirectingResponse.AsActionResult();
}
}
http://www.dotnetopenauth.net/developers/help/the-axfetchassregtransform-behavior/
Related
I'm building an app for our company which needs to have separate database per client. App is for the usage of other multiple companies, so the app needs to identify the company name when the user logs in and make the users operate only within their company db. I have it all set, but the problem is that the app is not able to handle many different databases simultaneously. When users from more different companies log in, the first users db gets changed to the db of the second user who is logged in! This is of course unacceptable. How can I make the app to use many dbs simultaneously?
I have one database which collects all app users and their company names and separate databases for each company. I also have a standard asp below are my codes:
My applicatinon dbcontext is
public static string _DbName;
public ApplicationDbContext() : base(string.IsNullOrWhiteSpace(ConString.dbCatlogConn) ? "DefaultConnection" : ConString.dbCatlogConn, throwIfV1Schema: false)
{
this.Database.CommandTimeout = 600;
}
public ApplicationDbContext(string dbName) : base(dbName)
{
_DbName = dbName;
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
Login class and database initializer in account controller
if (!ModelState.IsValid)
{
return View(model);
}
var regx = new Regex("[-]");
if (!regx.IsMatch(userdash))
{
ViewBag.Message = "Error";
return View();
}
string x = model.UserName.ToLower();
Session["Initial"] = x.Split('-').First();
var dbcompanies = db.CompanyLists.Where(t => (t.InitializationLetters == Session["Initial"].ToString())).Select(t => new { ConnString = t.ConnectionString }).ToList();
if (dbcompanies.Count > 0)
{
if (dbcompanies[0].ConnString == "")
{
}
else
{
Session["ConnectionString"] = dbcompanies[0].ConnString;
}
}
else
{
ModelState.AddModelError("", language == "en" ? "Invalid login attempt." : "text here");
return View(model);
}
if (Session["ConnectionString"].ToString() == "" || Session["ConnectionString"].ToString() == null)
{
ViewBag.Message1 = "notfound";
return View();
}
else
{
using ( db = new ApplicationDbContext(Session["ConnectionString"].ToString()))
{
UserManager.PasswordHasher = new CustomPasswordHasher();
var user = db.Users.Where(e => e.UserName.ToLower() == model.UserName.ToLower()).FirstOrDefault();
var result = new SignInStatus();
if (user == null)
{
result = SignInStatus.Failure;
}
else
{
string dbPassword = dal.DecryptPassword(user.AnotherUsername, user.AnotherSalt, user.PasswordHash);
var status = UserManager.PasswordHasher.VerifyHashedPassword(dbPassword, model.Password);
if (status == PasswordVerificationResult.Success)
{
result = await SignInManager.PasswordSignInAsync(model.UserName, user.PasswordHash, model.RememberMe, shouldLockout: false);
}
else
result = SignInStatus.Failure;
}
switch (result)
{
case SignInStatus.Success:
if (user != null)
{
if (user.Disabled == true)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
ModelState.AddModelError("", language == "en" ? "Invalid login attempt." : "text");
return View(model);
//return View("Lockout");
}
else
{
var ip = Request.ServerVariables["REMOTE_ADDR"];
user.LastIpAddress = ip;
db.SaveChanges();
if (User.IsInRole(UsersTypes.Interview.ToString()))
{
return RedirectToRoute("profile", new { type = profile.Acceptance });
}
}
}
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", language == "en" ? "Invalid login attempt." : "error");
return View(model);
}
}
}
I have found the same problem here asp.net mvc multitenant database per tenant
when I run i got error DbName cant to be null where should I declare or pass the database connection for that variable and will it be the main database?
I have also used the string literal as one of the comments like this one
private const string DbName = "default app connection string";
but I got error It must be variable or indexer
can I find help for that problem
I have asp.net MVC code first project I have managed to change my connection string dynamically depend on login values ( the database is a copy of the main one) and correctly changed but I always get password UserManager.PasswordHasher.VerifyHashedPassword error did not match and if I neglect this code SignInManager.PasswordSignInAsync always return Failure despite it is login correctly with the same main database
this is my trial ApplicationDbContext
public ApplicationDbContext(string connectionstring)
: base(connectionstring)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext(ConString.MeqyasdbCon(ConString.dbCatlogConn));
}
login page
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl, string language = Config.DefaultLanguage)
{
string x = model.UserName.ToLower();
string dbName = x.Split('_').First();
var dbname = db.dbLists.Where(t => (t.InitializationLetters == dbName)).Select(t => new { ConnString = t.ConnectionString }).ToList();
ConString.dbCatlogConn = dbname[0].ConnString;
//new conection
var checkconnection = ConString.dbCatlogConn;
using (db = new ApplicationDbContext(ConString.dbCatlogConn))
{
bool CheckConnResult = db.Database.Exists();
//code here
var user = db.Users.Where(e => e.UserName.ToLower() == model.UserName.ToLower()).FirstOrDefault();
var result = new SignInStatus();
if (user == null)
result = SignInStatus.Failure;
else
{
string dbPassword = dal.DecryptPassword(user.AnotherUsername, user.AnotherSalt, user.PasswordHash);
// I had to fix dbPassword to check where is the error
var status = UserManager.PasswordHasher.VerifyHashedPassword("Admin", model.Password);
if (status == PasswordVerificationResult.Success)
// error here
result = await SignInManager.PasswordSignInAsync(model.UserName, user.PasswordHash, model.RememberMe, shouldLockout: false);
// result = SignInStatus.Success;
else
result = SignInStatus.Failure;
}
switch (result)
{
case SignInStatus.Success:
if (user != null)
{
if (user.Disabled == true)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
ModelState.AddModelError("", language == "en" ? "Invalid login attempt." : "error ");
// rest the connection to default
ConString.dbCatlogConn = ConString.MainConn;
return View(model);
//return View("Lockout");
}
else
{
user.LastLoginDateUtc = DateTime.Now.ToUniversalTime();
db.SaveChanges();
if (User.IsInRole(UsersTypes.Interview.ToString()))
{
return RedirectToRoute("tutrial");
}
}
}
// returnUrl = "/"; // error it shouldn't be like this alaa mohamed
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", language == "en" ? "Invalid login attempt." : "error ");
ConString.dbCatlogConn = ConString.MainConn;
return View(model);
}
}
}
I'd want to determine whether JWT Token is valid in [AllowAnonymouse]] endpoint
edit
I have an endpoint which can be accessed by anyone (authorized and unauthorized people) and then: If that user has http authorization header OR he has token in cookies and his token valid then redirect him to X otherwise to Y
Pseudocode of my idea:
[Route("Passport/")]
public IActionResult Passport()
{
if (this.User.Identity.IsAuthenticated)
or pseudocode:
if (tokenIsValid(getJWTTokenFromHeader()));
{
return RedirectToAction("Resources");
}
else
{
return RedirectToAction("Login");
}
}
I thought about something like this:
[Route("Passport/")]
public IActionResult Passport()
{
var token = ExtractTokenFromHeader();
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue
("application/json"));
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
var get = client.GetAsync($"http://localhost/verifyToken").Result;
var responseBody = await get.Content.ReadAsStringAsync().ConfigureAwait(false);
switch (get.StatusCode)
{
case HttpStatusCode.Unauthorized:
return RedirectToAction("Login");
case HttpStatusCode.OK:
return RedirectToAction("Resources");
default:
return RedirectToAction(...);
}
}
Where endpoint verifyToken has an [Authorize] attribute and just returns Unauthorized (defaultly) or OK (from code)
You may try below code
private static bool ValidateJWTToken(string token, out string username) {
username = null;
var simplePrinciple = JwtManager.GetPrincipal(token);
var identity = simplePrinciple.Identity as ClaimsIdentity;
if (identity == null) return false;
if (!identity.IsAuthenticated) return false;
}
I am trying to save a Guid value in a cookie. The way I want to save it is by setting a Claim for the user and getting it back in every controller for validation purposes.
Before going on the subject I have seen this question here but it did not solve my problem!
Here is my code in login controller:
public async Task<ActionResult> Login_Post(LoginViewModel loginViewModel)
{
if (ModelState.IsValid)
{
var user = IdentityManager.UserManager.FindByName(loginViewModel.Username);
if (user != null)
{
IdentityManager.SignInManager.AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var status = SignInStatus.Failure;
if (!user.IsApproved)
{
status = SignInStatus.Failure;
}
if (!await IdentityManager.UserManager.IsEmailConfirmedAsync(user.Id))
{
status = SignInStatus.EmailNotConfirmed;
}
status = (SignInStatus)await IdentityManager.SignInManager
.PasswordSignInAsync(loginViewModel.Username, loginViewModel.Password, loginViewModel.RememberMe, true);
if (status == SignInStatus.Failure)
{
await IdentityManager.UserManager.AccessFailedAsync(user.Id);
if (await IdentityManager.UserManager.IsLockedOutAsync(user.Id))
{
status = SignInStatus.LockedOut;
}
}
switch (status)
{
case SignInStatus.Success:
var identity = await IdentityManager.UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
var permissions = IdentityManager.ApplicationDbContext.UserVesselPermissions(Guid.Parse(identity.GetUserId()), DateTime.Now).ToList();
var userVesselPermissionsResult = permissions.FirstOrDefault();
identity.AddClaim(userVesselPermissionsResult != null
? new Claim(SealogicalClaimUtility.VesselId, userVesselPermissionsResult.VesselId.ToString())
: new Claim(SealogicalClaimUtility.VesselId, ""));
IdentityManager.SignInManager.AuthenticationManager.SignIn(identity);
return RedirectToAction("Index", "HomeDashboard", new {area = "Dashboard"});
case SignInStatus.Failure:
ModelState.AddModelError("", "Login failed, username or password is incorrect.");
break;
case SignInStatus.RequiresVerification:
ModelState.AddModelError("", "Your account needs verification");
break;
case SignInStatus.LockedOut:
ModelState.AddModelError("",
"Login failed, this account has been locked. Contact administrator for further information.");
break;
case SignInStatus.EmailNotConfirmed:
ModelState.AddModelError("",
"Login failed, activate this account by clicking the email sent to your email account.");
break;
default:
ModelState.AddModelError("",
"Login failed, unkwon error. Contact administrator for further information");
break;
}
}
}
return View("Login", loginViewModel);
}
I am using PasswordSignInAsync() method for login validation because I need to get back that SignInStatus in order show a proper message to the user.
After that I read this question in here and they say to create a ClaimsIdentity and then use again the AuthenticationManager to sign in with that ClaimsIdentity object as I did here:
case SignInStatus.Success:
var identity = await IdentityManager.UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
var permissions = IdentityManager.ApplicationDbContext.UserVesselPermissions(Guid.Parse(identity.GetUserId()), DateTime.Now).ToList();
var userVesselPermissionsResult = permissions.FirstOrDefault();
identity.AddClaim(userVesselPermissionsResult != null
? new Claim(SealogicalClaimUtility.VesselId, userVesselPermissionsResult.VesselId.ToString())
: new Claim(SealogicalClaimUtility.VesselId, ""));
IdentityManager.SignInManager.AuthenticationManager.SignIn(identity);
return RedirectToAction("Index", "HomeDashboard", new {area = "Dashboard"});
SealogicalClaimUtility as a static class as below:
public static class SealogicalClaimUtility
{
public const string VesselId = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/vesselid";
}
Until now everything is working fine but when I try to get back that Claim it does not exist at all.
To get back that clam I use a custom property as below:
public static Guid? UserSelectedVesselId
{
get
{
var hasVesselClaim = ((ClaimsIdentity) HttpContext.Current.User.Identity)
.HasClaim(claim => claim.Type == SealogicalClaimUtility.VesselId);
if (hasVesselClaim)
{
var vesselClaim = ((ClaimsIdentity) HttpContext.Current.User.Identity).Claims.FirstOrDefault(
claim => claim.Type == SealogicalClaimUtility.VesselId);
if (vesselClaim != null)
{
Guid vesselId;
if (Guid.TryParse(vesselClaim.Value, out vesselId))
{
return vesselId;
}
}
return null;
}
var currentUserPermission = UserVesselPermissions.FirstOrDefault();
return currentUserPermission?.VesselId;
}
}
Any idea what I am doing wrong in here ?
Thanks in advance!
I am using ASP.NET Identity version 2
I'm using Oauth to get users to register through Facebook etc.
I got all the dlls. but how does it work ?
This is a code i found on the internet but it doesn't work. Any ideas how it works?.. I'm lost :/
Thanks for reading this!
using DotNetOpenAuth.Messaging;
public ActionResult LogOn()
{
var openid = new OpenIdRelyingParty();
IAuthenticationResponse response = openid.GetResponse();
if (response != null)
{
switch (response.Status)
{
case AuthenticationStatus.Authenticated:
FormsAuthentication.RedirectFromLoginPage(
response.ClaimedIdentifier, false);
break;
case AuthenticationStatus.Canceled:
ModelState.AddModelError("loginIdentifier",
"Login was cancelled at the provider");
break;
case AuthenticationStatus.Failed:
ModelState.AddModelError("loginIdentifier",
"Login failed using the provided OpenID identifier");
break;
}
}
return View();
}
[System.Web.Mvc.AcceptVerbs(HttpVerbs.Post)]
public ActionResult LogOn(string loginIdentifier)
{
if (!Identifier.IsValid(loginIdentifier))
{
ModelState.AddModelError("loginIdentifier",
"The specified login identifier is invalid");
return View();
}
else
{
var openid = new OpenIdRelyingParty();
IAuthenticationRequest request = openid.CreateRequest(
Identifier.Parse(loginIdentifier));
// Require some additional data
request.AddExtension(new ClaimsRequest
{
BirthDate = DemandLevel.NoRequest,
Email = DemandLevel.Require,
FullName = DemandLevel.Require
});
return request.RedirectingResponse.AsActionResult();
}
}