一步步搭建最简单author2.0认证服务

Posted 黄子清

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一步步搭建最简单author2.0认证服务相关的知识,希望对你有一定的参考价值。

oauth2.0 最早接触这个概念是在做微信订阅号开发。当时还被深深的绕进去,关于oauth2.0的解释网上有好多,而且都讲解的比较详细,下面给大家价格参考资料。

http://owin.org/

http://brockallen.com/2013/10/24/a-primer-on-owin-cookie-authentication-middleware-for-the-asp-net-developer/ 

http://www.asp.net/aspnet/overview/owin-and-katana/an-overview-of-project-katana

http://www.asp.net/aspnet/overview/owin-and-katana/owin-middleware-in-the-iis-integrated-pipeline

http://www.asp.net/aspnet/overview/owin-and-katana/owin-startup-class-detection

http://msdn.microsoft.com/en-us/library/ff359101.aspx

 

接下来用最简短的代码实现author认证和授权。我们也可以先实现简单案例,在理解。

这里我以客户端模式为例。

1.ASP.NET MVC 4 Web API 项目或者MVC5

2. 添加引用

Owin.dll

Microsoft.Owin.dll

Microsoft.Owin.Host.SystemWeb.dll

Microsoft.Owin.Security.dll

Microsoft.Owin.Security.Oauth.dll

 

Microsoft.Owin.Security.Cookies.dll

MicrosoftAspNet.Identity.Owin.dll

 

3.修改 App_Start 文件夹下面 Startup.Auth.cs文件,把原来自动生成那些东西全部去掉。

public void ConfigureAuth(Owin.IAppBuilder app){

var OauthOptions = new Microsoft.Owin.Securtity.Oauth.OAuthAuthorizationServerOptions{

AllowInsecureHttp = true,

AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,

//获取 access_token 授权服务请求地址

TokenEndpointPath = new Microsoft.Owin.PathString("/token"),

//获取 authorization_code 授权服务请求地址

AuthorizeEndpointPath = new Microsoft.Owin.PathString("/authorize"),

//access_token 过期时间

AccessTokenExpireTimeSpan = TimeSpan.FromSeconds(990),

//access_token 相关授权服务

Provider = new OpenAuthorizationServerProvider(),

//authorization_code 授权服务

RefreshTokenProvider = new OpenRefreshTokenProvider() //refresh_token 授权服务

};

app.UseOAuthBearerTokens(OAuthOptions);

}

 

修改Startup.cs 文件

 [assembly: OwinStartup(typeof(WebApplication2.Startup))]

 public partial class Startup

{

    public void Configuration(IAppBuilder app)

    {

        ConfigureAuth(app);

        var configuration = new HttpConfiguration();

        WebApiConfig.Register(configuration);

        app.UseWebApi(configuration);

     }

  }

 

上面这个文件的作用 相当于 Global.asax文件,在程序启动是及执行。

 

5. 新建 OpenAuthorizationServerProvider.cs 文件

 

public class OpenAuthorizationServerProvider :Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerProvider

{

    /// <summary>

   /// 验证 client 信息

    /// </summary>

    public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)

    {

        string clientId;

        string clientSecret;

        if (!context.TryGetBasicCredentials(out clientId, out clientSecret))

        {

            context.TryGetFormCredentials(out clientId, out clientSecret);

        }

        //对clientId 和 clientSecret 经行验证

        context.Validated();

   }

 

    /// <summary>

   /// 生成 access_token(client credentials 授权方式)

    /// </summary>

    public override async Task GrantClientCredentials(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);

     }

 

6.新建 OpenRefreshTokenProvider.cs 文件

 

public class OpenRefreshTokenProvider: AuthenticationTokenProvider

{

    private static ConcurrentDictionary<string, string> _refreshTokens = new ConcurrentDictionary<string, string>();

   /// <summary>

  /// 生成 refresh_token

  /// </summary>

public override void Create(AuthenticationTokenCreateContext context)

{

   context.Ticket.Properties.IssuedUtc = DateTime.UtcNow;

   context.Ticket.Properties.ExpiresUtc = DateTime.UtcNow.AddDays(60);

   context.SetToken(Guid.NewGuid().ToString("n") + Guid.NewGuid().ToString("n"));

  _refreshTokens[context.Token] = context.SerializeTicket();

}

 

