How to Authenticate Login form without using asp controls - asp.net

I have put together a really nice Login page in which I am using HTML input tags for my username, password, and login button. I have two different login forms, one for each type of user (student user, and business user). I have never authenticated against a database so I assumed my method would be easy to execute. After scouring the web for easy methods to implement with what I already had I found it nearly impossible to figure out how to accomplish my goal without having to use asp:login control. Begrudgingly, I scrapped what I had and threw in the asp:login control. My problem is, that it was a pain to implement (creating stored procedures, and messing with the web.config), it looks hideous as it doesn't not conform with the CSS I had previously written, and the FormsAuthentication I am using only allows me to redirect one user after login (to the home portal upon succesful login, and back to the login page if login failed.) using the authentication Forms mode in my Web.config:
<forms defaultUrl="~/InteriorStudentPortal.aspx" loginUrl="~/ExteriorLogin.aspx" slidingExpiration="true" timeout="2880"></forms>
Since I have two users I need to redirect based on what user is logging in. Here is a sample of the asp:login control that I have been using:
<asp:Login ID="Login1" runat="server" CssClass="Login" OnAuthenticate= "ValidateStudent" Width="313px"></asp:Login>
Along with the back code:
Imports System.Data
Imports System.Configuration
Imports System.Data.SqlClient
Imports System.Web.Security
Partial Class ExteriorLogin
Inherits System.Web.UI.Page
Protected Sub ValidateStudent(sender As Object, e As AuthenticateEventArgs) Handles Login1.Authenticate
Dim studentId As Integer = 0
Dim constr As String = ConfigurationManager.ConnectionStrings("DatabaseConnectionString").ConnectionString
Using con As New SqlConnection(constr)
Using cmd As New SqlCommand("Validate_Student")
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#Username", Login1.UserName)
cmd.Parameters.AddWithValue("#Password", Login1.Password)
cmd.Connection = con
con.Open()
studentId = Convert.ToInt32(cmd.ExecuteScalar())
con.Close()
End Using
Select Case studentId
Case -1
Login1.FailureText = "Username and/or password is incorrect."
Exit Select
Case -2
Login1.FailureText = "Account has not been activated."
Exit Select
Case Else
FormsAuthentication.RedirectFromLoginPage(Login1.UserName, Login1.RememberMeSet)
Exit Select
End Select
End Using
End Sub
End Class
My goal is to either continue using the asp:login controls and figure out how to allow for multiple user redirects after login....OR preferably, authenticate without using the asp:login and use my original HTML and CSS. Here is what I had prior to using the asp control:
<%-- STUDENT LOGIN --%>
<div class="student_login">
<div id="wrapper">
<form name="login-form" class="login-form" action="" method="post">
<div class="header">
<h1>Student Login</h1>
<span>Sign in below to login to start showing your skills, earning money, and gaining valuable experience...and did I mention earning MONEY.</span>
</div>
<div class="content">
<input name="username" type="text" class="input username" placeholder="Username" />
<input name="password" type="password" class="input password" placeholder="Password" />
</div>
<div class="footer">
<input type="submit" name="submit" value="Login" class="button" />
Register
</div>
</form>
</div>
</div><!--close student_login-->
NOTE: This section of code is written within a content placeholder. The master page does have a <form runat="server"></form> tag encompassing the body of the page. I do not have any back code for this particular method as I really have no clue how to authenticate without using the asp:login control and FormsAuthentication. Can someone please help me understand how to accomplish authenticating without the asp:login so that I can keep my nicely designed Login form? And please be generous or kind with the comments/explanation, this is my first login form so I have no experience doing this.

