13

I have set up an OWIN authorization server and several resource servers exposing ASP.NET Web APIs. I am serving up a JWT from the authorization server that is specific to each resource server (the idea being that each resource server needs custom claims wrapped up in its token).

These servers are all in an intranet environment where we historically have used Windows Authentication (Kerberos) to provide a single sign-on experience. This feature has been lost in my implementation because I am using the user's username and password (authenticated against AD) to grant a token. What I am wondering is if there is a way to get a single sign-on experience back - maybe by using Windows Authentication to establish the identity of a user before granting them a token?

I feel like this is somewhat unorthodox and might be dumb - so please tell me if there is a better, alternative approach to getting SSO with OAuth 2.0 in an intranet environment.

Joshua Barron
  • 1,532
  • 2
  • 26
  • 42

1 Answers1

11

As it turns out, this wasn't as hard as I expected. I created a standard web API controller off of an alternative endpoint (/token/windows/). This endpoint takes an HTTP POST with the client (resource) ID the Windows user is trying to connect to. I put the standard [Authorize] attribute on the action to ensure that identity is established, then I manually create a claims identity and return a JWT to the user. From that point on the user uses the standard token refresh process.

Edit: here's a sample below that represents what I implemented. Note that this app is configured in IIS to support Windows Authentication (in addition to anonymous authentication):

[RoutePrefix("token/windows")]
public class WindowsAuthenticationController : ApiController
{
    [Authorize]
    [HttpPost]
    [Route("{client_id}"]
    public async Task<IHttpActionResult> CreateTokenForWindowsIdentity(string client_id)
    {
        var user = User as ClaimsPrincipal;
        if (user == null) return Unauthorized(); //401
        var claims = //generate claims based on the User.Identity.Name...
        var identity = new ClaimsIdentity("JWT");
        identity.AddClaims(claims);

        //manually create JWT using whatever method you prefer,
        //I used something inspired from http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-and-identity-2/
    }
}
Joshua Barron
  • 1,532
  • 2
  • 26
  • 42
  • Do you have a code sample, or any links to show how this was done? – Eric Burdo Apr 13 '15 at 16:17
  • 2
    Joshua, is your authorization server and resource server the same or different? If you are doing a role based resource server then by wrapping the [Authorize] attribute would conflict with what is configured for the consumption of tokens. When you call "CreateTokenForWindowsIdentity" it would then expect the request to have a valid token because of this Authorize attribute. How did you architect your Resource and Authentication server to achieve both windows auth and token based auth? Thx – nav Mar 30 '16 at 21:30
  • No, the authorization server is separate from the resource servers. The authorization server only supports anonymous and Windows authentication. Resource servers are configured to use anonymous authentication but the APIs enforce the use of tokens. – Joshua Barron Mar 30 '16 at 21:33
  • If I wanted to create the Resource Owner Password Credentials flow (OAuth 2.0) with the same authorization server you have created for windows authentication, is this possible? Or have you created two different authorization servers, one for oauth2.0 and one for windows auth? Thanks – nav Mar 31 '16 at 14:10
  • You just need one authorization server. Set up an authorization server as normal supporting the resource owner flow and then add an MVC controller as per my sample above. As long as you configure the site to support both IIS and Windows authentication, you should be good to go - it's a little weird but it works. – Joshua Barron Mar 31 '16 at 14:50
  • I was searching for the same thing just now, for interest are you using this to create a single-point authentication and role management framework for your internal systems? Since you've set "Windows authentication" on the Authorization server I imagine your protected endpoints are protected by the the actual claims roles of your OAUTH server and not just [Authorize]? – LimpingNinja Apr 01 '16 at 13:23
  • @JoshuaBarron Setting up one Authorization Server that works for both OAuth and Windows is great. But I am facing an issue when I would like my Authorization Server to have both ways of authenticating and also make it the same as my resource server. To make everything in one, is that still possible, if so can you please explain? – nav Apr 01 '16 at 22:11
  • 3
    A note to anyone finding this question/answer - I do not think this setup is optimal and is a bit hacky. I have moved on to using an OpenID connect setup where I have a separate (windows-authenticated) service that acts as an identity provider. – Joshua Barron Jun 15 '16 at 16:28
  • 3
    @JoshuaBarron Can you provide some insights about windows authentication + openID or oauth implemention in your authentication server – ciril sebastian Apr 26 '17 at 13:47
  • 1
    @JoshuaBarron Can you share more details about your solution, please? – Diego Dias Feb 02 '18 at 15:57