Сводка
Это моя первая попытка с OAuth2 и механизмами внешнего входа.
Я создаю WebApp, который будет предоставлять APIфункции через удобный пользовательский интерфейс.
Для выполнения вызовов API мне нужно получить токен доступа от QBO, который предоставляет доступ к ресурсам.
Итак, у моего WebApp есть внешний логинопция, которую я использую для аутентификации в QBO, а затем авторизирую мое приложение.
Все отлично работает, пока ...
![Error loading external login information.](https://i.stack.imgur.com/HXzOO.png)
Конфигурация служб
Основываясь на руководстве по аутентификации GitHub, я придумал это.
services.AddAuthentication(o => {
o.DefaultAuthenticateScheme = IdentityConstants.ExternalScheme;
o.DefaultSignInScheme = IdentityConstants.ExternalScheme;
o.DefaultChallengeScheme = IdentityConstants.ExternalScheme;
})
.AddOAuth("qbo", "qbo", o => {
o.CallbackPath = new PathString("/signin-qbo");
o.ClientId = Configuration["ecm.qbo.client-id"];
o.ClientSecret = Configuration["ecm.qbo.client-secret"];
o.SaveTokens = true;
o.Scope.Add("openid");
o.Scope.Add("profile");
o.Scope.Add("email");
o.Scope.Add("com.intuit.quickbooks.accounting");
o.AuthorizationEndpoint = Configuration["ecm.qbo.authorization-endpoint"];
o.TokenEndpoint = Configuration["ecm.qbo.token-endpoint"];
o.UserInformationEndpoint = Configuration["ecm.qbo.user-info-endpoint"];
o.Events.OnCreatingTicket = async context => {
var companyId = context.Request.Query["realmid"].FirstOrDefault() ?? throw new ArgumentNullException("realmId");
var accessToken = context.AccessToken;
var refreshToken = context.RefreshToken;
Configuration["ecm.qbo.access-token"] = accessToken;
Configuration["ecm.qbo.refresh-token"] = refreshToken;
Configuration["ecm.qbo.realm-id"] = companyId;
context.Backchannel.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
context.Backchannel.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await context.Backchannel.GetStringAsync(context.Options.UserInformationEndpoint);
var result = JsonConvert.DeserializeObject<Dictionary<string, string>>(response);
var user = (ClaimsIdentity)context.Principal.Identity;
user.AddClaims(new Claim[] {
new Claim("access_token", accessToken),
new Claim("refresh_token", refreshToken),
new Claim(ClaimTypes.GivenName, result["givenName"]),
new Claim(ClaimTypes.Surname, result["familyName"]),
new Claim(ClaimTypes.Email, result["email"]),
new Claim(ClaimTypes.Name, result["givenName"]+" "+result["familyName"])
});
};
});
Это работает.Я могу добавить свои претензии на основе информации о пользователе, context.Principal.Identity указывает, что он аутентифицирован.
По некоторым причинам он пытается перенаправить на `/ Identity / Account / Login? ReturnUrl =% 2F,Почему это так?
Перенаправление страницы входа в систему
Здесь я не понимаю, почему я получаю перенаправление, и это меня сильно смущает.Итак, я добавил AccountController просто для того, чтобы попытаться закрыть его.
namespace ecm.backoffice.Controllers {
[Authorize]
[Route("[controller]/[action]")]
public class AccountController : Controller {
[AllowAnonymous]
[HttpGet]
public IActionResult Login(string returnUrl = "/") {
return Challenge(new AuthenticationProperties { RedirectUri = returnUrl });
}
[Authorize]
[HttpGet]
public async Task<IActionResult> Logout(string returnUrl = "/") {
await Request.HttpContext.SignOutAsync("qbo");
return Redirect(returnUrl);
}
}
}
И это на самом деле создает больше путаницы, чем решает.Я заблудился здесь ...
Применить миграции
Кажется, что это индивидуальное WebApp для аутентификации пользователей использует идентификацию, которая, похоже, создает многоза кулисами механизмов.Сначала я попытался зарегистрироваться в своем приложении, и мне пришлось «Применить миграции», которые я полностью получаю, поскольку модель данных не была инициализирована.
Итак, я нажал кнопку «Применить миграции».Хотя я был в порядке с этим ...
Entity Framework Core
Я знаю, что приложение использует Entity Framework Core для своихмеханизм персистентности, отсюда процесс регистрации и т. д. И для его настройки мне нужно было добавить эти строки в конфиги сервисов.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>();
Похоже, что он просто не будет работать вообще.
Мысли
На данный момент, я думаю, что в сообщении говорится, что Entity Framework просто не может загрузить пользовательскую информацию из основного хранилища данных.Я полностью понимаю это, и я не хочу регистрировать этого пользователя.Я просто хочу принять как должное то, что если QBO аутентифицировал пользователя, я в порядке, и я предоставляю открытый доступ к функциям WebApp, даже если пользователь не зарегистрирован.
Как сообщить это моемуWebApp?
Связанные Q / AI, прочитанные до запроса
Запретить перенаправление на / Account / Login в asp.net core 2.2 ASP.NET Core (2.1) Web API: поставщик удостоверений и внешнего входа asp.net core 2.2 перенаправляет вход в систему после успешного входа в систему Внешняя проверка подлинности входа в Asp.net core 2.1
и многие другие ...