1. 程式人生 > >一步步搭建最簡單author2.0認證服務

一步步搭建最簡單author2.0認證服務

web api ref pen pass 比較 mar prim uri part

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認證服務