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?