【7】.net WebAPI Owin OAuth 2.0 密码模式验证实例 1.OAuth密码模式 2.在VS中创建WebAPI项目 3.继承授权服务OAuthAuthorizationServerProvider类 4.创建新的客户端项目进行测试

【7】.net WebAPI Owin OAuth 2.0 密码模式验证实例
1.OAuth密码模式
2.在VS中创建WebAPI项目
3.继承授权服务OAuthAuthorizationServerProvider类
4.创建新的客户端项目进行测试

【7】.net WebAPI Owin OAuth 2.0 密码模式验证实例
1.OAuth密码模式
2.在VS中创建WebAPI项目
3.继承授权服务OAuthAuthorizationServerProvider类
4.创建新的客户端项目进行测试

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();
        }

结果如下:

【7】.net WebAPI Owin OAuth 2.0 密码模式验证实例
1.OAuth密码模式
2.在VS中创建WebAPI项目
3.继承授权服务OAuthAuthorizationServerProvider类
4.创建新的客户端项目进行测试

其中长串字符为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