Ocelot icon indicating copy to clipboard operation
Ocelot copied to clipboard

Asp.Net Core Identity Authentication With Cookies

Open tulde23 opened this issue 5 years ago • 4 comments

If anyone is looking to use cookies based authentication with .net core Identity here is some config to get you going.

"ReRoutes": [{
        "DownstreamHostAndPorts": [
            {
                "Host": "localhost",
                "Port": 51876,
            }
        ],
        "DownstreamPathTemplate": "/",
        "UpstreamPathTemplate": "/",
        "UpstreamHttpMethod": ["Post"],
        "ReRouteIsCaseSensitive": false,
        "DownstreamScheme": "http",
        "AuthenticationOptions": {
            "AuthenticationProviderKey": "Identity.Application",
            "AllowedScopes": [
                "role-admin",
                 "role-user"
]
        }
    }]

The important thing to notice here is "Identity.Application" passed for "AuthenticationProviderKey". I found this value at Microsoft.AspNetCore.Identity.IdentityConstants.ApplicationScheme in netcore 2.2

Startup.cs

//Startup.cs
//I repurpose AllowedScopes to be roles that I check on a per route basis.
   app.UseOcelot(p => p.AuthorisationMiddleware = Authorize
....
   private Task Authorize(DownstreamContext context, Func<Task> next)
        {
            var roles = context.DownstreamReRoute.AuthenticationOptions.AllowedScopes;
            bool authorized = false;
            foreach (var role in roles)
            {
                if (context.HttpContext.User.IsInRole(role))
                {
                    authorized = true;
                    break;
                }
            }

            if (authorized)
            {
                return next();
            }
            else
            {
                context.Errors.Add(new UnauthorizedError("Unauthorized", OcelotErrorCode.UserDoesNotHaveClaimError));
            }
            context.HttpContext.Response.StatusCode = 401;
            return Task.CompletedTask;
        }

AuthController

 [Route("/api/v1/[controller]"), AllowAnonymous]
    public class AuthController : Controller

    {
        private readonly SignInManager<GumshoeUser> _signInManager;
        private readonly UserManager<GumshoeUser> _userManager;

        public AuthController(SignInManager<GumshoeUser> signInManager,
                                      UserManager<GumshoeUser> userManager)
        {
            _signInManager = signInManager;
            _userManager = userManager;
        }

    

        [HttpPost("Login")]
        [Produces("application/json")]
        public async Task<AuthResponse> Login(string username, string password)
        {
            var user = await _userManager.FindByEmailAsync(username);
            if (user == null)
            {
                await HttpContext.SignOutAsync();
                return new AuthResponse { Status = 403, Name = username };
            }
            var result = await _signInManager.PasswordSignInAsync(username, password, false, false);

            if (result.Succeeded)
            {
                var roles = await _userManager.GetRolesAsync(user);
                var now = DateTime.UtcNow;

                var claims = new List<Claim>(){
                new Claim(ClaimTypes.Name, user.Email)
                };
                foreach (var item in roles)
                {
                    claims.Add(new Claim(ClaimTypes.Role, item));
                }


                return new AuthResponse { Status = 200, Name = username, Roles = roles.ToList() };
            }
            else
            {
                await HttpContext.SignOutAsync();
                return new AuthResponse { Status = 403, Name = username };
            }
        }

    }

tulde23 avatar Aug 29 '19 13:08 tulde23

Exactly what I was searching for! Have you some github repo showing this setup in detail?

Ewerton avatar Dec 12 '23 21:12 Ewerton

@tulde23 @Ewerton Welcome to Ocelot world! :tiger:

Guys, you could create a PR with a sample to keep all files in samples folder. If this solution really works then it can be converted to the bug fix and/or be a sample. Why not to create a PR? :wink:

raman-m avatar Dec 16 '23 12:12 raman-m

@Ewerton Why not to fork Ocelot repo into your account? I didn't find a fork in your repos.

raman-m avatar Dec 16 '23 12:12 raman-m

@tulde23 Hi Jason! Please, keep in mind we work on PR #1666 now which has changes in related "AuthenticationProviderKey" logic.

Are you still with Ocelot?

raman-m avatar Dec 16 '23 12:12 raman-m