I'm trying to implement a very simple login system for a webapi backend. The site will only have one login, which is an admin, which will allow create/update/delete actions.
For this reason, I'm trying to implement a simple login with usernames and passwords coded directly into the pages in C#.
Here's how I want it to work:
On the Login.aspx page, the user enters the username and password to a form, which gets sent to the server via a webmethod:
[WebMethod]
public static something Login(string username, string password)
{
if (username == "bob" && password == "password")
{
*Send some response indicating authentication success*
}
}
This response needs to be something I can obtain from the client-side. Ideally, I'd like to be able to grab it using javascript. Is this possible using WebMethod? And I'm not sure what the method signature should be like.. I assume it would be "public static something methodName" but I'm not sure what that something would be.
Basically, If the user login is a success, I'll pass back a string such as "A(#I#ASGJAWIAW", the client will cache it in the browser, and from there, when they need to make any CREATE, UPDATE, or DELETE requests, they will also send in that value to the webapi methods. The webapi methods will determine whether the have the correct value before running the action.
Does anyone have any experience doing something like this?
If you can use jQuery, you can make a simple call to the WebMethod. Make sure your webmethod returns a String.
ajaxreq = $.ajax({
type: "POST",
url: "LoginService.asmx/Login",
data: "{'username':'" + $('#txtUser').val().trim() + "','password':'" + $('#txtPwd').val()+"'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess
});
function OnSuccess(data, status) {
// Check response from server here and do your stuff here...
}
In the above code, txtUser and txtPwd are the textboxes where it picks up the up the User Name and Password supplied by the user.
Related
I am trying to incorporate a Edit Form page using GetAsync and PostAsync using typed httpclient. Everything works except my code doesn't call API actions with ValidateAntiForgeryToken. Most of the examples online do not address httpcontent used by httpclientfactory and instead use httpresponse. I am aware that the antiforgery token is missing on my request. How do I attach it to the request header? How do I retrieve it from the view? I want to use as less Javascript as possible. Here's a snippet of my Post request service.
Edit: For what it's worth, my api is dot net core and client is dot net core mvc.
var response = await _httpclient.PostAsync("api/edit/" + id, httpcontent);
response.EnsureSuccessStatusCode(); ```
In the MVC Edit view page, it will use a hidden file (named __RequestVerificationToken) to store the ValidateAntiForgeryToken, you can use F12 developer tools to check it.
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
After modifying the data, you could use JQuery to get the updated data, then use JQuery ajax to call the API method with the ValidateAntiForgeryToken. You can refer the sample code in my reply:
if we customize antiforgery options in Startup.ConfigureServices, such as: custom the Header Name for the RequestVerificationToken.
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN"); //configure the antiforgery service to look for the X-CSRF-TOKEN header. To prevent the cross-site request forgery.
Then, we could use the following script:
$.ajax({
type: "POST",
url: "/Survey/Create",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: { "CategoryName": $("#CategoryName").val(), "CategoryID": $("#CategoryID").val() },
success: function (response) {
alert(response);
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
Besides, you can also refer Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core.
I use interceptor to check if a user is logged in every controller call like this :
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) {
if(request.getSession().getAttribute("user") == null) {
response.sendRedirect("redirect:/login?next="+
URLEncoder.encode(
request.getRequestURL().toString() + "" +
(request.getQueryString() != null ? "?" + request.getQueryString() : "")
,"utf-8");
return false;
}
return true;
}
It work fine for normal request but for ajax request i can't make a response.sendRedirect(..).
How to know if it's a ajax or normal request ?
How can i do it like if i got a ajax error ?
$.ajax({
.....
success : function(data) { ...... },
error : function(){
alert("login error"); // or
document.location = '/path/login' // or something else
}
});
There a other way to handle it rather than using interceptor ?
1. How to know if it's a ajax or normal request ?
You can check inside your interceptor for the existence of the X-Requested-With header. This header is always added to the ajax request by the jQuery library (to my knowing almost all major js libraries add it as well) with the purpose of preventing the Cross-Site request forgery. To figure out if the request is ajax, you can write your preHandle method like
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) {
String requestedWith = request.getHeader("X-Requested-With");
Boolean isAjax = requestedWith != null ? "XMLHttpRequest".equals(requestedWith) : false;
...
}
2. How can i do it like if i got a ajax error ?
As you've already noticed, ajax request don't recognize server side redirects, as the intention of the server side redirects is to be transparent to the client. In the case of an ajax request, don't do redirect rather set some status code to the response e.g. response.setStatus(respCode) or add a custom header e.g. response.setHeader("Location", "/path/login"), and read it through in the jQuery's complete method which is a callback that follows after either success or error, e.g.
$.ajax({
//...
complete: function(xhr, textStatus) {
console.log(xhr.status);
console.log(xhr.getResponseHeader('Location'));
// do something e.g. redirect
}
});
3. There a other way to handle it rather than using interceptor ?
Definitely. Checkout Spring Security. Its a framework, and adds a bit to the learning curve, but its well worth it. It will add much more than a custom solution, e.g. you'll get authorization mechanism on top of the authentication. When your application matures, you'll notice that the straigthforward implementation that you're on to now, has quite a few security flaws that are not hard to exploit e.g. session fixation, where spring security can easily protect you. There's plenty of examples online, and you'll get better support here on the SO in comparison to any custom solution. You can unit test it, an asset I personally value very much
You could simply:
Refuse ajax requests before the user is properly logged in
once the user logs in, set a security token in the session or somewhere
pass that token in the ajax request and use that token to validate on the server side prehandle
in your case you would check the existence of the token before running into the code
Also, the preHandle does not have to apply to every routes, you could also have different routes each with different authorisation, prehandle, code.
just been trying to recieve the session value from multiple jquery ajax requests on the same domain name. i think i understand that each request is kind of a virtual browser request so the session is mutally exclusive to each request, but there must be a way some how, has anyone solved this. Basically this is what im trying to do:
I have tries using type: GET and POST but still no luck.
Can anyone help please, Thanks?
First request - Stores the product id in a session
$.ajax({
url: 'http://localhost/websitetest/test.aspx?storeproduct=' + productid,
type: 'GET',
async: true,
success: function(data) {
}
});
Second Request - From the callback variable "data" recieves the product id from the session
$.ajax({
url: 'http://localhost/websitetest/test.aspx,
type: 'GET',
async: true,
success: function(data) {
var productID = data;
}
});
There is no question to send ajax request while accessing Session variable from asp page.
Simply you can do is :
<%
String session_var = Session("name_of_session_variable");
%>
Even if you still want to try Ajax, I think you will need to print the session variable in test.aspx file using Response.Write(), which will automatically return the content.
Please check this for further reference.
Please correct me as well if I am wrong.
Thank you.
I'm trying to figure out how to implement an AJAX login for a ASP.NET 2.0 site with Jquery. I already have a implemented other simple Jquery AJAX application on the site, but I'm unsure how to convert over the standard login control to POST via AJAX. Should I expose the login.aspx page methods? Any help would be great.
Here are some ideas on how this can be implemented. This is not full code, but it should be enough to get you started on the right track.
You need to create your own login form fields for username/password.
Create an ASMX or WCF WebService for authentication with a method similar to this:
[WebMethod]
public string AuthenticateUser(string username, string password)
{
string result = "Invalid Username or Password";
if(Membership.ValidateUser(userName, password))
{
FormsAuthentication.SetAuthCookie(u.UserName, false);
result = "successful";
}
return result;
}
Then from your login button's click event you can use jQuery ajax to post the username/password to the webservice:
$.ajax({
type: "POST",
url: "WebService.asmx/AuthenticateUser",
data: "{username:"+$('#txtUsername').val()+",password:"+$('#txtPassword').val()+"}",
success: function(result) {
alert(result);
//if(result=='successful')
// redirectUser to the home page
}
});
With this solution there is a big security problem that username and password will be send in plain-text format. so you should use SSL or hash these data in some way.
take a look here
I am trying to figure out how to get the parameters that are passed in the URL from a jQuery plugin that I am using. Basically, I'm sending a POST ajax request to my web service and trying to use the URL parameters, but they are always returned as nothing. I'm assuming this has to do with the fact that I'm in a POST.
Can anyone please provide some insight for me on how to accomplish this?
I'm unsure why you're choosing to use querystring parameters on an AJAX call. Unless there's a very specific reason, you should just post them as parameters to your web service method instead.
If you're using asp.net WebForms, I recommend using the ScriptManager to generate a javascript proxy to your web-service, and then use that javascript proxy instead of manually doing an ajax call. Here's a quick tutorial/walk-through on using ScriptManager with web services: http://msdn.microsoft.com/en-us/magazine/cc163354.aspx
Something roughly like this:
// in html you have this
<script src="WebService.asmx/jsdebug" type="text/javascript"></script>
// csharp web-service like this
[WebMethod]
public int Add(int a, int b) { return a + b; }
// further javascript to call it
function CallAdd()
{
// method will return immediately
// processing done asynchronously
WebService.Add(0,6, OnMethodSucceeded, OnMethodFailed);
}
This should eliminate the need to post parameters via query-string, which is typically not supported in a soap environment, as the service expects a well-formed soap message.
Hi I'm using the jQuery jqGrid plugin and by default it posts 5 or 6 parameters to the url. I was having trouble getting to those parameters and from looking at some of the php examples, it showed the method grabbing the parameters from the Form variables...I was just trying to see if there was a way I could do that. I'll see what I can do about posting them as parameters. . . just for giggles, is there a way that I would or could do this though?
I'm having a similar problem.
I'm using jQuery/json and POSTing back to a C#/Webservice. I don't know how to read the json variable I created.
Here's the client side(on a user control):
<script type="text/javascript" language="javascript">
function DoLogin()
{
var un = document.getElementById('UserNameText').value;
var pw = document.getElementById('PasswordText').value;
var info = "{ 'UserName':'" + un + "', 'Password':'" + pw + "'}";
$.ajax(
{
type: "POST",
url: "http://localhost:60876/Sitefinity/Services/Login/Login.asmx/LoginSpecial",
dataType: 'json',
data: info,
contentType: "application/json; charset=utf-8",
success: function (msg) { alert(msg.d); },
error: function (msg) { alert(msg.responseText); }
});
}
</script>
Here's the web service side:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class Login : System.Web.Services.WebService
{
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
[WebMethod]
public string LoginSpecial()
{
// read the json variables: UserName, Password.
string un = HttpContext.Current.Request["UserName"] != null ? HttpContext.Current.Request["UserName"].ToString() : String.Empty;
// the previous isn't working for some reason.
return "Some message here";
}
}
I'm getting to the webservice but I need the Username/Password from json to do some validation.
for ASP.NET....
you can get the POST parameters with Request["paramName"];
If your using a GET request with query string parameters then
Request.QueryString["paramName"];
string parameter = HttpUtility.ParseQueryString(HttpContext.Current.Request.UrlReferrer.Query).Get("param1");