Log failed IIS login (windows authentication) - c#

In our application, we offer the use of Windows authentication. For this, the browser pops-up a window. When a user is logged in correctly, I can log this in the code after this:
if (HttpContext.Current.User.Identity.IsAuthenticated) c.Response.Redirect(General.PathPrefix() + "Default.aspx");
My question is, how can I log a user not getting authenticated, all code seems to stop when the login fails, and I get a 401 response.

You can log this error in the Global.asax file using the code below
public class CoolMvcApplication : System.Web.HttpApplication
{
protected void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
//check here if this exception is an unauthorized access error, if so
Server.ClearError();
Response.Redirect("/not_loggedin");
}
}
Also you can achieve this by using filters and assert there if the error is unauthorized access and follow the same logic.

Related

Losing USER information in ELMAH when using ADFS

I have an MVC web application using ELMAH to log unhandled exception. I'm now moving from windows authentication to ADFS authentication. The application has been adapted and is working fine. However now when I check the error, the user information is not there anymore. Which makes sense as ELMAH is using the context identity and not the claims to retrieve this info. Does anyone of you have an idea how I could do to get this information logged again?
You can enrich ELMAH errors using error filtering hook if you can accept a small hack. In short, you need to implement the ErrorLog_Filtering method in the Global.asax.cs file:
void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs args)
{
var httpContext = args.Context as HttpContext;
if (httpContext != null)
{
var error = new Error(args.Exception, httpContext);
error.User = GetUserFromDatabase();
ErrorLog.GetDefault(httpContext).Log(error);
args.Dismiss();
}
}
In the example, I update the User property with the value of a dummy method. How you want to implement this depends on how you would get the currently logged in user from ADFS. Finally, I log the error again and dismiss the initial (user-less) error.

Should a web api return status errors to the client applications?

Please see the code below:
public async Task<List<Person>> GetAllPeople()
{
var uri = API.People.GetAllPeople(_remoteServiceBaseUrl);
try
{
var responseString = await _httpClient.GetStringAsync(uri);
var response = JsonConvert.DeserializeObject<List<Person>>(responseString);
return response;
}
catch (Exception e)
{
//Redirect to error webpage
}
}
I am using Identity Server 4 for authentication and authorisation facilities in the web app and web api.
Say the Web API requires administrator users only and the user calling the web api is not an administrator, then a HttpRequestException is caught by the MVC caller. How should this scenario be handled? Is it enough just to put an Administrator Authorize attribute on the MVC method (GetAllPeople) and forget it or is there a more elegant way to do this i.e. remove the try catch?
It is not convenient to redirect user to error page in every method. You can add exception handler middleware to pipeline and configure it to catch error, log it and show default error page. Read this for more details:
UseExceptionHandler Method
StatusCodePagesExtensions.UseStatusCodePagesWithReExecute
As for you main question - it will be enough to user AuthorizeAttribute in case if default error handling is properly configured.

validating my mvc error handling

I have this in place in global.asax, and I was hoping some folks could tell me if I'm making any glaring mistakes. This my first MVC application.
protected void Application_Error(object sender, EventArgs e)
{
if (HttpContext.Current.IsDebuggingEnabled)
{
throw Server.GetLastError();
}
Exception exception = Server.GetLastError();
Response.Clear();
//here I email (exception.ToString()) to a helpdesk system.
Server.ClearError();
Response.Redirect("/Error/");
}
Basically I wanted something that would:
a) Let me get the raw thrown exception when in debug.
b) In production, send the exception to a logging service / helpdesk app.
c) In production, hide the exception from the user and present a simple error page.
So far it seems to work just fine but was just curious if there's anything wrong with my approach.
Please refer custome error configuration in web config

Basic authentication on a remote server

