asp.net權限認證:OWIN實現OAuth 2.0 之客戶端模式(Client Credential)

客戶端模式定義

客戶端使用本身的名義,而不是用戶的名義,向「服務提供商」 進行認證。html

 

如何理解這句話? 乍一看,定義有點拗口,剛接觸的童鞋可能徹底不知所云。api

不要緊,咱們先把他的工做流程圖畫出來,以下:服務器

據上圖,能夠得出一個大概的結論app

一、用戶(User)經過客戶端(Client)訪問受限資源(Resource)asp.net

二、由於資源受限,因此須要受權;而這個受權是Client與Authentication之間完成的,能夠說跟User沒有什麼關係ide

三、根據2得出,Resource與User沒有關聯關係,即User不是這個Resource的Owner(全部者)post

 

既然是這樣,那大概能夠推出這種認證的適用範圍。ui

第一,確定不能用做登陸認證!由於登陸認證後須要獲得用戶的一些基本信息,如暱稱,頭像之類,這些信息是屬於User的;url

第二,適用於一些對於權限要求不強的資源認證,好比:僅用於區分用戶是否登陸,排除匿名用戶獲取資源spa

 

新建一個資源項目:ResourceServer

 

引用owin:install-package Microsoft.Owin -Version 2.1.0

新增Startup.cs

[assembly: OwinStartup(typeof(ResourceServer.Startup))]
namespace ResourceServer
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }
    }
}

新增Startup.Auth.cs

namespace ResourceServer
{
    public partial class Startup
    {
        public void ConfigureAuth(IAppBuilder app)
        {
       // 這句是資源服務器認證token的關鍵,認證邏輯在裏邊封裝好了,咱們看不到 app.UseOAuthBearerAuthentication(new Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationOptions()); } } }

新增ValuesController.cs

namespace ResourceServer.Controllers
{
    [Authorize]
    public class ValuesController : ApiController
    {
        public string Get()
        {
            return "lanxiaoke";
        }
    }
}

 

新建認證服務項目

修改Startup.Auth.cs

public partial class Startup
    {
        public void ConfigureAuth(IAppBuilder app)
        {
            // Setup Authorization Server
            app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/OAuth/Token"),
                ApplicationCanDisplayErrors = true,
#if DEBUG
                AllowInsecureHttp = true,
#endif
                // Authorization server provider which controls the lifecycle of Authorization Server
                Provider = new OAuthAuthorizationServerProvider
                {
                    OnValidateClientAuthentication = ValidateClientAuthentication,
                    OnGrantClientCredentials = GrantClientCredetails
                },

                // Authorization code provider which creates and receives authorization code
                AuthorizationCodeProvider = new AuthenticationTokenProvider
                {
                    OnCreate = CreateAuthenticationCode,
                    OnReceive = ReceiveAuthenticationCode,
                },

                // Refresh token provider which creates and receives referesh token
                RefreshTokenProvider = new AuthenticationTokenProvider
                {
                    OnCreate = CreateRefreshToken,
                    OnReceive = ReceiveRefreshToken,
                }
            });
        }

        private Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            string clientId;
            string clientSecret;
            if (context.TryGetBasicCredentials(out clientId, out clientSecret) ||
                context.TryGetFormCredentials(out clientId, out clientSecret))
            {
                if (clientId == "123456" && clientSecret == "abcdef")
                {
                    context.Validated();
                }
            }
            return Task.FromResult(0);
        }

        private Task GrantClientCredetails(OAuthGrantClientCredentialsContext context)
        {
            var identity = new ClaimsIdentity(new GenericIdentity(context.ClientId, OAuthDefaults.AuthenticationType), context.Scope.Select(x => new Claim("urn:oauth:scope", x)));
            context.Validated(identity);
            return Task.FromResult(0);
        }

        private readonly ConcurrentDictionary<string, string> _authenticationCodes =
            new ConcurrentDictionary<string, string>(StringComparer.Ordinal);

        private void CreateAuthenticationCode(AuthenticationTokenCreateContext context)
        {
            context.SetToken(Guid.NewGuid().ToString("n") + Guid.NewGuid().ToString("n"));
            _authenticationCodes[context.Token] = context.SerializeTicket();
        }

        private void ReceiveAuthenticationCode(AuthenticationTokenReceiveContext context)
        {
            string value;
            if (_authenticationCodes.TryRemove(context.Token, out value))
            {
                context.DeserializeTicket(value);
            }
        }

        private void CreateRefreshToken(AuthenticationTokenCreateContext context)
        {
            context.SetToken(context.SerializeTicket());
        }

        private void ReceiveRefreshToken(AuthenticationTokenReceiveContext context)
        {
            context.DeserializeTicket(context.Token);
        }
    }

自此,認證服務項目算是建好了,由於對於客戶端模式,認證服務器只須要返回token

 

新增Client項目

     static void Main(string[] args)
        {
            var authorizationServerUri = new Uri("http://localhost:8270/");
            var authorizationServerDescription = new AuthorizationServerDescription
            {
                TokenEndpoint = new Uri(authorizationServerUri, "OAuth/Token")
            };

            var client = new WebServerClient(authorizationServerDescription, "123456", "abcdef");
            var state = client.GetClientAccessToken(new[] { "scopes1", "scopes2" });
            var token = state.AccessToken;
            Console.WriteLine("Token: {0}", token);

            var resourceServerUri = new Uri("http://localhost:8001/");
            var httpClient = new HttpClient(client.CreateAuthorizingHandler(token));
            var values = httpClient.GetStringAsync(new Uri(resourceServerUri, "api/Values")).Result;
            Console.WriteLine("Result: {0}", values);

            Console.ReadKey();
        }

 

OK,Client環境搭好了,咱們來運行下試試

 

認證成功!

  

asp.net權限認證系列

  1. asp.net權限認證:Forms認證
  2. asp.net權限認證:HTTP基本認證(http basic)
  3. asp.net權限認證:Windows認證
  4. asp.net權限認證:摘要認證(digest authentication)
  5. asp.net權限認證:OWIN實現OAuth 2.0 之客戶端模式(Client Credential)
  6. asp.net權限認證:OWIN實現OAuth 2.0 之密碼模式(Resource Owner Password Credential)
  7. asp.net權限認證:OWIN實現OAuth 2.0 之受權碼模式(Authorization Code)
  8. asp.net權限認證:OWIN實現OAuth 2.0 之簡化模式(Implicit)
相關文章
相關標籤/搜索