Do not store password in .net membership - asp.net-mvc-3

I use the built in membership system in a MVC 3 .net application. Later in the developement I will use an external web service for authentication. Hence I would only have to store the (unique) username in the membership system. All other user info can be retrieved through the webservice.
Therefore I wonder how to not store a password?

Don't worry about the storing of the password, just randomly generate and store a password when you create the user.
Have your account controller validate the password against the external webservice in the logon method, if its correct, then simply call FormsAuthentication.SetAuthCookie(userName, false /*persistantCookie*/), which will "login" the user :)
side note:
Have you though about how you will migrate the existing user's to the new external webservice if you only have their password hash/salts?

Not sure if I understand you correctly but I think the best solution to this is writing an custom membership provider. Basically this is just an class with an few functions overriden from the basic membership provider. Here you can implement your own logic for registering, logging in and logging out.
Found an example of an class I used an while back. Just write your own implementation. An other option is to work from your accountcontroller (like haz also mentioned) but I always tend not to implement too much logic into my controllers and let my services handle the business logic.
public class CustomMembershipProvider : MembershipProvider
{
private readonly IGenericService<User> _genericUserService;
public CustomMembershipProvider(IGenericService<User> genericUserService)
{
_genericUserService = genericUserService;
}
public CustomMembershipProvider() : this(new GenericService<User>())
{
}
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
throw new NotImplementedException();
}
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
{
throw new NotImplementedException();
}
public override string GetPassword(string username, string answer)
{
throw new NotImplementedException();
}
public override bool ChangePassword(string username, string oldPassword, string newPassword)
{
throw new NotImplementedException();
}
public override string ResetPassword(string username, string answer)
{
throw new NotImplementedException();
}
public override void UpdateUser(MembershipUser user)
{
throw new NotImplementedException();
}
public override bool ValidateUser(string username, string password)
{
try
{
var encodedPassword = password.AsSha512();
var user = _genericUserService.First(u => u.Email == username && u.Password == string.Empty );
return user != null;
}
catch (Exception)
{
return false;
}
}
public override bool UnlockUser(string userName)
{
throw new NotImplementedException();
}
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
{
throw new NotImplementedException();
}
public override MembershipUser GetUser(string username, bool userIsOnline)
{
var user = _genericUserService.First(x => x.Email.Equals(username));
var a = new MembershipUser("", user.Firstname, user.Id, user.Email, "", "", true, user.Active,
user.RegisteredOn, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now);
return a;
}
public override string GetUserNameByEmail(string email)
{
throw new NotImplementedException();
}
public override bool DeleteUser(string username, bool deleteAllRelatedData)
{
throw new NotImplementedException();
}
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override int GetNumberOfUsersOnline()
{
throw new NotImplementedException();
}
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override bool EnablePasswordRetrieval
{
get { throw new NotImplementedException(); }
}
public override bool EnablePasswordReset
{
get { throw new NotImplementedException(); }
}
public override bool RequiresQuestionAndAnswer
{
get { throw new NotImplementedException(); }
}
public override string ApplicationName
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public override int MaxInvalidPasswordAttempts
{
get { throw new NotImplementedException(); }
}
public override int PasswordAttemptWindow
{
get { throw new NotImplementedException(); }
}
public override bool RequiresUniqueEmail
{
get { throw new NotImplementedException(); }
}
public override MembershipPasswordFormat PasswordFormat
{
get { throw new NotImplementedException(); }
}
public override int MinRequiredPasswordLength
{
get { throw new NotImplementedException(); }
}
public override int MinRequiredNonAlphanumericCharacters
{
get { throw new NotImplementedException(); }
}
public override string PasswordStrengthRegularExpression
{
get { throw new NotImplementedException(); }
}
}

Related

Is there a way to use sql bulk insert without using datatable from generic list?

