1

I am extremely confused about how the actual authentication works so that [Authorize] does not redirect me to the login page.

Here's my Configuration:

public class IdentityConfig
{
    public void Configuration(IAppBuilder app)
    {
        app.CreatePerOwinContext(() => new MyANTon.DataContext.AntContext());
        app.CreatePerOwinContext<UserManager>(UserManager.Create);
        app.CreatePerOwinContext<RoleManager<AppRole>>((options, context) =>
            new RoleManager<AppRole>(
                new RoleStore<AppRole>(context.Get<MyANTon.DataContext.AntContext>())));

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Home/Login"),
        });
    }
}

In the controller, I want to call an Authenticate(string Email, String Password) method, authenticate the user and return a bool. However, I have no idea how the actual authentication works. In FormsAuthentication I would create a ticket, what do I do for Identity?

Here's what I have:

public static async System.Threading.Tasks.Task<bool> AuthUserAsync(string Email, string Password)
    {
        using (var db = new AntContext())
        {

            string hashedPW = GetHash(Password);
            bool userValid = db.Users.Any(user => user.Email == Email && user.Password == hashedPW);
            if (userValid)
            {
                var actUser = db.Users.FirstOrDefault(u => u.Email == Email && u.Password == hashedPW);
                if (actUser != null && !actUser.IsLocked)                   
                {
                    /** What do I do here? **/
                }
                else if (actUser.IsLocked)
                {
                    LoggingServices.AuthLog(actUser.Email, "Hat versucht auf ein gesperrtes Konto zuzugreifen.");
                }
            }
            return false;
        }
    }
mneumann
  • 491
  • 1
  • 5
  • 25

2 Answers2

1

You are heading in the right direction, what you are doing is sort of using OAuth to faciliate the mapping of your tokens and letting OWin handle the browser information. So, by using the [Authorize] attribute, like you are doing, how are you handling the signing of the identity? Like mentioned above with Forms authentication, you still have to create the Identity/Claim token. In my projects, I do something like this,

   protected void IdentitySignin(IUserModel userModel, string providerKey = null, bool isPersistent = true)
        {
            var claims                                                         = new List<Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, userModel.Id.ToString()),
                new Claim(ClaimTypes.Name, userModel.UserName),
                new Claim("UserContext", userModel.ToString())
            };
            var identity                                                       = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
            AuthenticationManager.SignIn(new AuthenticationProperties
            {
                IsPersistent                                                   = isPersistent,
                ExpiresUtc                                                     = DateTime.UtcNow.AddDays(7)
            }, identity);
        }

This forces OWIN/OAuth to login the user, and in my web.config I have the following:

<system.webserver>
    <authentication mode="None" />
</system.webserver>

And to sign my user out, and force the browser to get a new token:

 protected void IdentitySignout()
        {
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie,
                                            DefaultAuthenticationTypes.ExternalCookie);
        }

My AuthenticationManager is defined as such:

   private IAuthenticationManager AuthenticationManager
        {
            get { return HttpContext.GetOwinContext().Authentication; }
        }

Which is part of Microsoft.OWin.IOwinContext, you will have to add the reference if it does not exist.

You can handle an unauthorized user via the web.config file, or a base-controller, I opted for the base-controller option like so:

protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (UserContext == null || UserContext.Id.Equals(Guid.Empty))
            {
                if (filterContext.Controller.GetType()     == typeof(AccountController) || filterContext.Controller.GetType() == typeof(HomeController)) return;
                filterContext.Result                       = new RedirectResult("/Home/Index");
                return;
            }
}

But you can also do it via the AuthorizeAttribute if you wanted. This link will go into great detail on handling Oauth and Asp.Net MVC, may seem daunting at first, but it gives a great layout on using other providers if you decided to incorporate them into a release version.

https://www.codeproject.com/Articles/577384/Introduction-to-OAuth-in-ASP-NET-MVC

Kevin B Burns
  • 969
  • 7
  • 24
  • 1
    Thank you, I accepted your answer. In order to get it to work, I had to change a few things. I made most methods `static` (not strictly necessary), instead of writing `HttpContext.GetOwinContext().Authentication;` I had to write `HttpContext.Current.GetOwinContext().Authentication;`. Apart from that, it works nicely from what I can see now. – mneumann Oct 01 '18 at 08:08
  • 1
    Quick followup question: Is it true that I can't use roles based authorization like `[Authorize (Roles = "admin")]` on razor pages? – mneumann Oct 01 '18 at 09:49
  • 1
    I would check out these two sites here, https://stackoverflow.com/questions/13264496/asp-net-mvc-4-custom-authorize-attribute-with-permission-codes-without-roles, and https://dougrathbone.com/blog/2011/07/24/writing-your-own-custom-aspnet-mvc-authorize-attributes. The authorization attributes are incredibly modular and can facilitate almost any task you throw at them. I even have one, that compares the users' IP address to a Global database to redirect them based on their country origin. – Kevin B Burns Oct 01 '18 at 12:39
  • @KevinBBurns What about keeping session for 2 min? Can we set the session expiration duration with this approach? –  Apr 01 '20 at 13:51
  • @hexadecimal I think what you are looking for is Sliding Expirations, https://www.oauth.com/oauth2-servers/access-tokens/access-token-lifetime/ – Kevin B Burns Apr 09 '20 at 21:05
0

When you want Login in to your web-site you send your token to client and you can work with that to request and response in many, in other word, you have to login with your server side.

But when you want to logout from web-site, your client have to know that you want to logout this is not work just for server, the client should do this issue for log out.

I want to suggest you Token-JWT

if you want know about JWT click here

If you want I'll create an Example for you.

AmirReza-Farahlagha
  • 1,104
  • 11
  • 24