I created an Asp.Net Core 2.0 client website, running locally, that makes a call to an OAuth 2.0 server. The server returns a
302 Redirect response, but the method on the client never executes.
Is there a special version of MapRoute that will redirect the client to a new location?
I created an Asp.Net Core 2.0 client website, running locally, that makes a call to an OAuth 2.0 server. The server returns a
302 Redirect response, but the method on the client never executes.
Is there a special version of MapRoute that will redirect the client to a new location?
Your question makes little to no sense. You are showing code that is irrelevant or at best part of a larger body of work and missing relevant bit of information.
What is the redirect URL? What OAuth provider are you using?
The redirect URL was created when the OAuth account was created. If you do not know, then login to the account and look. Your application must have an action or Razor Page that matches the redirect URL.
Secondly, OAuth providers have documentation that you must read. The documentation explains how the OAuth service works.
Your question makes little to no sense. You are showing code that is irrelevant or at best part of a larger body of work and missing relevant bit of information.
What is the redirect URL?
I am sorry for not being able to explain my problem in a way that makes sense.
The redirect URL is: http://localhost:64370/token
mgebhard
What OAuth provider are you using?
I'm not sure of what you need here. Do you mean what version? It is 2.0.
mgebhard
The redirect URL was created when the OAuth account was created. If you do not know, then login to the account and look. Your application must have an action or Razor Page that matches the redirect URL.
Yes, it does.
mgebhard
Secondly, OAuth providers have documentation that you must read. The documentation explains how the OAuth service works.
I do know how the OAuth service works. I have the source code for it and it is running on my website. I would like to explain it this way. This client is working in a Asp.Net 4.5.2(not core) client website application. I am trying to migrate it to Asp.Net
Core 2.0. The reason why I think the problem is in the MapRoute, is because the MapRoute that is in the .Net 4.5.2 version of the client looks like this:
I am sorry for not being able to explain my problem in a way that makes sense.
The redirect URL is: http://localhost:64370/token
I think you've got it backwards... the token endpoint is where the client gets the token.
TGirgenti
I'm not sure of what you need here. Do you mean what version? It is 2.0.
Your OAuth provider is service providing OAuth services to the client application. If you do not know the OAuth provider then how do you expect anyone on the forum to provide assistance? Maybe there is someone on your team that can help you?
TGirgenti
I do know how the OAuth service works. I have the source code for it and it is running on my website. I would like to explain it this way. This client is working in a Asp.Net 4.5.2(not core) client website application. I am trying to migrate it to Asp.Net
Core 2.0. The reason why I think the problem is in the MapRoute, is because the MapRoute that is in the .Net 4.5.2 version of the client looks like this:
The most logical first step is learning the OAuth protocol. At this point, you're posting random bits of code without any logical connection.
The 4.5.2 app is working, Right?. That should provide enough of a time buffer for you to learn how OAuth works and figure out what Oauth provider you are using.
I am sure that I don't know as much as you do about all this.
If you tell me where to look in my OAuth server code to determine what you asking for, I would gladly look it up for you.
Also, if you can tell me what code to post to help you understand more about the problem, I would gladly do that.
I realize I am not adept at giving the proper information when requesting help, so if you can tell me exactly what it is that you need to help me, I would greatly appreciate it.
All you have told is the route you want. To help you we need to the controller and action you want the route to go to. Also we need to know your routing setup, are you using static routes or attribute routes, if static, we need your route map.
Also the route solution from the asp.net looks correct. Why didn’t you use it?
This is the controller. The Process method executes and after it executes the last statement,
return Redirect(authUrl);, it should return to the GetAccessToken method:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using ChinavasionAPI.Data;
using ChinavasionAPI.Models;
using ChinavasionAPI.Models.CAPIViewModels;
using ChinavasionAPI.Managers;
using ChinavasionAPI.Parameters;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Rendering;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Http;
namespace ChinavasionAPI.Controllers
{
public class APIController : Controller
{
private readonly ChinavasionAPIContext _context;
public APIController(ChinavasionAPIContext context)
{
_context = context;
}
public IActionResult Index()
{
return View();
}
[HttpGet]
public async Task<IActionResult> Process()
{
var viewModel = new SetupIndexData();
viewModel.Setups = await _context.Setups.ToListAsync();
return View(viewModel);
}
[HttpPost]
public async Task<IActionResult> Process(IFormCollection formCollection, string parameterName, string parameterValue)
{
string serverUrl = formCollection["SetupText"].ToString();
string queryCall = formCollection["QueryCallText"].ToString();
int? setupID = Convert.ToInt16(formCollection["SetupID"]);
if (setupID == null)
{
return NotFound();
}
var setup = await _context.Setups.SingleOrDefaultAsync(m => m.ID == setupID);
if (setup == null)
{
return NotFound();
}
string serverKey = setup.Key;
var model = new AccessModel();
model.UserAccessModel = _context.UserAccessModels.Single(a => a.ID == 1);
ViewBag.SyncOrAsync = "Asynchronous";
var productsService = new Service.ProductService();
List<Product> products = (await productsService.ProcessAPIAsync(serverUrl, serverKey, queryCall, parameterName, parameterValue));
if (ModelState.IsValid)
{
try
{
var nopAuthorizationManager = new AuthorizationManager(model.UserAccessModel.ClientId, model.UserAccessModel.ClientSecret, model.UserAccessModel.ServerUrl);
var redirectUrl = $"{this.Request.Scheme}://{this.Request.Host}{this.Request.PathBase}" + "/token";
if (redirectUrl != model.UserAccessModel.RedirectUrl)
{
return BadRequest();
}
// This should not be saved anywhere.
var state = Guid.NewGuid();
//Session["state"] = state;
string authUrl = nopAuthorizationManager.BuildAuthUrl(redirectUrl, new string[] { }, state.ToString());
return Redirect(authUrl);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
return BadRequest();
}
[HttpGet]
[AllowAnonymous]
public ActionResult GetAccessToken(string code, string state)
{
if (ModelState.IsValid && !string.IsNullOrEmpty(code) && !string.IsNullOrEmpty(state))
{
var model = new AccessModel();
model.UserAccessModel = _context.UserAccessModels.Single(a => a.ID == 1);
try
{
string clientId = model.UserAccessModel.ClientId;
string clientSecret = model.UserAccessModel.ClientSecret;
string serverUrl = model.UserAccessModel.ServerUrl;
string redirectUrl = model.UserAccessModel.RedirectUrl;
var authParameters = new AuthParameters()
{
ClientId = clientId,
ClientSecret = clientSecret,
ServerUrl = serverUrl,
RedirectUrl = redirectUrl,
GrantType = "authorization_code",
Code = code
};
var nopAuthorizationManager = new AuthorizationManager(authParameters.ClientId, authParameters.ClientSecret, authParameters.ServerUrl);
string responseJson = nopAuthorizationManager.GetAuthorizationData(authParameters);
AuthorizationModel authorizationModel = JsonConvert.DeserializeObject<AuthorizationModel>(responseJson);
model.AuthorizationModel = authorizationModel;
model.UserAccessModel = new UserAccessModel()
{
ClientId = clientId,
ClientSecret = clientSecret,
ServerUrl = serverUrl,
RedirectUrl = redirectUrl
};
// TODO: Here you can save your access and refresh tokens in the database. For illustration purposes we will save them in the Session and show them in the view.
//Session["accessToken"] = authorizationModel.AccessToken;
model.UserAccessModel.AccessToken = authorizationModel.AccessToken;
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
return View("~/Views/API/AccessToken.cshtml", model);
}
return BadRequest();
}
[HttpGet]
[AllowAnonymous]
public JsonResult RefreshAccessToken(string refreshToken, string clientId, string clientSecret, string serverUrl)
{
string json = string.Empty;
if (ModelState.IsValid &&
!string.IsNullOrEmpty(refreshToken) &&
!string.IsNullOrEmpty(clientId) &&
!string.IsNullOrEmpty(clientSecret) &&
!string.IsNullOrEmpty(serverUrl))
{
var model = new AccessModel();
try
{
var authParameters = new AuthParameters()
{
ClientId = clientId,
ClientSecret = clientSecret,
ServerUrl = serverUrl,
RefreshToken = refreshToken,
GrantType = "refresh_token"
};
var nopAuthorizationManager = new AuthorizationManager(authParameters.ClientId,
authParameters.ClientSecret, authParameters.ServerUrl);
string responseJson = nopAuthorizationManager.RefreshAuthorizationData(authParameters);
AuthorizationModel authorizationModel =
JsonConvert.DeserializeObject<AuthorizationModel>(responseJson);
model.AuthorizationModel = authorizationModel;
model.UserAccessModel = new UserAccessModel()
{
ClientId = clientId,
ServerUrl = serverUrl
};
// Here we use the temp data because this method is called via ajax and here we can't hold a session.
// This is needed for the GetCustomers method in the CustomersController.
TempData["accessToken"] = authorizationModel.AccessToken;
TempData["serverUrl"] = serverUrl;
}
catch (Exception ex)
{
json = string.Format("error: '{0}'", ex.Message);
//return Json(json, JsonRequestBehavior.AllowGet);
return Json(json);
}
json = JsonConvert.SerializeObject(model.AuthorizationModel);
}
else
{
json = "error: 'something went wrong'";
}
return Json(json);
}
private ActionResult BadRequest(string message = "Bad Request")
{
//return new HttpStatusCodeResult(HttpStatusCode.BadRequest, message);
return new StatusCodeResult(404);
}
}
}
It never gets to GetAccessToken. It just hangs up.
Using static routes, here is my complete Startup.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using ChinavasionAPI.Data;
namespace ChinavasionAPI
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Adds a default in-memory implementation of IDistributedCache.
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
// Set a short timeout for easy testing.
options.IdleTimeout = TimeSpan.FromSeconds(10);
options.Cookie.HttpOnly = true;
});
services.AddRouting();
services.AddMvc();
services.AddDbContext<ChinavasionAPIContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("ChinavasionAPIContext")));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "Process",
template: "{controller=API}/{action=Process}");
routes.MapRoute(
name: "GetAccessToken",
template: "{controller=API}/{action=GetAccessToken}");
});
}
}
}
because it does not like the url and namespaces parameters and I don't know how to use them in Asp.Net Core 2.0.
I would appreciate it if anyone can tell me how to find out what the server is returning to the client. I can't figure out how to do that. If I knew that, I might be able to know what is causing the hangup.
the second and third routes are never used, because they are identical to the first route (just different defaults). only the first route is used. passing "/token" as a route will goto to controller = "token", action = "index"
you can create this controller and move your code to the index method, or add a custom route, which must come first:
Member
34 Points
345 Posts
Need to create a route that executes on return from OAuth 2.0 server
Jun 16, 2018 11:28 AM|TGirgenti|LINK
Hello,
I created an Asp.Net Core 2.0 client website, running locally, that makes a call to an OAuth 2.0 server. The server returns a 302 Redirect response, but the method on the client never executes.
Is there a special version of MapRoute that will redirect the client to a new location?
I tried this:
and it gives a 404 Not Found on return.
Any help would be gratefully appreciated.
Thanks,
Tony
All-Star
43781 Points
18758 Posts
Re: Need to create a route that executes on return from OAuth 2.0 server
Jun 16, 2018 12:24 PM|mgebhard|LINK
Your question makes little to no sense. You are showing code that is irrelevant or at best part of a larger body of work and missing relevant bit of information.
What is the redirect URL? What OAuth provider are you using?
The redirect URL was created when the OAuth account was created. If you do not know, then login to the account and look. Your application must have an action or Razor Page that matches the redirect URL.
Secondly, OAuth providers have documentation that you must read. The documentation explains how the OAuth service works.
Member
34 Points
345 Posts
Re: Need to create a route that executes on return from OAuth 2.0 server
Jun 16, 2018 12:53 PM|TGirgenti|LINK
I am sorry for not being able to explain my problem in a way that makes sense.
The redirect URL is: http://localhost:64370/token
I'm not sure of what you need here. Do you mean what version? It is 2.0.
Yes, it does.
I do know how the OAuth service works. I have the source code for it and it is running on my website. I would like to explain it this way. This client is working in a Asp.Net 4.5.2(not core) client website application. I am trying to migrate it to Asp.Net Core 2.0. The reason why I think the problem is in the MapRoute, is because the MapRoute that is in the .Net 4.5.2 version of the client looks like this:
Any help that you can provide is gratefully appreciated.
Thanks,
Tony
All-Star
43781 Points
18758 Posts
Re: Need to create a route that executes on return from OAuth 2.0 server
Jun 16, 2018 01:24 PM|mgebhard|LINK
I think you've got it backwards... the token endpoint is where the client gets the token.
Your OAuth provider is service providing OAuth services to the client application. If you do not know the OAuth provider then how do you expect anyone on the forum to provide assistance? Maybe there is someone on your team that can help you?
The most logical first step is learning the OAuth protocol. At this point, you're posting random bits of code without any logical connection.
The 4.5.2 app is working, Right?. That should provide enough of a time buffer for you to learn how OAuth works and figure out what Oauth provider you are using.
Member
34 Points
345 Posts
Re: Need to create a route that executes on return from OAuth 2.0 server
Jun 16, 2018 01:45 PM|TGirgenti|LINK
I am sure that I don't know as much as you do about all this.
If you tell me where to look in my OAuth server code to determine what you asking for, I would gladly look it up for you.
Also, if you can tell me what code to post to help you understand more about the problem, I would gladly do that.
I realize I am not adept at giving the proper information when requesting help, so if you can tell me exactly what it is that you need to help me, I would greatly appreciate it.
Thanks,
Tony
All-Star
53594 Points
13328 Posts
Re: Need to create a route that executes on return from OAuth 2.0 server
Jun 16, 2018 05:56 PM|bruce (sqlwork.com)|LINK
Also the route solution from the asp.net looks correct. Why didn’t you use it?
Member
34 Points
345 Posts
Re: Need to create a route that executes on return from OAuth 2.0 server
Jun 17, 2018 01:35 PM|TGirgenti|LINK
This is the controller. The Process method executes and after it executes the last statement, return Redirect(authUrl);, it should return to the GetAccessToken method:
It never gets to GetAccessToken. It just hangs up.
Using static routes, here is my complete Startup.cs:
It has the route for GetAccessToken.
I did not use this MapRoute:
because it does not like the url and namespaces parameters and I don't know how to use them in Asp.Net Core 2.0.
I would appreciate it if anyone can tell me how to find out what the server is returning to the client. I can't figure out how to do that. If I knew that, I might be able to know what is causing the hangup.
Thanks for any help that anyone can provide.
Tony
All-Star
53594 Points
13328 Posts
Re: Need to create a route that executes on return from OAuth 2.0 server
Jun 17, 2018 03:58 PM|bruce (sqlwork.com)|LINK
you need to read the documentation on routing. you clearly don't understand how it works.
the second and third routes are never used, because they are identical to the first route (just different defaults). only the first route is used. passing "/token" as a route will goto to controller = "token", action = "index"
you can create this controller and move your code to the index method, or add a custom route, which must come first:
Member
34 Points
345 Posts
Re: Need to create a route that executes on return from OAuth 2.0 server
Jun 17, 2018 04:43 PM|TGirgenti|LINK
You are right. I don't understand how it works. After reading all these articles several times:
https://tools.ietf.org/html/rfc6749#section-4.1
https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-2.0#setting-up-routing-middleware
https://docs.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server#software-versions
https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-2.0#url-generation
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-2.1#using-routing-middleware
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-2.0#url-generation-reference
https://www.jerriepelser.com/blog/authenticate-oauth-aspnet-core-2/
https://medium.com/@mauridb/using-oauth2-middleware-with-asp-net-core-2-0-b31ffef58cd0
I still don't understand how it works.
Another thing I don't understand is 'when do I need a route'.
I will continue to read the articles and see if I can figure it out.
Happy Father's Day.
Tony