I have a generic list contains about six and a half million. I would like to insert this generic list to database by using sql bulk insert. But a datatable is necessary for using sql bulk insert. Convert generic list to datatable takes too much time. So how can I use sql bulk insert without using datatable ?
EDIT:
I use MSSQL SERVER and .NET FrameWork
I would like to just use it with a generic list.
I created a custom datareader that have been inherited IDataReader. I have achieved like below :
public class CustomDataReader<T> : IDataReader
{
private readonly IEnumerator<T> list;
private readonly List<PropertyInfo> properties = new List<PropertyInfo>();
public CustomDataReader(IEnumerable<T> list)
{
this.list = list.GetEnumerator();
var props = typeof(T).GetProperties();
foreach (var propertyInfo in props)
{
properties.Add(propertyInfo);
}
}
#region IDataReader Members
public void Close()
{
list.Dispose();
}
public int Depth
{
get { throw new NotImplementedException(); }
}
public DataTable GetSchemaTable()
{
throw new NotImplementedException();
}
public bool IsClosed
{
get { throw new NotImplementedException(); }
}
public bool NextResult()
{
throw new NotImplementedException();
}
public bool Read()
{
return list.MoveNext();
}
public int RecordsAffected
{
get { throw new NotImplementedException(); }
}
#endregion
#region IDisposable Members
public void Dispose()
{
Close();
}
#endregion
#region IDataRecord Members
public int FieldCount
{
get { return properties.Count; }
}
public bool GetBoolean(int i)
{
throw new NotImplementedException();
}
public byte GetByte(int i)
{
throw new NotImplementedException();
}
public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
{
throw new NotImplementedException();
}
public char GetChar(int i)
{
throw new NotImplementedException();
}
public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
{
throw new NotImplementedException();
}
public IDataReader GetData(int i)
{
throw new NotImplementedException();
}
public string GetDataTypeName(int i)
{
throw new NotImplementedException();
}
public DateTime GetDateTime(int i)
{
throw new NotImplementedException();
}
public decimal GetDecimal(int i)
{
throw new NotImplementedException();
}
public double GetDouble(int i)
{
throw new NotImplementedException();
}
public Type GetFieldType(int i)
{
return properties[i].PropertyType;
}
public float GetFloat(int i)
{
throw new NotImplementedException();
}
public Guid GetGuid(int i)
{
throw new NotImplementedException();
}
public short GetInt16(int i)
{
throw new NotImplementedException();
}
public int GetInt32(int i)
{
throw new NotImplementedException();
}
public long GetInt64(int i)
{
throw new NotImplementedException();
}
public string GetName(int i)
{
return properties[i].Name;
}
public int GetOrdinal(string name)
{
throw new NotImplementedException();
}
public string GetString(int i)
{
throw new NotImplementedException();
}
public object GetValue(int i)
{
return properties[i].GetValue(list.Current, null);
}
public int GetValues(object[] values)
{
throw new NotImplementedException();
}
public bool IsDBNull(int i)
{
throw new NotImplementedException();
}
public object this[string name]
{
get { throw new NotImplementedException(); }
}
public object this[int i]
{
get { throw new NotImplementedException(); }
}
#endregion
}
public static void BulkInsert<T>(this IEnumerable<T> list, string connStr, string tableName)
{
using (var reader = new CustomDataReader<T>(list))
{
using (var conn = new SqlConnection(connStr))
{
using (var sbc = new SqlBulkCopy(conn))
{
conn.Open();
sbc.DestinationTableName = tableName;
sbc.WriteToServer(reader);
conn.Close();
}
}
}
}

How to customize authentication to my own set of tables in asp.net web api 2?

