• 【7】.net WebAPI Owin OAuth 2.0 密码模式验证实例


    1.OAuth密码模式

    2.在VS中创建WebAPI项目

    在nuget中安装:

    Microsoft.AspNet.WebApi.Owin

    Microsoft.Owin.Host.SystemWeb

    这两个类库并添加Owin启动类Startup

    using System;
    using System.Threading.Tasks;
    using Microsoft.Owin;
    using Owin;
    using Microsoft.Owin.Security.OAuth;
    
    [assembly: OwinStartup(typeof(WebAPIOAuth.Startup))]
    
    namespace WebAPIOAuth
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                var OAuthOptions = new OAuthAuthorizationServerOptions
                {
                    AllowInsecureHttp = true,
                    TokenEndpointPath = new PathString("/token"), //获取 access_token 授权服务请求地址
                    AuthorizeEndpointPath = new PathString("/authorize"), //获取 authorization_code 授权服务请求地址
                    AccessTokenExpireTimeSpan = TimeSpan.FromSeconds(10), //access_token 过期时间
    
                    Provider = new OpenAuthorizationServerProvider(), //access_token 相关授权服务
                };
    
                app.UseOAuthBearerTokens(OAuthOptions); //表示 token_type 使用 bearer 方式 不记名令牌验证
            }
        }
    }

    ConfigureOAuth(IAppBuilder app)方法开启了OAuth服务。简单说一下OAuthAuthorizationServerOptions中各参数的含义:

    AllowInsecureHttp:允许客户端一http协议请求;

    TokenEndpointPath:token请求的地址,即http://localhost:端口号/token;

    AccessTokenExpireTimeSpan :token过期时间;

    Provider :提供具体的认证策略;

    3.继承授权服务OAuthAuthorizationServerProvider类

    重载ValidateClientAuthentication方法验证客户端的正确性

    重载GrantResourceOwnerCredentials方法实现用户名密码的验证,验证通过后会颁发token。

    public class OpenAuthorizationServerProvider : OAuthAuthorizationServerProvider
        {
            /// <summary>
            /// 验证调用端的clientid与clientSecret已验证调用端的合法性(clientid、clientSecret为约定好的字符串)。
            /// </summary>
            /// <param name="context"></param>
            /// <returns></returns>
            public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
            {
                string clientId;
                string clientSecret;
                context.TryGetBasicCredentials(out clientId, out clientSecret);
                if (clientId == "1234" && clientSecret == "5678")
                {
                    context.Validated(clientId);
                }
                await base.ValidateClientAuthentication(context);
            }
    
            /// <summary>
            /// 通过重载GrantResourceOwnerCredentials获取用户名和密码进行认证
            /// </summary>
            /// <param name="context"></param>
            /// <returns></returns>
            public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
            {
                //调用后台的登录服务验证用户名与密码
                if (context.UserName != "Admin" || context.Password != "123456")
                {
                    context.SetError("invalid_grant", "用户名或密码不正确。");
                    return;
                }
                
                var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
                oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
                var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
                context.Validated(ticket);
    
                await base.GrantResourceOwnerCredentials(context);
            }
        }

    在需要验证的方法处添加[Authorize]标签,当访问此接口时必须通过授权验证才可访问。

    以上服务器端代码全部完成。

    4.创建新的客户端项目进行测试

    添加测试类
    class OAuthClientTest
        {
            private HttpClient _httpClient;
            private string token;
            
            public OAuthClientTest()
            {
                _httpClient = new HttpClient();
                _httpClient.BaseAddress = new Uri("http://localhost");
            }
    
            public async Task<string> GetAccessToken()
            {
                var clientId = "1234";
                var clientSecret = "5678";
    
                var parameters = new Dictionary<string, string>();
                parameters.Add("grant_type", "password");
                parameters.Add("username", "Admin");
                parameters.Add("password", "123456");
    
                _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
                    "Basic",
                    Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret))
                    );
    
                var response = await _httpClient.PostAsync("OAuthTest/token", new FormUrlEncodedContent(parameters));
                var responseValue = await response.Content.ReadAsStringAsync();
                if (response.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    return JObject.Parse(responseValue)["access_token"].Value<string>();
                }
                else
                {
                    Console.WriteLine(responseValue);
                    return string.Empty;
                }
            }
    
            public async Task Call_WebAPI_By_Resource_Owner_Password_Credentials_Grant()
            {
                if(string.IsNullOrEmpty(token))
                    token = await GetAccessToken();
                Console.WriteLine(token);
                _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
                Console.WriteLine(await (await _httpClient.GetAsync("OAuthTest/api/Values")).Content.ReadAsStringAsync());
            }
        }
    main方法中调用进行测试:
    static void Main(string[] args)
            {
                var clientTest = new OAuthClientTest();
                var task = clientTest.Call_WebAPI_By_Resource_Owner_Password_Credentials_Grant();
                task.Wait();
                //var token = clientTest.GetAccessToken();
                //var strToken = token.Result;
                //Console.WriteLine(strToken);
                Console.ReadLine();
            }

    结果如下:



    其中长串字符为token,"value1, value2"为访问webapi返回的结果,表明访问成功。

    参考1:http://www.cnblogs.com/xishuai/p/aspnet-webapi-owin-oauth2.html

    参考2:http://www.cnblogs.com/Leo_wl/p/4919783.html

     
  • 相关阅读:
    linux g++编译dxf文件C++解析库dxflib
    linux g++使用总结
    一个使用three.js的网页DXF文件查看器dxf viewer
    node.js教程基础:node.js访问操作系统
    node.js教程基础:node.js全局对象
    node.js教程基础:node.js命令行选项
    node.js教程基础:node.js包管理器
    node.js教程基础:node.js REPL
    node.js教程基础:第一个node.js程序
    node.js教程基础:node.js安装
  • 原文地址:https://www.cnblogs.com/pengdylan/p/6602602.html
Copyright © 2020-2023  润新知