You can use the LayoutTemplate of the Login control to do what you want.
The trick is that you need to use a Literal with the ID of FailureText, the user field is a TextBox with ID of UserName, and another TextBox with the ID of Password.
You also will need to trigger a Login command which could be a Button.
This allows you to customize your own layout, I've done this a few times myself. Below is a quick copy/paste untested version with your HTML as an example.
See an MSDN reference at https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.login.layouttemplate.aspx
<asp:Login ID="Login1" runat="server"
OnAuthenticate="ValidateStudent"
Width="100%">
<LayoutTemplate>
<div class="student_login">
<div id="wrapper">
<asp:Literal ID="FailureText" runat="server"></asp:Literal>
<asp:ValidationSummary ID="vsLogin" runat="server" ValidationGroup="Login" />
<div class="header">
<h1>Student Login</h1>
<span>Sign in below to login to start showing your skills, earning money, and gaining valuable experience...and did I mention earning MONEY.</span>
</div>
<div class="content">
<asp:TextBox id="UserName" runat="server" CssClass="input username" placeholder="Enter your username"></asp:TextBox>
<asp:RequiredFieldValidator id="rfvUserName" runat="server"
ControlToValidate="UserName"
Display="None"
ErrorMessage="Username is required"
ValidationGroup="Login">
</asp:RequiredFieldValidator>
<asp:TextBox id="Password" runat="server" CssClass="input password" TextMode="Password" placeholder="Password"></asp:TextBox>
<asp:RequiredFieldValidator id="rfvPassword" runat="server"
ControlToValidate="Password"
Display="None"
ErrorMessage="Password is required"
ValidationGroup="Login">
</asp:RequiredFieldValidator>
</div>
<div class="footer">
<asp:Button ID="Login" runat="server" CommandName="Login" CssClass="button" Text="Login" ValidationGroup="Login" />
Register
</div>
</div>
</div>
</LayoutTemplate>
</asp:Login>

Related

How to make inline errors read aloud by screen reader tools?

I am doing accessibility testing. I created an email text box and added some validation as well. I want after typing wrong email as I move to next element screen reader should read the inline errors. I came across using aria-describeby and aria-live attribute but don't know how to use it in this code .
<asp:panel defaultbutton="btnEmail" cssclass="row" runat="server">
<biw:labelui associatedcontrolid="TextEmail" text="Email Address" runat="server" />
<biw:textbox id="TextEmail" width="200" runat="server" />
<asp:requiredfieldvalidator controltovalidate="TextEmail" text="*" errormessage="Please enter an e-mail address" display="dynamic" runat="server" />
<biw:emailaddressvalidator controltovalidate="TextEmail" text="*" errormessage="Please enter a valid e-mail address" display="dynamic" runat="server" />
<asp:customvalidator id="EmailValidator" controltovalidate="TextEmail" text="*" display="dynamic" runat="server" />
</asp:panel>
aria-describedby adds additional information to an element. An element usually has a name or label and additionally it can have a description. If your error message is in a separate element, such as a <div> or <span>, you can associate that <div> with the input field.
You code might look something like:
<label for="emailID">email address:</label>
<input id="emailID" aria-describedby="errorMsg">
<div id="errorMsg">invalid email address</div>
Some screen readers will read the aria-describedby after the field's label and others will tell you to hit a shortcut key to hear the description. It's up to the screen reader to decide how to present it to the user.
If the above field were in error, then it should have aria-invalid="true" as well.
<input id="emailID" aria-describedby="errorMsg" aria-invalid="true">
In order for the error message to be announced by screen readers, it should have aria-live="polite".
<div id="errorMsg" aria-live="polite"></div>
When you discover an error, you insert text into the <div> (via javascript) and the screen reader will announce it because it's a live region.
document.getElementById("errorMsg").innerHTML = "invalid email address";

How to create Button_Click() Event for Bootstrap Button?