In the default AccountController created I see
public AccountController()
: this(Startup.UserManagerFactory(), Startup.OAuthOptions.AccessTokenFormat)
{
}
In Startup.Auth.cs I see
UserManagerFactory = () =>
new UserManager<IdentityUser>(new UserStore<IdentityUser>());
Seems like the implementation of UserStore comes from Microsoft.AspNet.Identity.EntityFramework.
So, to customize the authentication do I have to implement my own version of UserStore like
class MYSTUFFUserStore<IdentityUser> : UserStore<IdentityUser>
{
}
and override the methods and then do this in Startup.Auth.cs
UserManagerFactory = () =>
new UserManager<IdentityUser>(new MYSTUFFUserStore<IdentityUser>());
I am looking for a correct way to customize the authentication.
Assuming your table is called AppUser, convert your own AppUser domain object to IUser(using Microsoft.AspNet.Identity) like this
using Microsoft.AspNet.Identity;
public class AppUser : IUser
{
//Existing database fields
public long AppUserId { get; set; }
public string AppUserName { get; set; }
public string AppPassword { get; set; }
public AppUser()
{
this.Id = Guid.NewGuid().ToString();
}
[Ignore]
public virtual string Id { get; set; }
[Ignore]
public string UserName
{
get
{
return AppUserName;
}
set
{
AppUserName = value;
}
}
}
Implement the UserStore object like this
using Microsoft.AspNet.Identity;
public class UserStoreService
: IUserStore<AppUser>, IUserPasswordStore<AppUser>
{
CompanyDbContext context = new CompanyDbContext();
public Task CreateAsync(AppUser user)
{
throw new NotImplementedException();
}
public Task DeleteAsync(AppUser user)
{
throw new NotImplementedException();
}
public Task<AppUser> FindByIdAsync(string userId)
{
throw new NotImplementedException();
}
public Task<AppUser> FindByNameAsync(string userName)
{
Task<AppUser> task = context.AppUsers.Where(
apu => apu.AppUserName == userName)
.FirstOrDefaultAsync();
return task;
}
public Task UpdateAsync(AppUser user)
{
throw new NotImplementedException();
}
public void Dispose()
{
context.Dispose();
}
public Task<string> GetPasswordHashAsync(AppUser user)
{
if (user == null)
{
throw new ArgumentNullException("user");
}
return Task.FromResult(user.AppPassword);
}
public Task<bool> HasPasswordAsync(AppUser user)
{
return Task.FromResult(user.AppPassword != null);
}
public Task SetPasswordHashAsync(AppUser user, string passwordHash)
{
throw new NotImplementedException();
}
}
If you have your own custom password hashing you will also need to implement IPasswordHasher. Below is an example where there is no hashing of the password(Oh no!)
using Microsoft.AspNet.Identity;
public class MyPasswordHasher : IPasswordHasher
{
public string HashPassword(string password)
{
return password;
}
public PasswordVerificationResult VerifyHashedPassword
(string hashedPassword, string providedPassword)
{
if (hashedPassword == HashPassword(providedPassword))
return PasswordVerificationResult.Success;
else
return PasswordVerificationResult.Failed;
}
}
In Startup.Auth.cs replace
UserManagerFactory = () =>
new UserManager<IdentityUser>(new UserStore<IdentityUser>());
with
UserManagerFactory = () =>
new UserManager<AppUser>(new UserStoreService()) { PasswordHasher = new MyPasswordHasher() };
In ApplicationOAuthProvider.cs, replace IdentityUser with AppUser
In AccountController.cs, replace IdentityUser with AppUser and delete all the external authentication methods like GetManageInfo and RegisterExternal etc.

Trying to call code in my controller but getting Null Reference error

