ServiceStack - Custom CredentialsAuthProvider in .Net MVC Application
I am trying to authenticate with MVC and ServiceStack following the example here - https://github.com/ServiceStack/ServiceStack.UseCases/tree/master/CustomAuthenticationMvc . My problem is that I cannot successfully authenticate with the ServiceStack on my initial Account / LogOn request.
ServiceStack related code in LogOn method of AccountController:
var apiAuthService = AppHostBase.Resolve<AuthService>();
apiAuthService.RequestContext = System.Web.HttpContext.Current.ToRequestContext();
var apiResponse = apiAuthService.Authenticate(new Auth
{
UserName = model.UserName,
Password = model.Password,
RememberMe = false
});
I have my own authentication provider that subclasses the CredentialsAuthProvider. I Configure as follows in the AppHost class:
var appSettings = new AppSettings();
Plugins.Add(new AuthFeature(() => new CustomUserSession(),
new IAuthProvider[] {
new ActiveDirectoryAuthProvider(),
}));
public override bool TryAuthenticate(ServiceStack.ServiceInterface.IServiceBase authService, string userName, string password)
{
//class to authenticate against ActiveDirectory
var adAuthentication = new ActiveDirectoryAuthenticationService();
if (!adAuthentication.Authenticate(userName, password))
return false;
var session = (CustomUserSession)authService.GetSession(false);
session.IsAuthenticated = true;
session.UserAuthId = session.UserAuthName;
authService.SaveSession(session, SessionExpiry);
return true;
}
I think my problem is that session.Id is null at the moment and saving the session continues with "urn: iauthsession:" in "SessionCache". However, I'm not sure how to fill in the session.Id correctly . Also, this may or may not be an issue, but the original LogOn request is the account / login that MVC handles. So there is no request to the ServiceStack prior to calling AuthService.Authenticate () in the AccountController.
In my subclass CredentialsAuthProvider, a possible solution I came up with was added.
public override bool TryAuthenticate(ServiceStack.ServiceInterface.IServiceBase authService, string userName, string password)
{
//class to authenticate against ActiveDirectory
var adAuthentication = new ActiveDirectoryAuthenticationService();
if (!adAuthentication.Authenticate(userName, password))
return false;
var session = (CustomUserSession)authService.GetSession(false);
//A possible solution???
if(session.Id == null)
{
var req = authService.RequestContext.Get<IHttpRequest>();
var sessId = HttpContext.Current.Response.ToResponse().CreateSessionIds(req);
session.Id = sessId;
req.SetItem(SessionFeature.SessionId, sessId);
}
//end possible solution
session.IsAuthenticated = true;
session.UserAuthId = session.UserAuthName;
authService.SaveSession(session, SessionExpiry);
return true;
}
Is there a configuration or call I am missing to "hook up" ServiceStack authentication in MVC?
Thank.
source to share
The only thing I do in my TryAuthenticate is validate the username, password and return true if valid.
I have another override method called OnAuthenticated where I store the session information. OnAuthenticated passes the Auth Service and Session parameter as a parameter, so you only need:
public override void OnAuthenticated(IServiceBase authService, IAuthSession session,.....
{
session.IsAuthenticated = true;
session.....
authService.SaveSession(session, SessionExpiry);
}
It seems that I am keeping the session information while I have registered the ICacheClient.
source to share