Замена Cookie аутентификацией на основе токенов в ASP.NET OWIN Поток авторизации кода OpenIdConnect
У нас есть веб-приложение, написанное на ASP.NET, которое использует MVC для обслуживания наших одностраничных приложений и веб-API для вызовов ajax.
В аутентификации используются Microsoft.Owin и OpenIdConnect с Azure AD для авторизации. Поток OAUTH - это авторизация кода на стороне сервера. Тогда в Startup.Auth.cs мы имеем
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
var cookieAuthenticationOptions = new CookieAuthenticationOptions()
{
CookieName = CookieName,
ExpireTimeSpan = TimeSpan.FromDays(30),
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
SlidingExpiration = true,
};
app.UseCookieAuthentication(cookieAuthenticationOptions);
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
AuthorizationCodeReceived = (context) =>
{
/*exchange authorization code for a token
stored on database to access API registered on AzureAD (using ADAL.NET) */
},
RedirectToIdentityProvider = (RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context) =>
{
/* Set the redirects URI here*/
},
});
}
При нажатии на вход мы переходим к URL-адресу, маршруты которого соответствуют методам следующего контроллера MVC.
public class AccountController : Controller
{
public void SignIn(string signalrRef)
{
var authenticationProperties = /* Proper auth properties, redirect etc.*/
HttpContext.GetOwinContext()
.Authentication.Challenge(authenticationProperties, OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
}
public void SignOut(string signalrRef)
{
var authenticationProperties = /* Proper auth properties, redirect etc.*/
HttpContext.GetOwinContext().Authentication.SignOut(authenticationProperties,
OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
}
Затем конечный пользователь, подключенный к нашему приложению, проходит проверку подлинности между нашими клиентскими приложениями и сервером ASP.net с помощью файла cookie ASP.NET. Вместо этого мы хотели бы использовать подход на основе токенов. Если вы заинтересованы, это причина.
Я попытался заменить пакет Nuget Microsoft.Owin.Security.Cookies на Microsoft.Owin.Security.OAuth и в Startup.cs заменить
app.UseCookieAuthentication(cookieAuthenticationOptions);
от app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
и в моем AccountController мы изменили вызов HttpContext.GetOwinContext().Authentication.SignOut(authenticationProperties,
OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
в HttpContext.GetOwinContext().Authentication.SignOut(authenticationProperties,
OpenIdConnectAuthenticationDefaults.AuthenticationType, OAuthDefaults.AuthenticationType);
Проблема в том, что с Cookie set-cookie автоматически отправлялся в ответе веб-запроса, когда поток завершает работу при перенаправлении на указанную нами ссылку. Где я могу найти Bearer, сгенерированный OWIN с UseOAuthBearerAuthentication (если есть) **, ** Где и когда я должен отправить его обратно в мои клиентские SPA
Примечание: пример того, что мы пытаемся сделать, можно найти в этом репозитории github.
1 ответ
Я думаю, что есть два подхода для рассмотрения.
- Используйте библиотеки javascript для выполнения входа и получения токенов в вашем одностраничном приложении. Тогда ваш бэкэнд представляет собой чисто веб-API и может просто использовать промежуточное программное обеспечение для переноса OAuth для аутентификации запросов. Бэкэнд ничего не знает о входе пользователя в систему. У нас есть хороший пример, который использует этот подход здесь. Если вашему бэкэнду также необходимо выполнять вызовы API, вы также можете рассмотреть поток OnBehalfOf. Я обычно рекомендую этот подход.
- Используйте промежуточное программное обеспечение OpenIDConnect на вашем сервере для выполнения входа пользователя и получения токена. Вы даже можете опустить использование
CookieAuthenticationMiddleware
полностью (хотя я не уверен на 100%). Вы можете захватить токен вAuthorizationCodeReceived
уведомление, как вы упомянули, и вы можете перенаправить обратно в ваш SPA с токеном во фрагменте URL. У вас также может быть какой-то маршрут, который доставляет токены (которые кэшируются на вашем сервере) в ваш javascript. В любом случае вам нужно убедиться, что внешний абонент не сможет получить доступ к вашим токенам.
Следует помнить, как вы обновляете токены по истечении срока их действия. Если вы используете #1, большая часть этого будет обрабатываться для вас библиотеками. Если вы используете #2, вам придется управлять им больше самостоятельно.