2

I am developing a website using ASP.NET MVC with an API using ServiceStack.

Very soon I want to add authentication. The website will have at least two types of users 'service providers' and 'service consumers', although a user could have multiple roles.

I am open to using new MVC Identity, but I want whatever I use to work nicely for both the servicestack API and MVC 'pages' that don't necessarily use the API but should show different content based on login. I do not want to require javascript for login/logout.

I would like the solution to use tokens as I have not used session state anywhere else, but I am open to other options providing they would scale horizontally on a cloud provider (users next request may go to a different instance of back-end).

Anyone have example of an ideal solution?

(N.B: I am not interested in an externally hosted service).

1
  • (I know about ServiceStack authentication and I have used it for a SPA API, but have not integrated with ASP.NET MVC or tokenised it before) Commented Nov 19, 2014 at 0:35

2 Answers 2

2

ServiceStack's Authentication can also be used by external ASP.NET Web Frameworks, the ServiceStack and MVC Integration docs shows how you can accept Login credentials from a MVC Controller and register them with ServiceStack:

public ActionResult Login(string userName, string password, string redirect=null)
{
    if (ModelState.IsValid)
    {
        try
        {
            using (var authService = ResolveService<AuthenticateService>())
            {
                var response = authService.Authenticate(new Authenticate {
                    provider = CredentialsAuthProvider.Name,
                    UserName = userName,
                    Password = password,
                    RememberMe = true,
                });

                // add ASP.NET auth cookie
                FormsAuthentication.SetAuthCookie(userName, true);

                return Redirect(string.IsNullOrEmpty(redirect) ? "/" : redirect);
            }
        }
        catch (Exception ex)
        {
            ModelState.AddModelError(string.Empty, ex.Message);
        }
    }

    return View("Index", GetViewModel());
}

The http://mvc.servicestack.net Live Demo shows an example of calling this controller using a standard MVC HTML Form.

Your MVC Controllers can then inherit ServiceStackController to access the Authenticated Users Session and different ServiceStack providers, here are the API's relating to Session and Authentication:

public class ServiceStackController : Controller
{
    //...
    ISession SessionBag { get; set; }
    bool IsAuthenticated { get; set; }
    IAuthSession GetSession(bool reload = true);
    TUserSession SessionAs<TUserSession>();
    void ClearSession();
}

Enable OAuth Providers

Should you need to you can also enable ServiceStack's different OAuth providers which can optionally callback either directly to a ServiceStack Service or

Sign up to request clarification or add additional context in comments.

4 Comments

I was of course hoping for you to answer, I've put a related question here: stackoverflow.com/questions/27180162/…
@Darren Couldn't tell you, never used ASP.NET Identity so not sure what the appropriate integration strategy would be. Don't have time to R&D myself, but some approaches I'd explore include a custom AuthProvider that's expected to be called via MVC in an OnAuthentication callback, if that's not possible another approach is to manually save a AuthUserSession in ServiceStack's Session yourself, you may also need to manually set ServiceStack's ss-id / ss-pid cookies on the Response yourself as Identity is based on OWIN instead of the ASP.NET context so any cookies SS sets might be ignored.
if you have 3 mins look at what I added below, perhaps I don't need/want GeType().Name in there.
@Darren it's ok, the OperationName is basically metadata to identify the name of the Request DTO, it's not used in Views.
1

Further to mythz answer I also needed to know if a user was authenticated in a view and the normal Request.IsAuthenticated does not work when your doing above. So I created a CustomWebViewPage (to use this you will have to change *pageBaseType="Your.NameSpace.CustomWebViewPage" in the View folder's Web.config).

public abstract class CustomWebViewPage : WebViewPage
{
    private IServiceStackProvider _serviceStackProvider;
    public virtual IServiceStackProvider ServiceStackProvider
    {
        get
        {
            return _serviceStackProvider ?? (_serviceStackProvider =
                new ServiceStackProvider(new AspNetRequest(base.Context, GetType().Name)));
        }
    }

    public virtual bool IsAuthenticated
    {
        get { return ServiceStackProvider.IsAuthenticated; }
    }
}

public abstract class CustomWebViewPage<TModel> : WebViewPage<TModel>
{
    //EXACTLY the same as above method...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.