Bootstrap login form is below:
<form class="form-vertical login-form" runat="server" action="~/Default.aspx">
<label class="control-label visible-ie8 visible-ie9">User Name</label>
<input class="m-wrap placeholder-no-fix" type="text" placeholder="UserName" name="username"/>
<label class="control-label visible-ie8 visible-ie9">Password</label>
<input class="m-wrap placeholder-no-fix" type="password" placeholder="Password" name="password"/>
<button type="submit" class="btn green pull-right" aria-pressed="undefined">
Log In <i class="m-icon-swapright m-icon-white"></i>
</button>
</form>
When the button is clicked, I want to create the connection to the database. So, I need to have sth like this:
protected void (ButtonName)_Click(object sender, EventArgs e)
{
string connStr = "Initial Catalog=LoginCheck; Data Source=MYCOMPUTER; User id=sa; password=000000;";
SqlConnection conn = new SqlConnection(connStr);
conn.Open();
...
}
But it doesn't work like ASP.NET. If I double-click on the button when I am designing, it's not taking me to code behind. Please put me in the right direction!
In ASP.Net, you want to use Server control if you want to post back.
Most of the time, <form> tag is located inside Master Page, so you cannot style it easily.
Here is an example -
<form id="form1" runat="server">
<div class="form-vertical login-form">
<asp:Label runat="server" ID="UsernameLabel"
AssociatedControlID="UserNameTextBox"
CssClass="control-label visible-ie8 visible-ie9">User Name
</asp:Label>
<asp:TextBox runat="server" ID="UserNameTextBox"
CssClass="m-wrap placeholder-no-fix" />
<asp:Label runat="server" ID="PasswordLabel"
AssociatedControlID="PasswordTextBox"
CssClass="control-label visible-ie8 visible-ie9">Password
</asp:Label>
<asp:TextBox runat="server" ID="PasswordTextBox"
CssClass="m-wrap placeholder-no-fix" />
<asp:LinkButton runat="server" ID="SubmitLinkButton"
CssClass="btn btn-default pull-right"
OnClick="SubmitLinkButton_Click">
Log In <i class="m-icon-swapright m-icon-white"></i>
</asp:LinkButton>
</div>
</form>
But it doesn't work like ASP.NET
Your code (aka "code-behind") looks like it expects ASP.Net server controls e.g. <asp:Button runat="server" id="foo"... so it can do a Postback which is the the ASP.NET "web forms" way.
Having said that, you can try
assigning a bootstrap css class to an ASP.net server control to make it look like a bootstrap button (styling)
keep your existing HTML above handle the normal HTTP POST and not deal with server controls (and deal with request.form)
It's your choice based on what works for you. Either way the core concept is based on standard HTTP POST (html form post, asp.net web forms "postback").
Hth...

Client ID is not getting generated for asp.net controls

I am writing a simple webform on .net 4.0 framework.
<body>
<form id="form1" runat="server">
<div>
<span>Name</span>
<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
</div>
<div>
<span>Email</span>
<asp:TextBox ID="txtEmail" EnableViewState="false" runat="server"></asp:TextBox>
</div>
<div>
<asp:Button ID="btnButton" runat="server" Text="Submit" />
</div>
</form>
</body>
Issue is when the form renders on browser, I am not getting ClientID for the server side controls. This is strange for me.
The portion of the markup in the browser is
<div>
<input type="submit" name="btnButton" value="Submit" id="btnButton" />
</div>
Notice there is no clientID.
Edit : Client ID something like 'ctl00$MasterPageBody$ctl00$btnButton2'
The client id of the button is btnButton. The other one "ctl..." is when you have your control inside a masterpage. As a side not: If you don´t wan´t asp.net changing your id:s you can set clientidmode='static'.
ClientID is a server side attribute.
You would see the ClientID on the client as the ID attribute:
id="btnButton"
Client id is calculated on the server, it never gets sent to the client.
You need runat="server" to generate a client ID for the control for the reasons mentioned

How do I retrieve HTML POST data for manipulation in ASP.NET WebForms?

I have the following html:
<html>
<body>
<form runat="server">
Name: <input type="text" name="name" />
<br />
<input type="submit" name="submit" />
</form>
</body>
</html>
How do I retrieve the value in the "name" textbox posted back to the webserver to manipulate in ASP.NET WebForms?
(I know about the ASP.NET built-in controls and the possibilities with them, but I am looking for a "clean" solution without the use of built-in ASP.NET controls)
If you can't, or don't want to use asp.net textboxes, then you can retrieve the name of a regular html textbox like this:
string nameTextPosted = Request.Form["name"];
Just note that textboxes created in this manner will not automatically persist their values across postbacks like asp.net textboxes will.
Simplest solution would be to turn it into a server-side component and access it by it's name. e.g.
<asp:TextBox Id="Name" runat="server"></asp:TextBox>
...
string name = Name.Text;
Unless you have other reasons not to use a component, you'd only be making things much more difficult on your part for no justification.
ASP.net includes Html server controls for backward compatibility for just someone like you fond of html. make your html tags server controls by adding the runat="server" and id properties and you are able to access them inside your server side code with their id.
<form runat="server">
Name: <input type="text" name="name" id="name" runat="server" />
<br />
<input type="submit" name="submit" id="name1" runat="server" />
</form>
Now after this you can control their behavior:
name.Value="Hellow World !"
You have to add id and runat="server" in each control. like this :
<input type="text" name="name" id="name" runat="server" />
Its better to use asp:TextBox like this :
<asp:TextBox ID="name" runat="server"></asp:TextBox>

ASP.NET CustomValidator control interferes with jQuery validation on form submission

I have a simple form that uses jQuery validation to notify the user of input errors, etc. When I add an ASP.NET CustomValidator to the form, it causes the page to postback and skip the jQuery validation. I need the form to not be submitted to the server until the client-validation is correct. Has anyone seen this before?
This is my form:
<form id="form1" runat="server">
<core:standardscriptmanager runat="server" />
<div>
<asp:textbox id="Email" name="Email" runat="server" cssclass="_RegisterFormValidate FormField Email {required:true, email:true, messages:{required:'You must enter an email address.', email:'Please enter a valid email address.'}}" maxlength="200" columns="75" width="98%" tooltip="Your email address"></asp:textbox>
<br /><br />
<core:recaptcha runat="server" />
<br />
<asp:linkbutton id="CreateAccount" runat="server" onclick="CreateAccount_Click" text="create"></asp:linkbutton>
</div>
</form>
And this is the core:recaptcha control that contains the custom validator:
<script type="text/javascript"
src="http://www.google.com/recaptcha/api/challenge?k=XXXKEY">
</script>
<noscript>
<iframe src="http://www.google.com/recaptcha/api/noscript?k=XXXKEY"
height="300" width="500" frameborder="0"></iframe><br>
<textarea name="recaptcha_challenge_field" rows="3" cols="40">
</textarea>
<input type="hidden" name="recaptcha_response_field"
value="manual_challenge">
</noscript>
<asp:customvalidator id="RecaptchaValidator" runat="server" controltovalidate="DummyInput" onservervalidate="ServerValidate" validateemptytext="true" />
<asp:textbox id="DummyInput" runat="server" cssclass="Hidden"></asp:textbox>
Note: The DummyInput is only there to make the CustomValidator happy, my ServerValidate event correctly deals with the captcha results.
The ServerValidate portion of the CustomValidator is working fine during the postback, but I need it to stop interfering with the client-side validation. If I remove the CustomValidator from the recaptcha control, everything plays nice.
Do I need to do something like call jquery-validate in the CustomValidator's clientvalidationfunction in order to make this work correctly?
Any thoughts or suggestions would be welcome.
So it turns out the answer to this issue was to set CausesValidation="False" on my linkbutton and then call Page.Validate() in the linkbutton's OnClick handler.
It's not exactly the solution I was looking for since I'll have to remember to do those things every time I want to use recaptcha (or any custom validator for that matter) but this seems to work for now.
You can set the EnableClientScript property of your validator to false:
<asp:CustomValidator id="RecaptchaValidator" runat="server"
ControlToValidate="DummyInput" OnServerValidate="ServerValidate"
ValidateEmptyText="True" EnableClientScript="False" />

Resources