Don't want to over-complicate the issue, but I think I need to post all the code that's hooked into this error.
Using MvcMailer and introduced a separate Send mechanism (for use with Orchard CMS' own EMail).
The MvcMailer Code:
1) AskUsMailer.cs:
public class AskUsMailer : MailerBase, IAskUsMailer
{
public AskUsMailer()
: base()
{
//MasterName = "_Layout";
}
public virtual MvcMailMessage EMailAskUs(AskUsViewModel model)
{
var mailMessage = new MvcMailMessage { Subject = "Ask Us" };
ViewData.Model = model;
this.PopulateBody(mailMessage, viewName: "EMailAskUs");
return mailMessage;
}
}
2) IAskUsMailer.cs:
public interface IAskUsMailer : IDependency
{
MvcMailMessage EMailAskUs(AskUsViewModel model);
}
3) AskUsController.cs: (GETTING NULL REFERENCE ERROR BELOW)
[Themed]
public ActionResult Submitted()
{
//This is the new call (see new code below):
//Note: Debugging steps through eMailMessagingService,
//then shows the null reference error when continuing to
//SendAskUs
eMailMessagingService.SendAskUs(askUsData);
//Below is normal MvcMailer call:
//AskUsMailer.EMailAskUs(askUsData).Send();
return View(askUsData);
}
Note: askUsData is defined in a separate block in the controller:
private AskUsViewModel askUsData;
protected override void OnActionExecuting(ActionExecutingContext
filterContext)
{
var serialized = Request.Form["askUsData"];
if (serialized != null) //Form was posted containing serialized data
{
askUsData = (AskUsViewModel)new MvcSerializer().
Deserialize(serialized, SerializationMode.Signed);
TryUpdateModel(askUsData);
}
else
askUsData = (AskUsViewModel)TempData["askUsData"] ??
new AskUsViewModel();
TempData.Keep();
}
protected override void OnResultExecuted(ResultExecutedContext
filterContext)
{
if (filterContext.Result is RedirectToRouteResult)
TempData["askUsData"] = askUsData;
}
I did not know how to get my EMailMessagingService.cs (see below) call into the controller, so in a separate block in the controller I did this:
private IEMailMessagingService eMailMessagingService;
public AskUsController(IEMailMessagingService eMailMessagingService)
{
this.eMailMessagingService = eMailMessagingService;
}
I think this is part of my problem.
Now, the new code trying to hook into Orchard's EMail:
1) EMailMessagingServices.cs:
public class EMailMessagingService : IMessageManager
{
private IAskUsMailer askUsMailer;
private IOrchardServices orchardServices;
public EMailMessagingService(IAskUsMailer askUsMailer,
IOrchardServices orchardServices)
{
this.orchardServices = orchardServices;
this.askUsMailer = askUsMailer;
this.Logger = NullLogger.Instance;
}
public ILogger Logger { get; set; }
public void SendAskUs(AskUsViewModel model)
{
var messageAskUs = this.askUsMailer.EMailAskUs(model);
messageAskUs.To.Add("email#email.com");
//Don't need the following (setting up e-mails to send a copy anyway)
//messageAskUs.Bcc.Add(AdminEmail);
//messageAskUs.Subject = "blabla";
Send(messageAskUs);
}
....
}
The EMailMessagingService.cs also contains the Send method:
private void Send(MailMessage messageAskUs)
{
var smtpSettings = orchardServices.WorkContext.
CurrentSite.As<SmtpSettingsPart>();
// can't process emails if the Smtp settings have not yet been set
if (smtpSettings == null || !smtpSettings.IsValid())
{
Logger.Error("The SMTP Settings have not been set up.");
return;
}
using (var smtpClient = new SmtpClient(smtpSettings.Host,
smtpSettings.Port))
{
smtpClient.UseDefaultCredentials =
!smtpSettings.RequireCredentials;
if (!smtpClient.UseDefaultCredentials &&
!String.IsNullOrWhiteSpace(smtpSettings.UserName))
{
smtpClient.Credentials = new NetworkCredential
(smtpSettings.UserName, smtpSettings.Password);
}
if (messageAskUs.To.Count == 0)
{
Logger.Error("Recipient is missing an email address");
return;
}
smtpClient.EnableSsl = smtpSettings.EnableSsl;
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
messageAskUs.From = new MailAddress(smtpSettings.Address);
messageAskUs.IsBodyHtml = messageAskUs.Body != null &&
messageAskUs.Body.Contains("<") &&
messageAskUs.Body.Contains(">");
try
{
smtpClient.Send(messageAskUs);
Logger.Debug("Message sent to {0} with subject: {1}",
messageAskUs.To[0].Address, messageAskUs.Subject);
}
catch (Exception e)
{
Logger.Error(e, "An unexpected error while sending
a message to {0} with subject: {1}",
messageAskUs.To[0].Address, messageAskUs.Subject);
}
}
}
Now, in EMailMessagingService.cs I was getting an error that things weren't being implemented, so I auto-generated the following (don't know if this is part of my error):
public void Send(Orchard.ContentManagement.Records.ContentItemRecord recipient, string type, string service, System.Collections.Generic.Dictionary<string, string> properties = null)
{
throw new NotImplementedException();
}
public void Send(System.Collections.Generic.IEnumerable<Orchard.ContentManagement.Records.ContentItemRecord> recipients, string type, string service, System.Collections.Generic.Dictionary<string, string> properties = null)
{
throw new NotImplementedException();
}
public void Send(System.Collections.Generic.IEnumerable<string> recipientAddresses, string type, string service, System.Collections.Generic.Dictionary<string, string> properties = null)
{
throw new NotImplementedException();
}
public bool HasChannels()
{
throw new NotImplementedException();
}
public System.Collections.Generic.IEnumerable<string> GetAvailableChannelServices()
{
throw new NotImplementedException();
}
2) IEMailMessagingServices.cs
public interface IEMailMessagingService
{
MailMessage SendAskUs(AskUsViewModel model);
}
MvcMailer works fine without this addition (outside of Orchard), but I am trying to get everything working within Orchard.
I just cannot figure out what I am doing wrong. Any thoughts?
Sorry for excessive code.
IEmailMessaginService does not implement IDependency, so it can't be found by Orchard as a dependency. That's why it's null.

