I want to put a CAPTCHA field into the the auth submit form api/auth/credentials.
So, now the form will need to contain a captcha field apart from username, password and rememberme.
I will then check the session where I stored the answer of the captcha image vs the form submitted captcha result.
My question is, which part(s) of the SS source code do I need to override in order to do it correctly?
My feeling is that I should look into override and customise CredentialsAuthProvider class for the start?
Here is a quickie way to do it:
public ExtDeskResponse Post(MyAuth req) {
//Captcha Validation
var valid = req.Captcha == base.Session.Get<Captcha>("Captcha").result;
//SS Authentication
var authService = AppHostBase.Instance.TryResolve<AuthService>();
authService.RequestContext = new HttpRequestContext(
System.Web.HttpContext.Current.Request.ToRequest(),
System.Web.HttpContext.Current.Response.ToResponse(),
null);
var auth = string.IsNullOrWhiteSpace(
authService.Authenticate(new Auth {
UserName = req.UserName,
Password = req.Password,
RememberMe = req.RememberMe,
}).UserName);
if (valid && auth) {
//...logic
}
return new MyAuthResponse() {
//...data
};
}
Look forward to see you guys show me more elegant/efficient/expandable ways to do it.
Related
I am working on a windows form application which starts when computer is started. Now i want that when first time a user logins than it must save password somewhere and than next time it
must automatic login when computer is started.
Can Any body help me out in this issue???
Please Help..
Thanks in Advance
If I understand, you want to do this :
At first login :
Properties.Settings.Default["Username"] = "test";
Properties.Settings.Default["Password"] = "password";
And after, just read previous settings :
var user = Properties.Settings.Default["Username"];
var password = Properties.Settings.Default["Password"];
// Then call your login method
Concrete application :
public bool Login()
{
var username = Properties.Settings.Default["Username"];
var password = Properties.Settings.Default["Password"];
if (username == null || password == null)
{
// Ask the user to login
var user = LoginWindow.AskForLogin();
// If user login
if (user != null)
{
username = user.Username;
password = user.Password;
Properties.Settings.Default["Username"] = username;
Properties.Settings.Default["Password"] = password;
}
}
// Log your user
return Authenticate(username, password);
}
For example this answer. And msdn answer.
Also you can write password to registry:
Registry.SetValue(#"HKEY_CURRENT_USER\Software\MyApp\", "Password", password);
And read it:
var password = Registry.GetValye(#"HKEY_CURRENT_USER\Software\MyApp\", "Password", null);
I wanted to implement this solution to handle antiforgery in ajax requests. I know there are other solutions but this is the one I like most.
The problem is I have to deal with System.Web.Webpages 1.0 so I cannot make use of AntiForgeryConfig.CookieName in my code.
public override void OnAuthorization(AuthorizationContext filterContext)
{
var request = filterContext.HttpContext.Request;
// Only validate POSTs
if (request.HttpMethod == WebRequestMethods.Http.Post)
{
// Ajax POSTs and normal form posts have to be treated differently when it comes
// to validating the AntiForgeryToken
if (request.IsAjaxRequest())
{
string cookieName = AntiForgeryData.GetAntiForgeryTokenName(context.Request.ApplicationPath);
var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName];
var cookieValue = antiForgeryCookie != null
? antiForgeryCookie.Value
: null;
AntiForgery.Validate(cookieValue, request.Headers["__RequestVerificationToken"]);
}
else
{
new ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
}
}
}
How can I retrieve (programmatically) the cookie name set by the antiforgery system in Mvc3? I suspect the AntiForgery.Validate part will also be a problem but I'll handle that before. Any thoughts?
The actual cookie name always starts from "__RequestVerificationToken" with some suffix. So you can find the cookie like this:
private static string FindCookieValueByName(HttpRequestBase request)
{
return request.Cookies
.Cast<string>()
.Where(cn => cn.StartsWith("__RequestVerificationToken", StringComparison.OrdinalIgnoreCase))
.Select(cn => request.Cookies[cn].Value)
.FirstOrDefault();
}
when a user login I store his id in session let say in Session["id"]. on mostly pages I store id from session in an integer and use it in various methods. I put a check on page_load event
protected void Page_Load(object sender, EventArgs e)
{
if (Session["id"] == null)
{
Response.Redirect("Home.aspx");
}
//code goes here
}
What I know is that session expire after 20 min if no request is send to server. but even continuously sending request session expire and i redirected on home page. Is this correct approach or I should try other alternative. any help will be appreciated.
The correct way would be to use the membership API which handles all these details transparently. As shown in this explanatory page you could directly set the timeout interval in membership API using a parameter in the web.config.
Hope I helped!
If there is gap more than 20 minutes between two requests to server then only your session will get expired
Use Permanent User Login Session In ASP.NET thi sample describes how to create a permanent user login session in ASP.NET. The sample code includes an ASP.NET MVC4 project to control the user registration and login process. But you can use this technique in any type of ASP.NET project. But briefly you can use this code
The functionality of this class is to add a form authentication ticket to the browser cookie collection with a life time expiry.
public sealed class CookieHelper
{
private HttpRequestBase _request;
private HttpResponseBase _response;
public CookieHelper(HttpRequestBase request,
HttpResponseBase response)
{
_request = request;
_response = response;
}
//[DebuggerStepThrough()]
public void SetLoginCookie(string userName,string password,bool isPermanentCookie)
{
if (_response != null)
{
if (isPermanentCookie)
{
FormsAuthenticationTicket userAuthTicket =
new FormsAuthenticationTicket(1, userName, DateTime.Now,
DateTime.MaxValue, true, password, FormsAuthentication.FormsCookiePath);
string encUserAuthTicket = FormsAuthentication.Encrypt(userAuthTicket);
HttpCookie userAuthCookie = new HttpCookie
(FormsAuthentication.FormsCookieName, encUserAuthTicket);
if (userAuthTicket.IsPersistent) userAuthCookie.Expires =
userAuthTicket.Expiration;
userAuthCookie.Path = FormsAuthentication.FormsCookiePath;
_response.Cookies.Add(userAuthCookie);
}
else
{
FormsAuthentication.SetAuthCookie(userName, isPermanentCookie);
}
}
}
}
This function is used in login page or control on the click of login button. In the attached sample project, the following function is written in AccountController class. This function validates the login of the user and then add a permanent form authentication ticket to the browser.
private bool Login(string userName, string password,bool rememberMe)
{
if (Membership.ValidateUser(userName, password))
{
CookieHelper newCookieHelper =
new CookieHelper(HttpContext.Request,HttpContext.Response);
newCookieHelper.SetLoginCookie(userName, password, rememberMe);
return true;
}
else
{
return false;
}
}
Microsoft is coming up with a new Membership system called ASP.NET Identity (also the default in ASP.NET MVC 5). I found the sample project, but this is not implemented a password reset.
On password reset topic just found this Article: Implementing User Confirmation and Password Reset with One ASP.NET Identity – Pain or Pleasure, not help for me, because do not use the built-in password recovery.
As I was looking at the options, as I think we need to generate a reset token, which I will send to the user. The user can set then the new password using the token, overwriting the old one.
I found the IdentityManager.Passwords.GenerateResetPasswordToken / IdentityManager.Passwords.GenerateResetPasswordTokenAsync(string tokenId, string userName, validUntilUtc), but I could not figure out what it might mean the tokenId parameter.
How do I implement the Password Reset in ASP.NET with MVC 5.0?
I get it: The tokenid is a freely chosen identity, which identifies a password option. For example,
1. looks like the password recovery process, step 1
(it is based on: https://stackoverflow.com/a/698879/208922)
[HttpPost]
[ValidateAntiForgeryToken]
[AllowAnonymous]
//[RecaptchaControlMvc.CaptchaValidator]
public virtual async Task<ActionResult> ResetPassword(
ResetPasswordViewModel rpvm)
{
string message = null;
//the token is valid for one day
var until = DateTime.Now.AddDays(1);
//We find the user, as the token can not generate the e-mail address,
//but the name should be.
var db = new Context();
var user = db.Users.SingleOrDefault(x=>x.Email == rpvm.Email);
var token = new StringBuilder();
//Prepare a 10-character random text
using (RNGCryptoServiceProvider
rngCsp = new RNGCryptoServiceProvider())
{
var data = new byte[4];
for (int i = 0; i < 10; i++)
{
//filled with an array of random numbers
rngCsp.GetBytes(data);
//this is converted into a character from A to Z
var randomchar = Convert.ToChar(
//produce a random number
//between 0 and 25
BitConverter.ToUInt32(data, 0) % 26
//Convert.ToInt32('A')==65
+ 65
);
token.Append(randomchar);
}
}
//This will be the password change identifier
//that the user will be sent out
var tokenid = token.ToString();
if (null!=user)
{
//Generating a token
var result = await IdentityManager
.Passwords
.GenerateResetPasswordTokenAsync(
tokenid,
user.UserName,
until
);
if (result.Success)
{
//send the email
...
}
}
message =
"We have sent a password reset request if the email is verified.";
return RedirectToAction(
MVC.Account.ResetPasswordWithToken(
token: string.Empty,
message: message
)
);
}
2 And then when the user enters the token and the new password:
[HttpPost]
[ValidateAntiForgeryToken]
[AllowAnonymous]
//[RecaptchaControlMvc.CaptchaValidator]
public virtual async Task<ActionResult> ResetPasswordWithToken(
ResetPasswordWithTokenViewModel
rpwtvm
)
{
if (ModelState.IsValid)
{
string message = null;
//reset the password
var result = await IdentityManager.Passwords.ResetPasswordAsync(
rpwtvm.Token,
rpwtvm.Password
);
if (result.Success)
{
message = "the password has been reset.";
return RedirectToAction(
MVC.Account.ResetPasswordCompleted(message: message)
);
}
else
{
AddErrors(result);
}
}
return View(MVC.Account.ResetPasswordWithToken(rpwtvm));
}
Skeleton proposal to sample project on github, if anyone needs it may be tested.The E-mail sending not yet written, possibly with the addition soon.
Seems like a lot of trouble...
What advantage does the above give over:
the user clicking a 'Recover Account' link
this sends an 64 byte encoded string of a datetime ticks value (call it psuedo-hash) in an email
click the link back in the email to a controller/action route that
matches email and it's source server to psuedo-hash, decrypts the psuedo-hash, validates the time since sent and
offers a View for the user to set a new password
with a valid password, the code removes the old user password and assigns the new.
Once complete, successful or not, delete the psuedo-hash.
With this flow, at no time do you EVER send a password out of your domain.
Please, anyone, prove to me how this is any less secure.
I'm developing a Facebook app, and i only want to allow access to certain views if the visitor is authorized through Facebook. This should be a pretty simple task, and i thought is was, until i tried it out in IE. The following code works fine in Chrome and Safari. I want to use Forms authentication, and therefore i have set
<forms loginUrl="~/Account/Login" timeout="2880" />
in web.config. This will direct the visitor to the following ActionResult when entering my app:
public ActionResult Login(string returnUrl)
{
ManagerGame2.Utilities.StaticDataContent.InitStaticData();
var oAuthClient = new FacebookOAuthClient();
oAuthClient.AppId = FacebookApplication.Current.AppId;
oAuthClient.RedirectUri = new Uri(redirectUrl);
var loginUri = oAuthClient.GetLoginUrl(new Dictionary<string, object> { { "state", returnUrl } });
return Redirect(loginUri.AbsoluteUri);
}
Then the user is redirected to a Facebook page, and an access token is sent back into my OAuth ActionResult:
public ActionResult OAuth(string code, string state)
{
FacebookOAuthResult oauthResult;
if (FacebookOAuthResult.TryParse(Request.Url, out oauthResult))
{
if (oauthResult.IsSuccess)
{
var oAuthClient = new FacebookOAuthClient();
oAuthClient.AppId = FacebookApplication.Current.AppId;
oAuthClient.AppSecret = FacebookApplication.Current.AppSecret;
oAuthClient.RedirectUri = new Uri(redirectUrl);
dynamic tokenResult = oAuthClient.ExchangeCodeForAccessToken(code);
string accessToken = tokenResult.access_token;
DateTime expiresOn = DateTime.MaxValue;
if (tokenResult.ContainsKey("expires"))
{
DateTimeConvertor.FromUnixTime(tokenResult.expires);
}
FacebookClient fbClient = new FacebookClient(accessToken);
dynamic me = fbClient.Get("me?fields=id,name");
long facebookID = Convert.ToInt64(me.id);
Account acc = (from x in db.Account.OfType<Account>() where x.FaceBookID == facebookID select x).FirstOrDefault();
if (acc == null)
{
acc = CreateAccount(me);
}
acc.LatestLogin = DateTime.Now;
db.Entry(acc).State = EntityState.Modified;
db.SaveChanges();
MemoryUserStore.CurrentAccount = acc;
UserRoleProvider usp = new UserRoleProvider();
usp.GetRolesForUser(acc.AccountID.ToString());
FormsAuthentication.SetAuthCookie(acc.AccountID.ToString(), false);
if (Url.IsLocalUrl(state))
{
return Redirect(state);
}
return RedirectToAction("Details", "Account", new { id = acc.AccountID });
}
}
return RedirectToAction("Index", "Account");
}
What i am trying to do here, is to first verify if the token i get back from the redirect is valid. If it is, then i pull some data about the visitor, like FacebookID and Name. I then match it with my database, to see if the user already exists, and if not, i create one. I also assign a role for the user in my custom Role provider, but i had the infinite loop problem before this. Then i set
FormsAuthentication.SetAuthCookie(acc.AccountID.ToString(), false);
and i assume this is the core of keeping track of wheter a visitor is authorized or not. As far as i understand, when the visitor is trying to call a ActionResult that requires [Authorize] then the system will check for this cookie.
Well, could someone please clarify why the above code is working in Chrome/Safari, but keeps looping through Login and then OAuth infinitely in IE?
My app is using MVC 3, EF Code First and Facebook C# SDK 5.0.25
Okay, so i figured out that the problem was triggered by the [Authorize] annotation, as expected. The Facebook SDK has a [CanvasAuthorize] annotation, and when i switch to using this, IE works fine and does not login forever.
Before this, i tried using cookieless authentication, but IE still didn't want to play along.
As far as i have figured out, the problem occurs because Facebook apps are inside an IFrame. This supposedly screws something up with cookies and trust. If someone knows why this is, i would appreciate to hear about it.
Also, if anyone knows how to use and maintain roles, easily, with this [CanvasAuthorize], i would be glad to know.
I know this seems obvious but are you sure cookies aren't disabled in IE? There is an option to disable cookies in developer tools.