WebAPI - 如何从令牌中获取 UserID
WebAPI - How to get UserID from token
我有 WebApi 应用程序并在 ApplicationOAuthProvider 中将 UserID 添加到令牌 class:
public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
{
context.AdditionalResponseParameters.Add(property.Key, property.Value);
}
context.AdditionalResponseParameters.Add("ID", context.Identity.GetUserId<int>());
return Task.FromResult<object>(null);
}
现在如何在我的控制器方法中获取此 ID?
我尝试以下操作:
[Authorize]
public class ApiEditorialController : ApiController
{
public HttpResponseMessage GetEditorialRequests()
{
int id = HttpContext.Current.User.Identity.GetUserId<int>();
var r = Request.CreateResponse(HttpStatusCode.Accepted);
r.ReasonPhrase = "Cool!";
return r;
}
}
但我在
上收到 NullReferenceException
int id = HttpContext.Current.User.Identity.GetUserId<int>();
字符串....
更新:
查看下面的响应(来自 Francis Ducharme),只需覆盖 OnAuthorization 而不是创建私有构造函数:)
public class AuthorizeApiFilter : AuthorizeAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
string token = string.Empty;
AuthenticationTicket ticket;
token = (actionContext.Request.Headers.Any(x => x.Key == "Authorization")) ? actionContext.Request.Headers.Where(x => x.Key == "Authorization").FirstOrDefault().Value.SingleOrDefault().Replace("Bearer ", "") : "";
if (token == string.Empty)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, "Missing 'Authorization' header. Access denied.");
return;
}
//your OAuth startup class may be called something else...
ticket = Startup.OAuthOptions.AccessTokenFormat.Unprotect(token);
if (ticket == null)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid token decrypted.");
return;
}
// you could perform some logic on the ticket here...
// you will be able to retrieve the ticket in all controllers by querying properties and looking for "Ticket"...
actionContext.Request.Properties.Add(new KeyValuePair<string, object>("Ticket", ticket));
base.OnAuthorization(actionContext);
}
}
谢谢你,弗朗西斯·杜查姆
您需要拦截响应消息并将该值附加回您的用户。
AdditionalResponseParameters 将显示在响应中,但您的应用程序不会将它们分配给任何东西,除非您告诉它。
找到用于向用户分配声明值/名称等的代码(在从 OAuth 提供商重定向回您的站点时),然后在响应中查找参数。
您可以在 OAuth 启动程序 GrantResourceOwnerCredentials
中 class,将其添加到字典中。
ticket.Properties.Dictionary.Add(KeyValuePair<string, string>("UserID", user.Id.ToString())); //the user object from your authentication logic...
然后实现一个 AuthorizeAttribute
,您可以在其中检索在请求的 Authorize
header 中发送的令牌,取消保护并将其添加到请求属性中然后在所有控制器的方法中可用。
public class AuthFilter : AuthorizeAttribute
{
private void AuthorizeRequest(HttpActionContext actionContext)
{
string token = string.Empty;
AuthenticationTicket ticket;
token = (actionContext.Request.Headers.Any(x => x.Key == "Authorization")) ? actionContext.Request.Headers.Where(x => x.Key == "Authorization").FirstOrDefault().Value.SingleOrDefault().Replace("Bearer ", "") : "";
if (token == string.Empty)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, "Missing 'Authorization' header. Access denied.");
return;
}
//your OAuth startup class may be called something else...
ticket = Startup.OAuthBearerOptions.AccessTokenFormat.Unprotect(token);
if (ticket == null)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid token decrypted.");
return;
}
// you could perform some logic on the ticket here...
// you will be able to retrieve the ticket in all controllers by querying properties and looking for "Ticket"...
actionContext.Request.Properties.Add(new KeyValuePair<string, object>("Ticket", ticket));
}
}
然后在您的网络方法中,Request.Properties
将包含 Ticket
,它本身有一个包含 UserID
.
的字典
您需要在WebApiConfig.cs
中注册AuthorizeAttribute
config.Filters.Add(new AuthFilter());
// I also have this in my Web API config. Not sure if I had to add this manually or the default project had these lines already...
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
我有 WebApi 应用程序并在 ApplicationOAuthProvider 中将 UserID 添加到令牌 class:
public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
{
context.AdditionalResponseParameters.Add(property.Key, property.Value);
}
context.AdditionalResponseParameters.Add("ID", context.Identity.GetUserId<int>());
return Task.FromResult<object>(null);
}
现在如何在我的控制器方法中获取此 ID?
我尝试以下操作:
[Authorize]
public class ApiEditorialController : ApiController
{
public HttpResponseMessage GetEditorialRequests()
{
int id = HttpContext.Current.User.Identity.GetUserId<int>();
var r = Request.CreateResponse(HttpStatusCode.Accepted);
r.ReasonPhrase = "Cool!";
return r;
}
}
但我在
上收到 NullReferenceExceptionint id = HttpContext.Current.User.Identity.GetUserId<int>();
字符串....
更新: 查看下面的响应(来自 Francis Ducharme),只需覆盖 OnAuthorization 而不是创建私有构造函数:)
public class AuthorizeApiFilter : AuthorizeAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
string token = string.Empty;
AuthenticationTicket ticket;
token = (actionContext.Request.Headers.Any(x => x.Key == "Authorization")) ? actionContext.Request.Headers.Where(x => x.Key == "Authorization").FirstOrDefault().Value.SingleOrDefault().Replace("Bearer ", "") : "";
if (token == string.Empty)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, "Missing 'Authorization' header. Access denied.");
return;
}
//your OAuth startup class may be called something else...
ticket = Startup.OAuthOptions.AccessTokenFormat.Unprotect(token);
if (ticket == null)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid token decrypted.");
return;
}
// you could perform some logic on the ticket here...
// you will be able to retrieve the ticket in all controllers by querying properties and looking for "Ticket"...
actionContext.Request.Properties.Add(new KeyValuePair<string, object>("Ticket", ticket));
base.OnAuthorization(actionContext);
}
}
谢谢你,弗朗西斯·杜查姆
您需要拦截响应消息并将该值附加回您的用户。
AdditionalResponseParameters 将显示在响应中,但您的应用程序不会将它们分配给任何东西,除非您告诉它。
找到用于向用户分配声明值/名称等的代码(在从 OAuth 提供商重定向回您的站点时),然后在响应中查找参数。
您可以在 OAuth 启动程序 GrantResourceOwnerCredentials
中 class,将其添加到字典中。
ticket.Properties.Dictionary.Add(KeyValuePair<string, string>("UserID", user.Id.ToString())); //the user object from your authentication logic...
然后实现一个 AuthorizeAttribute
,您可以在其中检索在请求的 Authorize
header 中发送的令牌,取消保护并将其添加到请求属性中然后在所有控制器的方法中可用。
public class AuthFilter : AuthorizeAttribute
{
private void AuthorizeRequest(HttpActionContext actionContext)
{
string token = string.Empty;
AuthenticationTicket ticket;
token = (actionContext.Request.Headers.Any(x => x.Key == "Authorization")) ? actionContext.Request.Headers.Where(x => x.Key == "Authorization").FirstOrDefault().Value.SingleOrDefault().Replace("Bearer ", "") : "";
if (token == string.Empty)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, "Missing 'Authorization' header. Access denied.");
return;
}
//your OAuth startup class may be called something else...
ticket = Startup.OAuthBearerOptions.AccessTokenFormat.Unprotect(token);
if (ticket == null)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid token decrypted.");
return;
}
// you could perform some logic on the ticket here...
// you will be able to retrieve the ticket in all controllers by querying properties and looking for "Ticket"...
actionContext.Request.Properties.Add(new KeyValuePair<string, object>("Ticket", ticket));
}
}
然后在您的网络方法中,Request.Properties
将包含 Ticket
,它本身有一个包含 UserID
.
您需要在WebApiConfig.cs
AuthorizeAttribute
config.Filters.Add(new AuthFilter());
// I also have this in my Web API config. Not sure if I had to add this manually or the default project had these lines already...
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));