Междоменная аутентификация ASP.net MVC
У меня есть два разных веб-приложения, созданных с помощью ASP.net MVC. Это два приложения могут не работать на одном сервере или в одном домене.
Я бы хотел, чтобы при входе пользователя в один из них автоматически должен был быть вход в другой. То же самое должно работать с выходом из системы.
Какое, по вашему мнению, лучшее решение? Знаете ли вы о каком-то примерном коде?
Спасибо!
--- ИЗМЕНИТЬ БОЛЬШЕ ИНФОРМАЦИИ ---
Использовать сценарий:
Пользователь имеет веб-приложение A, открытое на вкладке, и в какой-то момент приложения есть ссылка, которая перенаправляет пользователя в веб-приложение B. Если он зарегистрирован на A, я хотел бы показать ему полную страницу, а если нет, перенаправите его в форму для входа.
Зачем мне это нужно:
Приложения A и B уже построены. По-видимому, единственный способ доступа к B - это щелкнуть ссылку, расположенную в A, которая отображается только в том случае, если вы ранее зарегистрировались. Проблема в том, что если вы знаете URL-адрес какой-либо страницы B (длинный и сложный, но все же), вы можете записать его в браузере и получить доступ к B, который он означает проблему безопасности.
Ответы
Ответ 1
Я предполагаю, что вы не можете общаться между приложениями A и B, используя любой общий хранилище. (Это может позволить некоторую совместную реализацию сеанса).
Чем больше стандартного в отрасли способа (OpenID Connect) делает это, как намекают на некоторые другие ответы. Я попробую и дам более подробную информацию, чтобы вы на правильном пути.
Оба приложения A и B должны передать процесс аутентификации доверенному третьему лицу (которое может быть размещено как в A, B, так и в другом приложении) - Позвольте называть его C
Когда пользователь достигает A или B (независимо от того, что B имеет странные сложные URL-адреса, она всегда может их добавлять), его запрос должен содержать токен авторизации. Если это не так, она не аутентифицирована и будет перенаправлена на C и представлена каким-то механизмом входа в систему - скажем, пользовательская/пропуская форма.
После успешного входа в систему она перенаправляется обратно в A/B (в зависимости от того, откуда она взялась), чтобы завершить то, что она делала с токеном аутентификации. Теперь, имея настоящий токен аутентификации, она аутентифицирована.
Если она аутентифицирована с помощью A и затем перенаправлена на B, это перенаправление также должно содержать токен, B будет знать, как доверять этому токену.
Теперь, если он только откроется, откроется новая вкладка, B не увидит какой-либо токен, и поэтому она будет перенаправлена на C, только для того, чтобы быть перенаправлена обратно (она уже прошла проверку подлинности, помните?), чтобы B с маркером, и теперь все хорошо.
То, что я описал, является общим потоком, использующим OpenID-соединение, и если я использую .net, я действительно предлагаю использовать IdentityServer от Thinktecture, чтобы выполнить тяжелую работу для вас и быть вашим "C".
Другой вариант - заплатить за такое "C", размещенное как приложение SaaS, - Auth0
Ответ 2
Мой ответ может быть не лучшим, но вы можете использовать какой-то сложный механизм, например
- всякий раз, когда вы отправляетесь в другое приложение, вам нужно передать один токен из приложения A в B.
- Подтвердить этот токен на сайте B.
- и авторизовать пользователя на основе токена. (я имею в виду использование молчаливого или бэкдор-входа)
Ответ 3
Вы можете реализовать OAuth в Project. Вы можете получить дополнительную помощь здесь: http://www.openauthentication.org/about
Ответ 4
Сервер авторизации OWuth OAuth 2.0
http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server
Ответ 5
Я думаю, что вы находитесь за CAS (Central Authentication Service)
https://en.wikipedia.org/wiki/Central_Authentication_Service
имеются номера доступных поставщиков CAS. Я бы рекомендовал вам проверить это https://wiki.jasig.org/display/CAS/Home
это даст вам количество готовых решений, которые позволят веб-сервисы, написанные на определенном языке или основанные на структуре, использовать CAS. Это поможет вам внедрить решение SSO в вопрос часов
Ответ 6
Благодаря ответу @Kaushik Thanki я внедрил некоторый код, который исправил мою проблему. Я опубликую здесь решение, которое оно работает для меня, даже если это не оптимист.
Прежде всего, я применил метод A, чтобы сделать запрос на отправку B. Внутри этого метода я беру идентификатор пользователя, и я делаю хэш его с некоторыми другими параметрами и паролями. Затем я посылаю B идентификатор пользователя, хеш и логическое значение для выбора между логином и выходом из системы.
private void SendPostRequest(bool login)
{
// Create the combine string
string data = // userId combined with more stuff
// Create the hash of the combine string
HashAlgorithm algorithm = MD5.Create();
byte[] hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(data));
StringBuilder sb = new StringBuilder();
foreach (byte b in hash)
sb.Append(b.ToString("X2"));
string encriptedData = sb.ToString();
// Fill the url with the path and the data
string url = "http://localhost/xxx/yyy/ExternalAuthentication/Login?id=" + _cachedCustomer.Id + "&hash=" + encriptedData + "&login=" + login.ToString();
// Make the Post request
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream resStream = response.GetResponseStream();
}
После этого я создал в B новый класс для обработки логики входа. Я использую переменную HttpContext.Current.Application, чтобы сохранить статус аутентификации:
public class ExternalAuthenticationController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Login(string id, string hash, string login)
{
// Create the combine string
string data = //user id + same stuff than in A;
// Create the hash of the combine string
HashAlgorithm algorithm = MD5.Create();
byte[] hashArray = algorithm.ComputeHash(Encoding.UTF8.GetBytes(data));
StringBuilder sb = new StringBuilder();
foreach (byte b in hashArray)
sb.Append(b.ToString("X2"));
string originalHash = sb.ToString();
// Compare the two hash. If they are the same, create the variable
if (hash.CompareTo(originalHash) == 0)
{
if (System.Web.HttpContext.Current.Application["Auth"] == null)
{
System.Web.HttpContext.Current.Application["Auth"] = false;
}
if (Convert.ToBoolean(login))
{
System.Web.HttpContext.Current.Application["Auth"] = true;
}
else
{
System.Web.HttpContext.Current.Application["Auth"] = false;
}
}
}
Вероятно, ответ, предоставляемый @vijay shiyani, является лучшим и более обобщенным, но, с моей точки зрения, для его реализации требуется много времени.