Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Application and User Authentication using ASP.NET Core

Tags:

Can anyone point me to some good documentation or provide good information on the best way to implement authentication and authorisation for an ASP.NET Core REST API.I need to authenticating and authorising the app first and then authenticate and authorise the user.

Ideally I want to be able restrict the controller method that an authenticated app and/or user can access.

I am thinking of using AspNet.Security.OpenIdConnect.Serverenter for the App authentication but I am not sure then how best to perform the user authentication. Maybe reuse the OpenIdConnect authentication on a different endpoint for users with a different header to contain the user token.

Once authenticated I am thinking of just using roles base security to restrict which controllers methods can be accessed.

Is this the correct route to solving this problem?

like image 328
Michael Edwards Avatar asked Jan 01 '17 18:01

Michael Edwards


People also ask

How do I use authentication in .NET Core?

For example, when using ASP.NET Core Identity, AddAuthentication is called internally. The Authentication middleware is added in Startup. Configure by calling UseAuthentication. Calling UseAuthentication registers the middleware that uses the previously registered authentication schemes.

What is identity authentication in ASP.NET Core?

ASP.NET Core Identity is basically a membership system that provides login functionality including user registration in any ASP.NET Core applications. This new authentication system is intended to replace the existing membership system of classic ASP.NET.

What is the default type of authentication for ASP.NET Core MVC?

The windows Authentication provider lets you authenticates users based on their windows accounts. This provider uses IIS to perform the authentication and then passes the authenticated identity to your code. This is the default provided for ASP.net.


3 Answers

This is actually a tougher question that that it may seem because the type of clients (software clients) that are using the api seem to drive what kind of auth* is needed. For example, in a web application, where the web application needs auth*, then Asp.Net Identity would work with either a token or a cookie. However, if other clients are going to consume the provided services (mobile apps, WUP apps, then it may be easier to implement using token authentication . When I had this problem, I ran into the issue that I had a knowledge gap because I didn't really understand OAuth. I had to get back to basics.

https://alexbilbie.com/guide-to-oauth-2-grants/

https://www.pluralsight.com/courses/oauth2-json-web-tokens-openid-connect-introduction

Most of the tutorials around Asp.Net Identity "Seem" to be geared towards web clients. Although it is possible to find those that are not. With the introduction of asp.net core, the syntax has changed and many of the old tutorials that show combining cookie and token authentication are no longer applicable. Additionally, Web Api is not longer a separated from other project types in Visual Studio making the change even more pronounced. Here are some older tutorials.

http://satvasolutions.com/combine-asp-net-identity-web-api-and-mvc-best-in-a-single-web-app/

http://blog.iteedee.com/2014/03/asp-net-identity-2-0-cookie-token-authentication/

Combine the use of authentication both for MVC pages and for Web API pages?

IdentityServer is a completely valid solution, works with both client credential and Resource owner credentials grant (user,password) and Brock Allen has usually been very responsive in SO under the tag

https://stackoverflow.com/questions/tagged/identityserver4

or on the github site under issues labeled as questions

https://github.com/IdentityServer/IdentityServer4/issues

With identity server, Once again, I had to go back to basics and work through the tutorials to get an understanding of how this would work in my project.

https://identityserver4.readthedocs.io/en/release/intro/big_picture.html

As Brock quickly pointed out to me in another post, asp.net ef identity is a user store and good to use with the resource owner credentials workflow.

like image 82
Bill Avatar answered Nov 11 '22 18:11

Bill


For authentication you can use ASP.NET Core Identity that will use the Microsoft.AspNetCore.Identity.EntityFrameworkCore package, which will persist the identity data and schema to SQL Server using Entity Framework Core.

For authorization you can use Role Based Authorization that uses the Microsoft.AspNetCore.Authorization package.

You can also checkout this video for an overview on ASP.NET Core Authorization

like image 42
S.Dav Avatar answered Nov 11 '22 16:11

S.Dav


I couldn't find any good documentation on this, however I had to achieve the same thing so I coded the rest api myself by modifying the actions in the standard ASP.NET authentication template to REST API equivalents.

For example here is how I worked the login action:

    // POST: /Account/Login
    [HttpPost("[action]")]
    [AllowAnonymous]
    public async Task<ReturnValue<ApplicationUser>> Login([FromBody] loginModel login)
    {
        if (ModelState.IsValid)
        {
            ApplicationUser user = await _userManager.FindByEmailAsync(login.email);

            if (user == null)
            {
                return new ReturnValue<ApplicationUser>(false, "Login failed, check username and password.", null);
            }
            // else if (user.EmailConfirmed == false)
            // {
            //     return new ReturnValue<ApplicationUser>(true, "Confirm email address.", null, user);
            // }
            else
            {
                // This doesn't count login failures towards account lockout
                // To enable password failures to trigger account lockout, set lockoutOnFailure: true
                var result = await _signInManager.PasswordSignInAsync(user, login.password, (bool)login.rememberMe, lockoutOnFailure: false);
                if (result.Succeeded)
                {
                    return new ReturnValue<ApplicationUser>(true, user);
                }
                //if (result.RequiresTwoFactor)
                //{
                //    return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
                //}
                if (result.IsLockedOut)
                {
                    return new ReturnValue<ApplicationUser>(false, "The account is locked out.", null);
                }
            }
        }
        else
        {
            string message = string.Join("; ", ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage));
            return new ReturnValue<ApplicationUser>(false, "Invalid login attempt: " + message, null);
        }

        // If we got this far, something failed in the model.
        return new ReturnValue<ApplicationUser>(false, "Login failed.", null);
    }

If you call the API from a javascript within a browser the cookies will be loaded and you should be able to make further authorised calls to the API, if you're calling from another type of client, you will want to ensure the CookieContainer is retained for authorized calls.

From this point you can authorize your REST API controllers using [Authorize] decorator through the standard Microsoft libraries: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity

Good luck.

like image 20
Gary Holland Avatar answered Nov 11 '22 16:11

Gary Holland