У меня есть приложение ServiceStack, которое сосуществует с mvc5 в одном веб-проекте. Единственная цель части mvc5 - разместить одно действие контроллера, которое получает обратный вызов из janrain для инициированного javascript социального входа. Я мог бы получить этот обратный вызов в запросе службы SS тоже, но тогда я не знаю, как я буду перенаправлять на returnUrl, который проходит через весь путь из контекста javascript. Даже если бы я смог это понять, мой вопрос все равно был бы таким же.Ручная принудительная аутентификация пользователя без выдачи запроса на аутентификацию
Внутри действия контроллера, как только я проверяю, что предоставленный токен janrain разрешает пользователю в моей системе, мне нужно вручную сообщить ServiceStack «Эй, доверься мне, этому человеку разрешено».
Все мои поиски приводят к некоторому коду по линиям следующего фрагмента кода:
var authService = AppHostBase.Resolve<AuthService>();
authService.RequestContext = System.Web.HttpContext.Current.ToRequestContext();
var AuthResponse = authService.Authenticate(new Auth
{
provider = "credentials",
UserName = user.user_id,
Password = user.password,
RememberMe = true
});
Моя первая проблема в том, что я храню хеширования паролей (я поддерживаю социальную логин, а также руководство Логин), так что я не знаю пароль пользователя (и не должен).
Моя вторая проблема заключается в том, что этот код работает только для SS 3.X, а не 4.X. Мне требуется ServiceStack.ServiceInterface.dll, который таинственно отсутствует в 4.X.
Есть ли короткий и точный способ ручной аутентификации пользователя с SS на стороне сервера?
Благодаря
EDIT: До сих пор это то, что я делаю: (Это не окончательный код - я заметил некоторые вещи, которые я не знаю, что делать с):
public class UsernameOnlyAuthorizationService : Service
{
public object Post(UsernameOnlyLoginRequest request)
{
var authProvider = new UsernameOnlyAuthProvider();
authProvider.Authenticate(this, GetSession(), new Authenticate()
{
UserName = request.username,
Password = "NotRelevant",
RememberMe = true
});
return HttpResult.Redirect(request.returnUrl);
}
}
public class UsernameOnlyAuthProvider : CredentialsAuthProvider
{
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
var authRepo = authService.TryResolve<IAuthRepository>().AsUserAuthRepository(authService.GetResolver());
ReferScienceDataContext db = authService.TryResolve<ReferScienceDataContext>();
var session = authService.GetSession();
IUserAuth userAuth;
var user = db.Users.FirstOrDefault(u => u.Username == userName);
if (user != null)
{
//AssertNotLocked(userAuth);
//session.PopulateWith(userAuth);
session.Id = user.Id.ToString();
session.UserName = user.Username;
session.FirstName = user.FirstName;
session.LastName = user.LastName;
session.IsAuthenticated = true;
session.UserAuthId = user.Id.ToString(CultureInfo.InvariantCulture);
session.ProviderOAuthAccess = authRepo.GetUserAuthDetails(session.UserAuthId)
.ConvertAll(x => (IAuthTokens)x);
return true;
}
return false;
}
}
И из моей JanRain коды успеха обратного вызова Я называю это так:
HostContext.ResolveService<UsernameOnlyAuthorizationService>().Post(new UsernameOnlyLoginRequest() {username = user.Username, returnUrl= returnUrl});
Это, кажется, работает хорошо, однако, я не могу заставить его вспомнить свой сеанс через браузер закрытие s. Я hardcoding RememberMe = true - почему это не работает?
Это выглядит как отличное решение.Я собираюсь дать ему попытку и, надеюсь, я смогу принять ваш пост как ответ в ближайшее время. Спасибо. – t316
Я заметил, что вы написали этот маленький класс аутентификатора в качестве службы SS. Технически, это мог быть любой простой старый класс, который может быть введен в зависимость, правильно? Сначала я думал, что это проблема безопасности, потому что я думал о SS как о дистанционно вызываемых услугах. Тем не менее, кажется, что эти унаследованные классы служб могут быть вызваны как локальная служба, так и удаленная служба. Правильно ли я полагаю, что JanrainSuccessService нельзя назвать удаленно, потому что маршрут не определен? Очевидно, я не хочу, чтобы какое-либо удаленное приложение javascript могло выдавать себя за кого-то ... – t316
@ t316 Я добавил его как услугу, потому что он автоматически подключает решение сеанса, и для решения других зависимостей меньше кода. Но вы правы, что вы не делаете этого *, если вы сами разрешаете зависимости из HostContext. Что касается безопасности, доступ к этому методу отсутствует, потому что нет пути к нему. И имя метода не является именем метода 'HTTP', таким как' Get' или 'Post'. Вы можете подтвердить это, просмотрев метаданные, где метод не будет показан. – Scott