zoukankan      html  css  js  c++  java
  • asp.net权限认证:OWIN实现OAuth 2.0 之客户端模式(Client Credential)

    客户端模式定义

    客户端使用自己的名义,而不是用户的名义,向“服务提供商” 进行认证。

    如何理解这句话? 乍一看,定义有点拗口,刚接触的童鞋可能完全不知所云。

    没关系,我们先把他的工作流程图画出来,如下:

    据上图,可以得出一个大概的结论

    1、用户(User)通过客户端(Client)访问受限资源(Resource)

    2、因为资源受限,所以需要授权;而这个授权是Client与Authentication之间完成的,可以说跟User没有什么关系

    3、根据2得出,Resource与User没有关联关系,即User不是这个Resource的Owner(所有者)

    既然是这样,那大概可以推出这种认证的适用范围。

    第一,肯定不能用作登录认证!因为登录认证后需要得到用户的一些基本信息,如昵称,头像之类,这些信息是属于User的;

    第二,适用于一些对于权限要求不强的资源认证,比如:仅用于区分用户是否登录,排除匿名用户获取资源

    新建一个资源项目: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)
  • 相关阅读:
    linux网络编程之socket编程(三)
    linux网络编程之socket编程(二)
    字符串转成时间戳
    xls的读写
    统计词语频率保存到xls
    信息时代的学习(对于人类)
    编码格式简介:ASCII码、ANSI、GBK、GB2312、GB18030和Unicode、UTF-8,BOM头
    ThinkPHP中:RBAC权限控制的实习步骤
    getField()和select()方法的区别
    按钮美化,变化显示效果
  • 原文地址:https://www.cnblogs.com/lanxiaoke/p/6358332.html
Copyright © 2011-2022 走看看