2

Im following the following tutorial https://www.youtube.com/watch?v=0oBIgPaFYOg&list=PLOeFnOV9YBa7dnrjpOG6lMpcyd7Wn7E8V&index=8 about authorization en authentication in aspnet core only problem when it is time for config.CallbackPath = "/oauth/callback"; to do something it throws the following error Exception: An error was encountered while handling the remote login. according to The oauth state was missing or invalid. An error was encountered while handling the remote login i should remove config.CallbackPath while it is very crucial to me or specify something in app.useendpoints here's my startup.cs of the client

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace lesson6
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication(config => {
                config.DefaultAuthenticateScheme = "ClientCookie";
                config.DefaultSignInScheme = "ClientCookie";
                config.DefaultChallengeScheme = "OurServer";
            })
            .AddCookie("ClientCookie")
            .AddOAuth("OurServer", config => {
                config.ClientId = "client_id";
                config.ClientSecret = "client_secret "; 
                config.CallbackPath = "/oauth/callback";
                config.AuthorizationEndpoint = "http://localhost:4444/oauth/authorize";
                config.TokenEndpoint = "http://localhost:4444/oauth/token";
            });
            services.AddControllersWithViews().AddRazorRuntimeCompilation();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();
            app.UseAuthorization();
            app.UseAuthentication();
            app.UseHttpsRedirection();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
            });
        }
    }
}

im working on an oauth client and a server here's my startup of the server

    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication("OAuth").AddJwtBearer(
                "OAuth", config => {
                    var secretBytes = Encoding.UTF8.GetBytes(Constants.Secret);
                    var key = new SymmetricSecurityKey(secretBytes);

                    config.Events = new JwtBearerEvents {
                        OnMessageReceived = context => {
                            if(context.Request.Query.ContainsKey("access_token")) {
                                context.Token = context.Request.Query["access_token"];
                            }
                            return Task.CompletedTask;
                        }
                    };

                
                    config.TokenValidationParameters = new TokenValidationParameters {
                        ValidIssuer = Constants.Issuer,
                        ValidAudience = Constants.Audience,
                        IssuerSigningKey = key
                    };
                }
            );
            
            services.AddControllersWithViews()
            .AddRazorRuntimeCompilation();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
            });
        }
    }

oauthcontroller.cs of server

    public class OAuthController : Controller {
        public IActionResult Authorize(
            string response_type,
            string client_id,
            string scope,
            string redirect_uri,
            string state
        ) {
            var query = new QueryBuilder();
            query.Add("redirect_uri", redirect_uri);
            query.Add("state", state);
            Console.WriteLine("ifnext");
            Console.WriteLine(query.ToString());
            return View(model: query.ToString());
        }
        [HttpPost]
        public IActionResult Authorize(
            string username,
            string redirect_uri,
            string state
        ) {
            Console.WriteLine("ifwouldif");
            const string code = "ajskfhjasfhsjakf";
            var query = new QueryBuilder();
            query.Add("code", code);
            query.Add("state", state);
            return Redirect($"{redirect_uri}{query.ToString()}");
        }
        public async Task<IActionResult> Token(
            string grant_type,
            string code,
            string redirect_uri,
            string client_id
        ) {
            var claims = new[] {
                new Claim(JwtRegisteredClaimNames.Sub, "some_id"),
                new Claim("granny", "cookie")
            };
            var secretBytes = Encoding.UTF8.GetBytes(Constants.Secret);
            var key = new SymmetricSecurityKey(secretBytes);
            var algorithm = SecurityAlgorithms.HmacSha256;
            var signingCredentials = new SigningCredentials(key, algorithm);
            var token = new JwtSecurityToken(
                Constants.Issuer,
                Constants.Audience,
                claims,
                notBefore: DateTime.Now,
                expires: DateTime.Now.AddHours(1),
                signingCredentials
            );
            var access_token = new JwtSecurityTokenHandler().WriteToken(token);
            var responseObject = new {
                access_token,
                token_type = "Bearer",
                raw_claim = "oauthtutorial"
            };
            var responseJson = JsonConvert.SerializeObject(responseObject);
            var responseBytes = Encoding.UTF8.GetBytes(responseJson);
            await Response.Body.WriteAsync(responseBytes, 0, responseBytes.Length);
            return Redirect(redirect_uri);
        }
    }

homecontroller.cs server

    public class HomeController : Controller {
        private readonly IAuthorizationService authorizationService;

        public HomeController(IAuthorizationService authorizationService) 
        {
            this.authorizationService = authorizationService;
        }
        public IActionResult Index() {
            return View();
        }
        [Authorize]
        public IActionResult Secret() {
            return View();
        }
        public IActionResult Authenticate() {
            var claims = new[] {
                new Claim(JwtRegisteredClaimNames.Sub, "some_id"),
                new Claim("granny", "cookie")
            };
            var secretBytes = Encoding.UTF8.GetBytes(Constants.Secret);
            var key = new SymmetricSecurityKey(secretBytes);
            var algorithm = SecurityAlgorithms.HmacSha256;
            var signingCredentials = new SigningCredentials(key, algorithm);
            var token = new JwtSecurityToken(
                Constants.Issuer,
                Constants.Audience,
                claims,
                notBefore: DateTime.Now,
                expires: DateTime.Now.AddHours(1),
                signingCredentials
            );
            var tokenJson = new JwtSecurityTokenHandler().WriteToken(token);

            return Ok(new  { access_token = tokenJson });
        }
        public IActionResult Decode(string part) {
            var bytes = Convert.FromBase64String(part);
            return Ok(Encoding.UTF8.GetString(bytes));
        }
    }

homecontroller of client

    public class HomeController : Controller {
        public IActionResult Index() {
            return View();
        }
        [Authorize]
        public async Task<IActionResult> Secret() {
            // var token = await HttpContext.GetTokenAsync("access_token");
            return View();
        }
        
    }

I would like to be redirected to the secret action of the homecontroller of the client but how in the best way with a callback?

noonecious
  • 63
  • 1
  • 1
  • 6
  • Check out how ASP.NET Core does it: https://github.com/dotnet/aspnetcore/blob/5c78265f7232a9b100c31d67a682cec26359df5b/src/Identity/samples/IdentitySample.Mvc/Controllers/AccountController.cs#L146 – abdusco Jun 28 '21 at 08:02

0 Answers0