 /// <summary>

/// 由 refresh_token 解析成 access_token

/// </summary>

public override void Receive(AuthenticationTokenReceiveContext context)

{

   string value;

   if (_refreshTokens.TryRemove(context.Token, out value))

  {

      context.DeserializeTicket(value);

   }

 }

}

 

 

修改ValuesControl.cs

public class ValuesController : ApiController

{

    [Authorize]

    public IEnumerable<string> Get()

    {

        return new string[] { "value1", "value2" };

    }

}

 

到这里整个author2.0 客户端模式 服务就待建好了。发布项目,这里发布地址我们定义:http://192.168.1.147:87。接下来我们搭建测试端。

 

7.新建 “控制台应用程序”。

8.新建 TokenResponse.cs 实体类。

public class TokenResponse

{

   [JsonProperty("access_token")]

   public string AccessToken { get; set; }

   [JsonProperty("refresh_token")]

   public string RefreshToken { get; set; }

   [JsonProperty("token_type")]

   public string TokenType { get; set; }

   [JsonProperty("expires_in")]

   public int expires_in { get; set; }

 }

 

修改 Program.cs

static void Main(string[] args) {

Program p = new Program();

string result = p.Request_WebRequest("http://192.168.1.147:87/token", "ceshi", "123456", 500000);

}

 

public string Request_WebRequest(string uri, string username, string password, int timeout)

{

    string result = string.Empty;

    WebRequest request = WebRequest.Create(new Uri(uri));

    if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))

    {

             request.Credentials = GetCredentialCache(new Uri(uri), username, password);

        request.Headers.Add("Authorization", GetAuthorization(username, password));

    }

 

    if (timeout > 0)

    request.Timeout = timeout;

    request.Method = "POST";

    request.ContentType = "application/x-www-form-urlencoded";

    ASCIIEncoding asciiEncode = new ASCIIEncoding();

    byte[] data = asciiEncode.GetBytes("grant_type=client_credentials");

    request.ContentLength = data.Length;

    Stream newStream = request.GetRequestStream();

    newStream.Write(data, 0, data.Length);

    newStream.Close();

 

    WebResponse response = request.GetResponse();

    Stream stream = response.GetResponseStream();

    StreamReader sr = new StreamReader(stream);

 

    result = sr.ReadToEnd();

 

    TokenResponse tokenRes     =Newtonsoft.Json.JsonConvert.DeserializeObject<TokenResponse>(result);

 

    request = WebRequest.Create(new Uri("http://192.168.1.147:87/api/values"));

    string rha = "Bearer " + tokenRes.AccessToken;

    request.Headers.Add("Authorization",rha);

    request.Method = "Get";

    response = request.GetResponse();

    stream = response.GetResponseStream();

    sr = new StreamReader(stream);

    result = sr.ReadToEnd();

           

    sr.Close();

    stream.Close();

 

    return result;

}

private static CredentialCache GetCredentialCache(Uri uri, string username, string password)

{

    string authorization = string.Format("{0}:{1}", username, password);

    CredentialCache credCache = new CredentialCache();

    credCache.Add(uri, "Basic", new NetworkCredential(username, password));

    return credCache;

}

 

private static string GetAuthorization(string username, string password)

{

    string authorization = string.Format("{0}:{1}", username, password);

    return "Basic " + Convert.ToBase64String(new ASCIIEncoding().GetBytes(authorization));

}

 

运行测试,

得到["value1","value2"]

得到预期结果。

以上是关于一步步搭建最简单author2.0认证服务的主要内容,如果未能解决你的问题,请参考以下文章

零基础带你一步步搭建Nacos高可用集群(史上最详细,赛过教科书!)为此我准备了三台云服务器+云数据库

带你一步步实现最简单的分布式系统日志全链路追踪

用FastDFS一步步搭建文件管理系统

代码篇从零开始一步步搭建自己的golang框架

ASP.NET Core 一步步搭建个人网站_环境搭建

利用SpringCloud搭建一个最简单的微服务框架