I need some help with ASMX web-services.
Let's suppose I have a ServerService which provides some data. Let's suppose it has a method GetRandomInteger which returns a random integer (obviously). It implements a custom basic authentication using IHttpModule.
public class BasicAuthHttpModule : IHttpModule
{
private UserRepository _userRepository;
public void Dispose()
{
}
public void Init(HttpApplication application)
{
_userRepository = new UserRepository();
application.AuthenticateRequest += OnAuthenticateRequest;
application.EndRequest += OnEndRequest;
}
public void OnAuthenticateRequest(object source, EventArgs e)
{
var app = (HttpApplication)source;
string authHeader = app.Request.Headers["Authorization"];
if (!string.IsNullOrEmpty(authHeader))
{
// Here I successfully get credentials from header
if (_userRepository.ValidateUser(username, password)) return;
// Return 401 and CompleteRequest
}
else
{
// Return 401 and End
}
}
public void OnEndRequest(object source, EventArgs eventArgs)
{
if (HttpContext.Current.Response.StatusCode == 401)
{
// Return 401 and require new authorization
}
}
Fortunately, it works. Now I can successfully open Service.asmx file, get basic authentication window and get access to it's GetRandomInteger method after successful authentication.
Now I have an ASP.NET MVC 4 application called ClientService. It must provide user interface with convenient and appropriate access to methods of ServerService. Now it has default controllers like Account and Home, default views etc.
I need this ClientService to authenticate on a ServerService. I mean there will be a Home/Index page with button "Login". I enter login and password there and ClientService tries to authenticate at ServerService. It returns error on fail or authenticates on success providing access to some Home/RandomInt page which will show the integer requested from ServerService. What is the best and the easiest way to do this?
How to implement registration on a ServerService? There is no AllowAnonymous attribute or something at ASMX, so I can't register user because he doesn't have access to any of methods due to 401 error.
Thank you in advance.
P.S. No. I can't use WCF or something else. I need to implement an ASMX web-service.
Update 1: OK, I have learned something new from here
http://www.aspsnippets.com/Articles/How-to-add-reference-of-Web-Service-ASMX-in-ASPNet-using-Visual-Studio.aspx
There is an old-style thing like "Web reference" and it's not an "Service reference". I have added this Web reference to my project and now I can call some methods from this ASMX page in this way:
try
{
ServerService svc = new ServerService();
svc.Credentials = new NetworkCredential("user", "password");
int a = svc.GetRandomInteger();
} catch (WebException e) {
// Auth failed
}
However, I don't understand how to link it with ASP.NET MVC ClientService authentication. So, both questions are still open. Hopefully, I will understand it or you will help me.
Here is a documentation for adding a Web reference to an ASMX Service.
http://www.aspsnippets.com/Articles/How-to-add-reference-of-Web-Service-ASMX-in-ASPNet-using-Visual-Studio.aspx
Using this information I can easily make requests to a web service.
The only thing I left to do on the moment of question update is to create a custom authentication.
When user logins, the client sends a request to a service. In case of successful basic authentication, it creates proper FormsAuthentication cookie ticket for a user. User logs in.
On each request to a service, the client extracts login from FormsAuthentication cookie and his password from server cache and uses them to authenticate on a service. In case of basic auth failure (it can only occur if user's password has been changed on the service side) the cookie is cleared and session is aborted.
Registration is implemented using another one ASMX service which is not using basic auth but is anonymous (because registration is supposed to be anonymous method).
That's it. Finally, I have found a proper solution :)

ASP.Net simple login page

I am trying to make a simple log in page in ASP.net and this is my code:
protected void Submit1_Click(object sender, EventArgs e)
{
// Validate the user against the Membership framework user store
if (Membership.ValidateUser(UserName.Text, Password.Text))
{
// Log the user into the site
FormsAuthentication.RedirectFromLoginPage(UserName.Text, Persist.Checked);
Response.Redirect("test-records.aspx");
}
// If we reach here, the user's credentials were invalid
Msg.Visible = true;
}
I don't know whats wrong because it shows no error and it just refreshes with no error
even the label msg is not visible.
If your using a MembershipProvider, and since it seems that there is nothing special have been done in your code, why not use the Login Control, and give it the membership provider class, and thats it!.

Categories