Custom Login for MVC3 application

I want to build a website that displays user-specific information (e.g. user sees her own records when she logs in). I don't want to use MVC3 Internet Application with default Membership provider as I would like to experience building my own authentication. I found some links on the web but feel that I need more sources to read from.
My project is MVC3, Entity Framework with code first. Thank you,
Desciption
You can implement your own custom MemberShip Provider with your own logic.
More Information
ASP.NET MVC 2 Custom Membership Provider Tutorial
Codeplex: Custom Membership Providers
Using a Custom Membership Provider in an MVC Application
MSDN: Implementing a Membership Provider
I recently did a similar thing - we have an application written in classic ASP and I wanted to authenticate with .NET using the existing database tables at the same time (for anyone who's interested I first logged the user into the classic ASP side then posted their details to the .NET logon form causing it to do its own login process).
Pretty much everything I found suggested just writing my own MemberShip Provider (as suggested by (dknaack) and IPrincipal object to allow me to add additional fields I wanted (it was easier than extending the profile data).
It was actually very easy in the end; I didn't bother implementing all of the MembershipProvider functions because I didn't need them. Here I just use Entity framework to check if the username/password are valid but clearly you could use whatever you wanted.
Here's a dump of my code to get you started:
using System;
using System.Collections.Specialized;
using System.Linq;
using System.Security.Principal;
using System.Web.Security;
using My.Company.Project.Entities;
namespace My.Company.Project.Classes
{
public class ClassicMembershipProvider : MembershipProvider
{
public override void Initialize(string name, NameValueCollection config)
{
base.Initialize(name, config);
}
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
throw new NotImplementedException();
}
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
{
throw new NotImplementedException();
}
public override string GetPassword(string username, string answer)
{
throw new NotImplementedException();
}
public override bool ChangePassword(string username, string oldPassword, string newPassword)
{
throw new NotImplementedException();
}
public override string ResetPassword(string username, string answer)
{
throw new NotImplementedException();
}
public override void UpdateUser(MembershipUser user)
{
throw new NotImplementedException();
}
public override bool ValidateUser(string username, string password)
{
using (var entities = new ProjectEntities())
{
return entities.Buprofile
.Where(p => p.profileid == username &&
p.profilepassword == password)
.Count() == 1;
}
}
public override bool UnlockUser(string userName)
{
throw new NotImplementedException();
}
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
{
throw new NotImplementedException();
}
public override MembershipUser GetUser(string username, bool userIsOnline)
{
throw new NotImplementedException();
}
public override string GetUserNameByEmail(string email)
{
throw new NotImplementedException();
}
public override bool DeleteUser(string username, bool deleteAllRelatedData)
{
throw new NotImplementedException();
}
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override int GetNumberOfUsersOnline()
{
throw new NotImplementedException();
}
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override bool EnablePasswordRetrieval
{
get { return false; }
}
public override bool EnablePasswordReset
{
get { return false; }
}
public override bool RequiresQuestionAndAnswer
{
get { return false; }
}
public override string ApplicationName
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public override int MaxInvalidPasswordAttempts
{
get { throw new NotImplementedException(); }
}
public override int PasswordAttemptWindow
{
get { throw new NotImplementedException(); }
}
public override bool RequiresUniqueEmail
{
get { return true; }
}
public override MembershipPasswordFormat PasswordFormat
{
get { throw new NotImplementedException(); }
}
public override int MinRequiredPasswordLength
{
get { throw new NotImplementedException(); }
}
public override int MinRequiredNonAlphanumericCharacters
{
get { throw new NotImplementedException(); }
}
public override string PasswordStrengthRegularExpression
{
get { throw new NotImplementedException(); }
}
}
}
You can hook it up by adding/updating in your web.config:
<membership defaultProvider="ClassicMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="ClassicMembershipProvider" type="My.Company.Project.Classes.ClassicMembershipProvider" applicationName="MyApplication" />
</providers>
</membership>
I also created a custom IPrincipal (based on http://blog.codevelop.dk/post/2007/11/24/ASPNET-20-Forms-authentication-Keeping-it-customized-yet-simple.aspx) which allows you to store various bits of data about the user in a UserData property (as mentioned, it looked far easier this way than to extend the user profile).
You can access UserData of a user once logged in by casting User: ((MyPrincipal)User).UserData - I overode the User property in my page base class so I could just use User. in future though:
/// <summary>
/// Override User and return a MyPrincipal with its additional data
/// </summary>
public new MyPrincipal User
{
get { return HttpContext.Current.User is MyPrincipal ? (MyPrincipal) HttpContext.Current.User : null; }
}
In the end this was pretty pain-free, and far less hassle than writing my own from scratch yet I still have all the control I need.

How to create custom JsonAuthorize Attribute to secure actions which returns JsonResults?

I was thinking how to correctly secure JsonResult action with custom attribute instead of doing kind of this on each action like saying here ASP.NET MVC JsonResult and AuthorizeAttribute
if (!User.Identity.IsAuthenticated)
return Json("Need to login");
But the question is how could i create such attribute which would return Json.
So i've started from that:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class JsonAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
IPrincipal user = httpContext.User;
if (!user.Identity.IsAuthenticated)
{
//?
}
//Need to return json somehow ?
}
}
Bot how i may return json result from such attribute? any ideas?
You can use an ActionFilterAttribute which allows you to return a result without using the httpcontext.response.write or anything.
public class JsonActionFilterAttribute : ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext filterContext) {
if (!HttpContext.Current.User.Identity.IsAuthenticated) {
filterContext.Result = new JsonResult() { Data = "Need to login." };
}
base.OnActionExecuting(filterContext);
}
}
1 way is to override AuthorizeAttribute.HandleUnauthorizedRequest
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
throw new CustomUnauthorizedException();
}
... And then in your Global.asax:
protected void Application_Error(object sender, EventArgs e)
{
Exception error = Server.GetLastError();
if (error is CustomUnauthorizedException) {
if (AjaxRequest(Request)) {
... return Json response.
} else {
... redirect
}
}
}
So you can throw the exception anywhere in your codebase and you've centralized the handling of that exception in Global.asax
Try this.. it works for me
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
dynamic ResponseObj = new JObject();
ResponseObj.Message = "Authorization has been denied for this request.";
string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(ResponseObj);
actionContext.Response = new HttpResponseMessage
{
StatusCode = HttpStatusCode.Unauthorized,
Content = new StringContent(jsonString, System.Text.Encoding.UTF8,"application/json")
};
}

Resources