locked
OWIN MVC Reverse Proxy RRS feed

  • Question

  • User2007938681 posted

    Hi

    I have new MVC project created using the VS2103 Update 2 RC template with a individual user account authentication method.  The web site will sit behind a reverse proxy meaning all users must authenticate to the reverse proxy before accessing the site.  Once authenticated at the reverse proxy can add a basic authentication header or a custom header that contains the user name.  There is no need to authentice the user again in the MVC web app.

    I've writtern the following code as the startup class, the claim gets created, but the Register and Sign in links (top right corner of the page) don't update with the authenticated user.  Any ideas how to make that happen?

    public class Startup {
        public static void Configuration(IAppBuilder app) {
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
            app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions() {
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/token"),
                Provider = new OAuthAuthorizationServerProvider() {
                OnValidateClientAuthentication = async c =>
                    {
                        c.Validated();
                    },
    
                    OnGrantResourceOwnerCredentials = async c =>
                    {
    string username = c.Request.Headers["proxy_user"]; if (!string.IsNullOrEmpty(username) { ClaimsIdentity id = new ClaimsIdentity( new Claim[] { new Claim(ClaimTypes.Name, username) }, OAuthDefaults.AuthenticationType); c.Validated(id); } } } }); } }

    thanks

    Monday, May 12, 2014 6:18 PM

All replies

  • User1779161005 posted

    By doing basic auth at the proxy, you've decided how you want to authenticate the API call. I don't see the need for doing OAuth2 then. The OAuth2 plumbing you're adding is code to issue a token to the caller, and that's not needed since you need to do this with basic auth. So in short, basic auth is your token for authenticating (and not a token issues from OAuth2).

    Hope this makes some sense.

    Monday, May 12, 2014 6:52 PM
  • User2007938681 posted

    Hi Brock

    Thanks for the reply.  So if I've understood correctly, my reverse proxy can add the Authorization header with a value being "Basic base64encodedstring"  The base64 string represents the user name and a dummy password (set by the reverse proxy).

    As the user has already authenticated to the reverse proxy (the reverse proxy issues a session cookie), all I need to do is pull the user name from the base64 encoded string and maybe verify the dummy password against a config setting and tell the MVC app that the user is authenticated - which I presummed meant issuing a token.  In otherwords I need to bypass the account controller.Login method.

    Firts time at MVC and OWIN, bare with me :-|

    Monday, May 12, 2014 7:51 PM
  • User1779161005 posted

    Well, what it sounded like to me was that due to the reverse proxy all calls had to use basic auth. Once that's done, then the proxy could add any header to pass along the user's username and then in your code you can just use that to know who the user is. None of this has anything to do with owin/katana or OAuth2.

    Monday, May 12, 2014 7:58 PM
  • User2007938681 posted

    Yeah you're right, it probably doesn't have anything to do with owin\katana...  In an out of the box MVC app created using an individual user account authentication the Startup class looks like this:

    // Configure the db context and user manager to use a single instance per request
    app.CreatePerOwinContext(ApplicationDbContext.Create);
    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    
    // Enable the application to use a cookie to store information for the signed in user
    // and to use a cookie to temporarily store information about a user logging in with a third party login provider
    // Configure the sign in cookie
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        Provider = new CookieAuthenticationProvider
        {
            OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                validateInterval: TimeSpan.FromMinutes(30),
                regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
        }
    });
                
    app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

    I just need to authenticate a user in the MVC app from a header in code.  So perhaps I need to use the app.UserExternalSignInCookie or create a custom provider.  This is where I'd like some guidance as to my next step(s).

    thanks

    Monday, May 12, 2014 8:29 PM
  • User1779161005 posted

    Well, if every call has the username in a header from the proxy, then do you need to issue a cookie? You can of course, but then you'd have two tokens in every call that represents the user.

    Anywaym, if you want to issue a cookie, then look at this for some more info:

    http://brockallen.com/2013/10/24/a-primer-on-owin-cookie-authentication-middleware-for-the-asp-net-developer/

    Or are these calls all API/Ajax calls?

    Monday, May 12, 2014 8:34 PM
  • User2007938681 posted

    ok.  let's say I don't bother with the cookie, how would I get the username injected from the reverse proxy header to appear in the banner?  Currently there isn't a use case for API/Ajax calls.

    Monday, May 12, 2014 8:43 PM
  • User1779161005 posted

    Well, you said the proxy puts in a request header, right? So use MVC to access the Request.Headers and grab the one you're expecting.

    Monday, May 12, 2014 8:50 PM
  • User2007938681 posted

    basically modify the _LoginPartial.cshtml page to perform the signin from the request header

    Monday, May 12, 2014 10:16 PM