http://blog.developers.ba/post/2012/03/03/ASPNET-Web-API-Authorization-using-Tokens.aspx
When you try to plan how to build real world REST API like other major players like Facebook or Foursquare have you will soon realize that all major players use OAuth 2.0 .
ASP.NET Web API comes with support for authorize attribute and that’s nice, but for real world API I want to support token based approach.
For supporting token based approach you must have some kind of server that will issue tokens. Building token server can be complex and most major players have implemented OAuth 2.0 server based on draft 10 OAuth documentation.
We hope that Microsoft will provide us with their own OAuth 2.0 server for free in final version of ASP.NET MVC 4.
Meanwhile I will just assume that you already have your own OAuth 2.0 server.
I have solved my problem with authorization by implementing RequireAuthorize ActionFilterAttribute. This attribute also have scope property. Scope property is used for limiting access to your REST API.
You just need to decorate controllers or actions in controllers with this attribute and optionally set required scope for accessing these actions.
Here is RequireAuthorizeAtribute:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
public
class
RequireAuthorization : ActionFilterAttribute
{
public
string
Scope {
get
;
set
; }
public
override
void
OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
string
[] scope =
null
;
if
(!
string
.IsNullOrEmpty(Scope))
{
scope = Scope.Split(
new
[] {
","
}, StringSplitOptions.RemoveEmptyEntries);
}
string
query = actionContext.Request.RequestUri.Query;
string
accessToken = HttpUtility.ParseQueryString(query).Get(
"accessToken"
);
// we first check for valid token
if
(accessToken !=
null
)
{
IAccessTokenValidator accessTokenValidator =
new
AccessTokenValidator();
bool
validToken = accessTokenValidator.ValidateToken(accessToken, scope);
if
(!validToken)
{
var response =
new
HttpResponseMessage
{
Content =
new
StringContent(
"This token is not valid, please refresh token or obtain valid token!"
),
StatusCode = HttpStatusCode.Unauthorized
};
throw
new
HttpResponseException(response);
}
}
else
{
var response =
new
HttpResponseMessage
{
Content =
new
StringContent(
"You must supply valid token to access method!"
),
StatusCode = HttpStatusCode.Unauthorized
};
throw
new
HttpResponseException(response);
}
base
.OnActionExecuting(actionContext);
}
}
|
And here is AccessTokenValidator class:
1
2
3
4
5
6
7
8
9
10
11
12
|
public
class
AccessTokenValidator : IAccessTokenValidator
{
public
bool
ValidateToken(
string
token,
string
[] scope)
{
// replace this logic with dataBase access to table with tokens
if
(token !=
"someToken"
)
{
return
false
;
}
return
true
;
}
}
|