У меня угловое приложение, использующее 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. Что не так с приведенным выше кодом, который выдает ошибку?