Web API在OWIN下實現OAuth
OAuth(Open Authorization)
為用戶資源的授權提供了一個安全的、開放而又簡易的標准。與以往的授權方式不同之處是OAuth的授權不會使第三方觸及到用戶的帳號信息(如用戶名與密碼),即第三方無需使用用戶的用戶名與密碼就可以申請獲得該用戶資源的授權,因此OAuth是安全的。
本節目錄:
1.創建一個控制台項目(其實類庫都可以)ApiServer
Nuget引用:
Install-Package Microsoft.AspNet.WebApi.OwinSelfHost
或者引用以下三個
Install-Package Microsoft.AspNet.WebApi.Owin (讓WebApi作為中間件)
Install-Package Microsoft.Owin.Hosting (Hosting接口默認使用HttpListener作為Server)
Install-Package Microsoft.Owin.Host.HttpListener (默認的Server實現)
2.添加Startup類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
void
Configuration(IAppBuilder app)
{
// 有關如何配置應用程序的詳細信息,請訪問 http://go.microsoft.com/fwlink/?LinkID=316888
ApiConfig(app);
}
private
static
void
ApiConfig(IAppBuilder app)
{
var
config =
new
HttpConfiguration();
config.Routes.MapHttpRoute(
name:
"DefaultApi"
,
routeTemplate:
"api/{controller}/{action}/{id}"
,
defaults:
new
{ id = RouteParameter.Optional , action = RouteParameter.Optional }
);
app.UseWebApi(config);
}
|
如何讓Owin關聯到Startup類的方法,可以看我的博客:
[ASP.NET] 下一代ASP.NET開發規范:OWIN
3.創建一個Api控制器
1
2
3
4
5
6
7
|
public
class
ValuesController : ApiController
{
public
string
Get()
{
return
"Never、C"
;
}
}
|
4.Main方法啟動
1
2
3
4
5
6
7
8
9
|
static
void
Main(
string
[] args)
{
using
(WebApp.Start<Startup>(url))
{
Console.WriteLine(
"開啟成功"
);
Console.ReadLine();
}
}
|
5.瀏覽器訪問
在上面的Owin Web API的基礎上,開始實現OAuth.
Nuget:
Install-Package Microsoft.Owin.Security.OAuth(owin的oauth的實現)
使用OAuth會要求Owin使用UseOAuthBearerTokens認證方式,所以引用
Install-Package Microsoft.AspNet.Identity.Owin
1.在Startup添加一個中間件配置
1
2
3
4
5
6
7
8
9
10
11
|
private
static
void
OAuthConfig(IAppBuilder app)
{
var
OAuthOptions =
new
OAuthAuthorizationServerOptions
{
TokenEndpointPath =
new
PathString(
"/token"
),
Provider =
new
OTWAuthorizationServerProvider(),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp =
true
,
};
app.UseOAuthBearerTokens(OAuthOptions);
}
|
並且設置Web API使用OAuth
1
2
|
config.Filters.Add(
new
HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
//添加的配置
app.UseWebApi(config);
|
2.自定義的provider
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public
class
OTWAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
//1.驗證客戶
public
override
Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{<br>
//此處可以判斷client和user <br>
//this.ClientId = clientId;
//this.IsValidated = true;
//this.HasError = false;
context.Validated(
"自定義的clientId"
);
return
base
.ValidateClientAuthentication(context);
}
//授權客戶
public
override
Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
{
var
ticket =
new
AuthenticationTicket(
new
ClaimsIdentity(
new
[] {
new
Claim(ClaimTypes.Name,
"Never、C"
) }, context.Options.AuthenticationType),
null
);
//this.Ticket = ticket;
//this.IsValidated = true;
//this.HasError = false;
context.Validated(ticket);
return
base
.GrantClientCredentials(context);
}
}
|
3.用客戶端來調用我們的(建議不要用單元測試,此處新建一個控制台項目)
1
2
3
4
5
6
7
|
static
void
Main(
string
[] args)
{
var
client =
new
HttpClient();
var
rst = client.PostAsync(url +
"token"
,
new
StringContent(
"grant_type=client_credentials"
)).Result.Content.ReadAsStringAsync().Result;
Console.WriteLine(rst);
}
|
4.先啟動服務端,再啟動客戶端
1.ValuesController添加特性Authorize
1
2
3
4
5
6
7
8
|
[Authorize]
public
class
ValuesController : ApiController
{
public
string
Get()
{
return
User.Identity.Name;
}
}
|
訪問會返回
{"Response status code does not indicate success: 401 (Unauthorized)."}
2.客戶端引用
Install-Package Newtonsoft.Json -Version 7.0.1
3.修改Main方法,帶上Token
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
class
Program
{
static
void
Main(
string
[] args)
{
var
client =
new
HttpClient();
var
rst = client.PostAsync(url +
"token"
,
new
StringContent(
"grant_type=client_credentials"
)).Result.Content.ReadAsStringAsync().Result;
var
obj = JsonConvert.DeserializeObject<Token>(rst);
client.DefaultRequestHeaders.Authorization =
new
AuthenticationHeaderValue(
"Bearer"
, obj.AccessToken);
rst = client.GetStringAsync(url +
"api/values"
).Result;
Console.WriteLine(rst);
Console.ReadLine();
}
}
public
class
Token
{
[JsonProperty(
"Access_Token"
)]
public
string
AccessToken {
get
;
set
; }
}
|
4.先啟動服務端,再啟動客戶端
擴展
其實OAuth自己也能實現,本質是生成一個加密的唯一的字符串
OAuth的實現方案還有DotNetOpenAuth、Thinktecture IdentityServer
本文地址:http://neverc.cnblogs.com/p/4970996.html
參考:
http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/
http://www.cnblogs.com/dudu/p/4569857.html