У нас есть приложение ASP. NET, которое использует общий логин Microsoft для входа в систему пользователей, а затем перенаправляет обратно в наше веб-приложение (в Azure). Аутентификация подключена к Azure Active Directory. Это мультитенантное приложение с несколькими Azure объявлениями. Когда Microsoft перенаправляет обратно на наш сайт, мы используем эту информацию для создания Cook ie, который используется для веб-звонков. Кроме того, обратный вызов возвращает код пользователя, который мы используем для получения токена. Это используется в качестве аутентификации для наших контроллеров API.
Это работает долгое время. Однако теперь нам нужно интегрироваться с другим сторонним порталом, который запустит наш продукт. Они будут использовать SAML для SSO. Они не интегрированы с Azure AD. Итак, идея в том, что мы проверяем пользователей с помощью утверждений SAML. Это будет содержать имя пользователя, с которым мы затем хотим «войти».
Я могу создать повара ie из этой информации, и это прекрасно работает с нашими вызовами через веб-контроллер. Однако, поскольку я не получаю обратный вызов от Azure AD, у меня нет токена для вызовов API. Я попытался вызвать Azure AD для аутентификации приложений, но это, похоже, удовлетворяет авторизации API-контроллера. В частности, RequestContext.Principal.Identity, похоже, не устанавливается с этим шаблоном.
Я установил аутентификацию повара ie с этим кодом:
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
var cookieOptions = new CookieAuthenticationOptions
{
ExpireTimeSpan = TimeSpan.FromDays(14),
SlidingExpiration = true,
LoginPath = new PathString("/home/login"),
AuthenticationType = "ApplicationCookie",
AuthenticationMode = AuthenticationMode.Active,
CookieHttpOnly = true,
CookieSecure = CookieSecureOption.Always,
CookieSameSite = SameSiteMode.Lax,
};
// Forms/Cookie Authentication
app.UseCookieAuthentication(cookieOptions);
И оставил код аутентификации токена на предъявителя так:
// Bearer Token Authentication used for API access
BearerAuthenticationOptions = new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Tenant = <application tenant id>,
AuthenticationType = OAuthDefaults.AuthenticationType,
// Disable Issuer validation. We'll validate the Isuuer in the ClaimsAuthorizationFilter.
TokenValidationParameters = new TokenValidationParameters
{
ValidAudience = <resource id>,
ValidateIssuer = false
},
};
app.UseWindowsAzureActiveDirectoryBearerAuthentication(BearerAuthenticationOptions);
Код Azure AD auth (который должен заменить логин SAML):
var openIdConnectOptions = new OpenIdConnectAuthenticationOptions { ClientId = <ClientId>, Authority = "https://login.windows.net/common/", // setting this to false uses the cookie expiration instead UseTokenLifetime = false, TokenValidationParameters = new TokenValidationParameters { // we'll validate Issuer on the SecurityTokenValidated notification below ValidateIssuer = false },
Notifications = new OpenIdConnectAuthenticationNotifications { // An AAD auth token is validated and we have a Claims Identity SecurityTokenValidated = context => { ... additional validation is performed here...
return Task.FromResult(0); },
//the user has just signed in to the external auth provider (AAD) and then were redirected here // with an access code that we can use to turn around and acquire an auth token AuthorizationCodeReceived = context => { var code = context.Code; var identity = context.AuthenticationTicket.Identity;
var appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase; // causes the retreived API token to be cached for later use TokenService.GetUserLevelTokenFromAccessCode(new HttpUserSessionWithClaimsId(identity), code, <ApiResourceId>, new Uri(appBaseUrl));
return Task.FromResult(0); }, // We are about to redirect to the identity provider (AAD) RedirectToIdentityProvider = context => { // This ensures that the address used for sign in and sign out is picked up dynamically from the request // Remember that the base URL of the address used here must be provisioned in Azure AD beforehand. var appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase; context.ProtocolMessage.RedirectUri = appBaseUrl + "/"; context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
context.HandleResponse();
return Task.FromResult(0); }, // Something went wrong during this auth process AuthenticationFailed = context => { if (context.Exception is Microsoft.IdentityModel.Protocols.OpenIdConnect
.OpenIdConnectProtocolInvalidNonceException) {
//This is a message we can't do anything about, so we want to ignore it.
Log.Info("AuthenticationFailed in OpenIdConnectAuthentication middleware", context.Exception); } else {
Log.Error("AuthenticationFailed in OpenIdConnectAuthentication middleware",
context.Exception); }
// IDX10205 == Tenant validation failed var message = (context.Exception.Message.StartsWith("IDX10205"))
? InvalidTenantMessage
: GenericErrorMessage;
context.OwinContext.Response.Redirect("/?Error=" + Uri.EscapeDataString(message)); context.HandleResponse(); // Suppress the exception return Task.FromResult(0); }, MessageReceived = context => { if (!string.IsNullOrWhiteSpace(context.ProtocolMessage.Error)) {
// AADSTS65004 == user did not grant access in OAuth flow
Log.Error("MessageReceived containing error in OpenIdConnectAuthentication middleware. \nError: {0}\nDescription: {1}"
.FormatWith(context.ProtocolMessage.Error, context.ProtocolMessage.ErrorDescription));
//context.OwinContext.Response.Redirect("/");
//context.HandleResponse(); // Suppress the exception } return Task.FromResult(0); } } };
app.UseOpenIdConnectAuthentication(openIdConnectOptions);
Любая помощь будет принята с благодарностью.