Автоматический вход пользователя - Identity Server 4
У меня есть угловое приложение, использующее oidc Authentication для аутентификации пользователей на IdentityServer 4. Это работает нормально.
Мое приложение доверяет токену другого приложения, которое использует другой механизм аутентификации. Таким образом, идея заключается в том, что мое приложение будет проверять токен из другого приложения, и если оно будет проверено, оно будет автоматически входить в систему пользователя в моем приложении. (Я бы предложил пользователю войти в систему, если отображение не сохранено, и сохранить отображение)
Я могу обработать сопоставление и другую часть, но при наличии проблем авторизуйтесь автоматически. Я унаследовал от "AuthorizeInteractionResponseGenerator" и переопределил "ProcessInteractionAsync". Ниже приведен код для того же.
using IdentityModel;
using IdentityServer4;
using IdentityServer4.Events;
using IdentityServer4.Models;
using IdentityServer4.Quickstart.UI;
using IdentityServer4.ResponseHandling;
using IdentityServer4.Services;
using IdentityServer4.Validation;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using PaperSave.IdentityServer.ADOStore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace PaperSave.IdentityServer.Extensions
{
public class CustomAuthentication : AuthorizeInteractionResponseGenerator
{
IHttpContextAccessor _httpContextAccessor;
IEventService _events;
private readonly IUserStore _users;
private readonly ISystemClock _systemClock;
private IProfileService _profileService;
public CustomAuthentication(ISystemClock clock, ILogger<AuthorizeInteractionResponseGenerator> logger, IConsentService consent, IProfileService profile, IHttpContextAccessor httpContextAccessor, IEventService events, IUserStore users) : base(clock, logger, consent, profile)
{
_httpContextAccessor = httpContextAccessor;
_events = events;
_users = users;
_systemClock = clock;
_profileService = profile;
}
public override async Task<InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
{
if (request?.Client?.ClientId == "mvc" || request?.Client?.ClientId == "angular_spa")
{
//
// https://github.com/IdentityServer/IdentityServer4/issues/853
//
var isAuthenticated = _httpContextAccessor.HttpContext.User.Identity.IsAuthenticated;
var userId = request.GetAcrValues().FirstOrDefault(a => a.StartsWith("impersonatedUserId"));
if (isAuthenticated)// || key == null)
{
return await base.ProcessInteractionAsync(request, consent);
}
string userName = "test";
var hostName = _httpContextAccessor.HttpContext.Request.Host.Value.ToLower();
var lstClaims = await _users.GetUserProfile(userName, "", hostName);
var user = await _users.FindByUsername(userName);
if (user == null)
{
user = await _users.AutoProvisionUser("local", CryptoRandom.CreateUniqueId(), lstClaims);
}
await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username));
AuthenticationProperties props = null;
if (AccountOptions.AllowRememberLogin && false)
{
props = new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)
};
};
await _httpContextAccessor.HttpContext.SignInAsync(user.SubjectId, user.Username, props);
return new InteractionResponse()
{
};
}
return await base.ProcessInteractionAsync(request, consent);
}
}
}
И я зарегистрировал этот класс в Startup.cs. Он вызывается правильно, но после этого код завершается с ошибкой "подпретензия отсутствует".
Итак, мои вопросы: 1. Это правильный путь, или я должен сделать это по-другому? 2. Что не так с приведенным выше кодом, который выдает ошибку?