简体   繁体   中英

Reconnecting to Servicestack session in an asp.net MVC4 application

I have an asp.net mvc4 web application that is consuming data data from an API written in C# and hosted on a Linux machine w/ Apache / mod_mono

The client application is written in C#/asp.net - It runs on a different web server, also Linux / Apache / mod_mono. I'm not sure if those details are important in this case, but I figured any background may help.

The question leading up to this one: AppHostBase instance not set - Helped me gain quite a bit more understanding of how this all fits together.

I believe the proper question I should be asking now is: Once I create a session in servicestack (On the API server), how do I properly reconnect to it?

Following the answers in previous questions, I've used this bit of code in my auth controller on the client application:

        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
            });

This returns a ResolutionException:
Required dependency of type ServiceStack.ServiceInterface.Auth.AuthService could not be resolved.

Is there something simple I might be missing when it comes to getting the client to work from within an asp.net application?

I apologize if the question is too vague and will happily provide any more information.

Update:
This is AuthController - Excuse the mess, I've been trying a few things since my last post:

{
public partial class AuthController : BaseController
{
    JsonServiceClient client = new ServiceStack.ServiceClient.Web.JsonServiceClient("<TheAPIurl>");

    // GET: /Login/

    public ActionResult login()
    {
        if (Session["IsAuthenticated"] != null)
        {
            ViewData["Result"] = Session["IsAuthenticated"];
        }

        return View();
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult login(UserModel user)
    {
        try
        {
        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
            });

            if (AuthResponse.SessionId != null)
            {
                Session["IsAuthenticated"] = true;
                Session["UserID"] = AuthResponse.UserName;
                Session["jsclient"] = client; 
                FormsAuthentication.SetAuthCookie(user.user_id, true);
                return Redirect("/default");
            }
            else
            {
                Session["IsAuthenticated"] = false;
            }

        }
        catch (Exception ex)
        {
            Session["IsAuthenticated"] = false;
        }

        return View();
    }
    protected override void ExecuteCore()
    {
        throw new NotImplementedException();
    }
}

}

Authenticating with a local ServiceStack instance

You can only retrieve an auto-wired ServiceStack service (or other IOC dependency) out from a ServiceStack Container if the ServiceStack instance is hosted within the same App Domain as MVC, ie:

var authService = AppHostBase.Resolve<AuthService>();
authService.RequestContext = System.Web.HttpContext.Current.ToRequestContext();

Although the recommended code for resolving the auto-wired implementation of another service is:

using (var authAservice = AppHostBase.ResolveService<AuthService>()) {
    ...
}

ie As services may make use of resources that should be disposed. Inside a ServiceStack service you should use base.ResolveService<AuthService>() instead.

So if ServiceStack hosted within the same AppDomain as MVC, you can call the Service directory, like this:

var authResponse = authService.Authenticate(new Auth {
    provider = "credentials",
    UserName = user.user_id,
    Password = user.password,
    RememberMe = true
});

Authenticating with a Remote ServiceStack instance

Otherwise if it's remote you need to use one of ServiceStack's C# Service Clients , eg:

var client = new JsonServiceClient(ServiceStackBaseUrl);
var authResponse = client.Post(new Auth {
    provider = "credentials",
    UserName = user.user_id,
    Password = user.password,
    RememberMe = true
});

Attaching ServiceStack SessionId back to originating MVC request

This will setup an authenticated session with that ServiceClient client, by attaching it to the ss-pid Cookie (see Session docs for more info). You can pass through this cookie to the originating browser that called MVC with:

var response = HttpContext.Current.Response.ToResponse();
response.Cookies.AddSessionCookie(
    SessionFeature.PermanentSessionId, authResponse.SessionId);

Subsequent requests with the authenticated session

To re-attach with the remote authenticated ServiceStack Session from within MVC you would then need to pass the cookie back into the Service Client, eg:

var cookie = HttpContext.Request.Cookies.Get(SessionFeature.PermanentSessionId);

var client = new JsonServiceClient(ServiceStackBaseUrl);
var cookie = new Cookie(SessionFeature.PermanentSessionId, cookie.Value);
client.CookieContainer.Add(cookie);

You can set the cookie domain, globally in the Web.Config:

<httpCookies domain="mydomain.com" />

Or at runtime with:

cookie.Domain = "mydomain.com";

The ServiceStack AuthTests.cs Integration Tests has some other useful examples showing how Authentication works in ServiceStack.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM