9

I've overridden the CredentialsAuthProvider like so:

public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
        {
            //TODO: Auth the user and return if valid login
            return true;
        }

public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IOAuthTokens tokens, Dictionary<string, string> authInfo)
        {
            base.OnAuthenticated(authService, session, tokens, authInfo);

            //User has been authenticated

            //Find the user's role form the DB

            if (roleA)
                //GOTO mypage1

            if (roleB)
                //GOTO mypage2
        }

I perform a simple post to ~/auth/Credentials and while the authentication works and the OnAuthenticated method is called, how do I actually redirect the user to the appropriate page based on a role or something similar?

I tired to do the following in the OnAuthenticated method but it did not have the desired effect:

authService.("/views/customers");

Update using Starter Template (see comment below):

public class CustomCredentialsAuthProvider : CredentialsAuthProvider
    {
        public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
        {
            return true;
        }

        public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IOAuthTokens tokens, Dictionary<string, string> authInfo)
        {
            session.ReferrerUrl = "http://www.msn.com";

            base.OnAuthenticated(authService, session, tokens, authInfo);
        }
    }

And the form to POST:

<form method="POST" action="/auth/credentials">
        <input name="UserName"/>
        <input name="Password" type="password"/>
        <input type="submit"/>
    </form>
legion
  • 497
  • 1
  • 5
  • 15

2 Answers2

7

The different places where you can set the Url to redirect to during ServiceStack Authentication, in order of precedence are:

  1. The Continue QueryString, FormData or Request DTO variable when making the request to /auth
  2. The Session.ReferrerUrl Url
  3. The HTTP Referer HTTP Header
  4. The CallbackUrl in the AuthConfig of the current AuthProvider used

Given these order of preferences, if the request didn't have a Continue parameter, it should use the session.ReferrerUrl, so you could do:

if (roleA) session.ReferrerUrl = "http://myPage1Url";
if (roleB) session.ReferrerUrl = "http://myPage2Url";
mythz
  • 141,670
  • 29
  • 246
  • 390
  • That worked...sort of...here is the behavior: I have to submit the form twice. Here is my setup: i have a default.cshtml Content Page in the root where the login form is. Watching fiddler, the only difference i can see is that, the first time i load the page, i don't have a ss-id cookie. Once i submit the form, the server send me back to default.cshtml. But this time with an ss-id. If i submit this second time, the redirection you described works. Whats up with the ss-id? – legion Nov 13 '12 at 18:06
  • One more note, I do get ss-pid and I have Plugins.Add(new SessionFeature()); in AppHost. – legion Nov 13 '12 at 18:09
  • The `ss-id` is described in [ServiceStack's Session Wiki page](https://github.com/ServiceStack/ServiceStack/wiki/Sessions) – mythz Nov 13 '12 at 18:30
  • Ok. Just to make sure i'm not going insane, I installed the Starter ASP.NET WebSite Template - ServiceStact nuget package. Here is the simple form: https://gist.github.com/4068164 and the auth provider: https://gist.github.com/4068170 That's it. Run it with the starter template and you'll see you have to post twice before the redirect to msn.com. – legion Nov 13 '12 at 20:28
  • Is the first page you load the HTML form from a ServiceStack page or something else? – mythz Nov 13 '12 at 21:37
2

mythz,

Good call on making this OSS. :)

You are correct regarding the order of precedence:

  1. The Continue QueryString, FormData or Request DTO variable when making the request to /auth
  2. The Session.ReferrerUrl Url The HTTP
  3. Referer HTTP Header
  4. The CallbackUrl in the AuthConfig of the current AuthProvider used

So in my example, I didn't have the Continue QueryString, Form Data or Request DTO variable, and I didn't have the CallbackUrl, and certainly not the Session.ReferrerUrl because this is the first post of the Session.

From AuthService.cs:

var referrerUrl = request.Continue
    ?? session.ReferrerUrl
    ?? this.RequestContext.GetHeader("Referer")
    ?? oAuthConfig.CallbackUrl;

By default referrerUrl will have the Referer header value from the request. And that is what is going to be assigned to the Location header further down the Post method of the AuthService.cs:

if (!(response is IHttpResult))
                    {
                        return new HttpResult(response) {
                            Location = referrerUrl
                        };
                    }

Once authenticated, and the session.ReferrerUrl is set here the response will be sent to the client with the Location property above set to the original referrer, not the value below:

public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IOAuthTokens tokens, Dictionary<string, string> authInfo)
        {
            session.ReferrerUrl = "http://www.msn.com";
        }

It's only on the second POST of the same session will the client navigate to www.msn.com (in this example) because the session has already been populated. I think this:

var referrerUrl = request.Continue
                ?? session.ReferrerUrl
                ?? this.RequestContext.GetHeader("Referer")
                ?? oAuthConfig.CallbackUrl;

Needs to be determined after the call to auth.

legion
  • 497
  • 1
  • 5
  • 15
  • Agreed, fixed [in this commit](https://github.com/ServiceStack/ServiceStack/commit/49833b731d2d8e402be358088ca060cb8bab42f0), available in the next release of ServiceStack at the end of the week. BTW, feel free to send a pull-request for future stuff like this :) – mythz Nov 14 '12 at 13:41
  • 1
    Awesome. Will do for next time, and btw, great framework. I won't be looking back... I'm sure you've heard this before but SS needs more docs and best practices. – legion Nov 14 '12 at 15:34
  • I think the [ServiceStack wiki](https://github.com/ServiceStack/ServiceStack/wiki) is already quite comprehensive. It's a community wiki so if you feel something could be improved - feel free to add it. – mythz Nov 14 '12 at 15:54