Can two different OWIN applications authorize an OAuth2 bearer access token?

This question already has an answer here:

  • Using Oauth tickets across several services? 4 answers

  • Yes, you can decouple the authorization server and the resource server. They could live in different owin apps and not only that, they can even live on different servers.

    The authorization server would be responsible to issue access tokens to your client application and, eventually, manage users and roles.

    The resource server would host the protected resource, accepting access tokens released by the authorization server.

    Looking at your infrastructure your Identity API would be the authorization server and Product API would be your resource server.

    The authorization server needs to configure and use an implementation of OAuthAuthorizationServerProvider .
    In your startup you would do something like this:

    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    
    var OAuthOptions = new OAuthAuthorizationServerOptions
    {
        AllowInsecureHttp = true,
        TokenEndpointPath = new PathString("/oauth/Token"),
        AccessTokenExpireTimeSpan = TimeSpan.FromHours(8),
        Provider = new MyAuthorizationServerProvider(),
        // RefreshTokenProvider = new MyRefreshTokenProvider(DateTime.UtcNow.AddHours(8))
    };
    
    app.UseOAuthAuthorizationServer(OAuthOptions);
    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
    

    As you can see I've used MyAuthorizationServerProvider as custom provider for the authentication.

    It is responsible to validate the client ( ValidateClientAuthentication ) and grant the authorization to access the resource ( GrantResourceOwnerCredentials ).

    GrantResourceOwnerCredentials will check if the credentials of the client (username & password) are valid and release a valid token:

    var ticket = new AuthenticationTicket(identity, props);
    context.Validated(ticket);
    

    The AuthenticationTicket receives a ClaimsIdentity object and a collection of AuthenticationProperties .

    You would normally add the username claim and the roles here:

    ClaimsIdentity identity = new ClaimsIdentity(context.Options.AuthenticationType);
    identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
    identity.AddClaim(new Claim(ClaimTypes.Role, "Users"));
    

    and, eventually, other types of claims you might want to use.
    The AuthenticationProperties collection would define your extended info you want to pass to the client:

    var props = new AuthenticationProperties(new Dictionary<string, string>
    {
        { 
        "name", "John"
        },
        { 
        "surname", "Smith"
        },
        { 
        "age", "40"
        },
        { 
        "gender", "Male"
        }
    });
    

    You can check this github repo to have a look at the implementation.

    Your resource server, the RESTful APIs responsible to manage your business info, won't have to re-implement the whole authorization/authentication layer.

    In your startup ( Product API ) you would simply instruct the api to use and consume bearer tokens:

    public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();
    
        OAuthBearerAuthenticationOptions OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
        app.UseOAuthBearerAuthentication(OAuthBearerOptions);
    
        WebApiConfig.Register(config);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(config);
    }
    

    And your protected resource would be something like this:

    [Authorize(Roles = "Users")]
    public class ProductsController : ApiController
    {
        public Models.Product GetProduct(string id)
        {
            var identity = User.Identity as ClaimsIdentity;
    
            return new Models.Product();
        }
    }
    

    As you can see I've used the Authorize attribute cause I only want to authorize a certain type of user.

    NOTE:

    If you want to host the authorization server and the resource server on to different machines, you have to make sure you're sharing the same machineKey on both server or the resource server won't be able to decrypt the bearer token released by authorization server :

    <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
        <machineKey validationKey="VALUE GOES HERE" 
                    decryptionKey="VALUE GOES HERE" 
                    validation="SHA1" 
                    decryption="AES"/>
    </system.web>
    

    I would suggest you to read this article to find a really good explanation about all the pieces involved.

    Taisser also as another article where he goes through the same process using Json Web Tokens to achieve the same result.

    链接地址: http://www.djcxy.com/p/22422.html

    上一篇: WebAPI混合身份验证与OWIN令牌和Windows身份验证

    下一篇: 两个不同的OWIN应用程序可以授权OAuth2载体访问令牌吗?