是否可以将 AuthorizeAttribute 与外部 api 调用一起使用?
Is it possible use AuthorizeAttribute with a external api call?
我正在使用 asp mvc 5,我必须安排一些任务,所以我想创建一个简单的方法来从一个简单的控制台程序 C# 中调用并使用 [=33 安排它们=] 任务计划程序。
我的想法是,我正在使用具有 Authorize
属性的身份来管理用户权限。
比如我有下一个方法:
[Authorize(Roles="Admin")]
public async Task<JsonResult> CriticalTask(string someParam)
{
//procesing data
return null;
}
认为,是:
我不知道如何登录才能通过 Authorize(Roles="Admin")
的验证
我尝试在它之前创建一个简单的登录方法,但这不起作用
我正在尝试这样的
const string URL = "http://localhost:53665/";
RestClient mClient = new RestClient(URL);
const string parameterUserName = "userName";
const string parameterPassword = "password";
const string ruta = "Usuarios/ApiLogin";
var request = new RestRequest(ruta);
request.AddParameter(parameterUserName, "userName");
request.AddParameter(parameterPassword, "password");
//Method to login
var result2 = mClient.Execute(request);
Console.WriteLine($"Login\n{result2.Content}");
//Method that needs Admin permissions
request = new RestRequest("Usuarios/Test");
var result3 = mClient.Execute(request);
Console.WriteLine($"Test\n{result3.Content}");
只有授权属性才有可能吗?或者我需要实现一些令牌方法来授权此调用?
谢谢!
最简单的解决方案是使用 BasicAuth - 您在 headers 中为每个请求传递凭据,并且每个请求都单独验证 - 从示例设置中搜索 MVC Basic auth。我是最简单的形式 - 但也非常不安全,因为您在每次调用中几乎以纯文本形式传递您的凭据(它只是您凭据的 base64)
我建议您使用 Identity Server 4 来使用不记名令牌授权您的客户端。
这种方式在第一次调用之前从服务器请求令牌,然后将其传递给后续请求并使用它来授权您的 api 调用。
请参阅以下有关设置的教程。
http://docs.identityserver.io/en/aspnetcore1/quickstarts/6_aspnet_identity.html
在接下来的 url 中,您可以看到内存用户的示例,但也可以看到令牌 requests.it 的简单但已过时
https://neelbhatt.com/2018/03/04/step-by-step-setup-for-the-auth-server-and-the-client-identityserver4-with-net-core-part-ii/
您还可以使用以下某种代码以不太过时的方式获取令牌:
using (var httpClient = new HttpClient()) {
var discovery = await _httpClient.GetDiscoveryDocumentAsync(_configuration["ApiBaseAddress"]);
if (discovery.IsError)
{
return false;
}
request.Address = discovery.TokenEndpoint;
request.ClientId = _configuration["AuthClientName"];
request.ClientSecret = _configuration["AuthClientSecret"];
var request = new PasswordTokenRequest
{
UserName = "yourUserName",
Password = "yourPassword"
};
var token = await _httpClient.RequestPasswordTokenAsync(request);
}
在 token.AccessToken
中,您有访问令牌 - 需要发送给呼叫 api 的令牌。您在 token.RefreshToken
中也有您的刷新令牌 - 稍后会有用
然后发送呼叫只需将不记名令牌添加到您的 HttpRequestMessage 即可完成
var _httpClient = new HttpClient();
//Configure your http client here
var req= new HttpRequestMessage("http request method", "request uri");
req.SetBearerToken("your access token goes here);
var result = await _httpClient.SendAsync(req);
请记住,在您收到拒绝的权限后,刷新令牌比获取另一个令牌更好(您不需要发送您的凭据)。您使用我之前提到的刷新令牌。
刷新令牌的代码与login/password获取令牌的代码非常相似。只需使用以下 class:
而不是 PasswordTokenRequest
class
var request = new RefreshTokenRequest
{
RefreshToken = _refreshToken
};
而 httpClient.RequestPasswordTokenAsync(request)
使用 httpClient.RequestRefreshTokenAsync(request)
。其余代码可能保持相似。
你应该做的是登录后保存收到的令牌,然后将令牌添加到需要授权的请求头中:
var result = mClient.Execute(request);
string resultContent = result.Content.ReadAsStringAsync().Result;
//This token will be used for authorization
var token = JsonConvert.DeserializeObject<TokenModel>(resultContent);
var request = new RestRequest("Usuarios/Test"); //add token to header of request
mClient.AddDefaultHeader("Authorization", string.Format("bearer {0}", token.Access_Token));
var result3 = mClient.Execute(request);
代币模型:
public class TokenModel
{
...
public string Access_Token { get; set; }
...
}
我最终创建了一个基于 reply posted by crrlos in Whosebug in Spanish 的自定义属性。
我会尽我所能翻译它,以便它可以为他人服务
What you can do is create a custom authorization attribute, for that
you create a class that inherits AuthorizeAttribute
and override the
AuthorizeCore
method. The modification consists in passing to the
route an additional parameter to indicate that it is calling from the
task scheduler, if the parameter is not found then it will perform the
normal validation, if the parameter is found (it must have a value or
if it will not be null ) Then take the credentials of the url and
perform the validation, if they are correct return a true allowing
access to the method.
public class CustomAuthorization : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
//get special parameter indicating that the request was made from the task scheduler
var parametro = httpContext.Request.QueryString.Get("parametro_especial");
if(parametro != null)
{
// get access credentials and validate them
// if they are valid, return true
}
//if they are not valid, or aren't present
//try with deffault validate.
return base.AuthorizeCore(httpContext);
}
}
How to use it?
[CustomAuthorization (Roles = "Admin")]
public JsonResult CargarTodosLosArticulos()
{
return null;
}
我正在使用 asp mvc 5,我必须安排一些任务,所以我想创建一个简单的方法来从一个简单的控制台程序 C# 中调用并使用 [=33 安排它们=] 任务计划程序。
我的想法是,我正在使用具有 Authorize
属性的身份来管理用户权限。
比如我有下一个方法:
[Authorize(Roles="Admin")]
public async Task<JsonResult> CriticalTask(string someParam)
{
//procesing data
return null;
}
认为,是:
我不知道如何登录才能通过 Authorize(Roles="Admin")
我尝试在它之前创建一个简单的登录方法,但这不起作用
我正在尝试这样的
const string URL = "http://localhost:53665/";
RestClient mClient = new RestClient(URL);
const string parameterUserName = "userName";
const string parameterPassword = "password";
const string ruta = "Usuarios/ApiLogin";
var request = new RestRequest(ruta);
request.AddParameter(parameterUserName, "userName");
request.AddParameter(parameterPassword, "password");
//Method to login
var result2 = mClient.Execute(request);
Console.WriteLine($"Login\n{result2.Content}");
//Method that needs Admin permissions
request = new RestRequest("Usuarios/Test");
var result3 = mClient.Execute(request);
Console.WriteLine($"Test\n{result3.Content}");
只有授权属性才有可能吗?或者我需要实现一些令牌方法来授权此调用?
谢谢!
最简单的解决方案是使用 BasicAuth - 您在 headers 中为每个请求传递凭据,并且每个请求都单独验证 - 从示例设置中搜索 MVC Basic auth。我是最简单的形式 - 但也非常不安全,因为您在每次调用中几乎以纯文本形式传递您的凭据(它只是您凭据的 base64)
我建议您使用 Identity Server 4 来使用不记名令牌授权您的客户端。
这种方式在第一次调用之前从服务器请求令牌,然后将其传递给后续请求并使用它来授权您的 api 调用。
请参阅以下有关设置的教程。 http://docs.identityserver.io/en/aspnetcore1/quickstarts/6_aspnet_identity.html
在接下来的 url 中,您可以看到内存用户的示例,但也可以看到令牌 requests.it 的简单但已过时 https://neelbhatt.com/2018/03/04/step-by-step-setup-for-the-auth-server-and-the-client-identityserver4-with-net-core-part-ii/
您还可以使用以下某种代码以不太过时的方式获取令牌:
using (var httpClient = new HttpClient()) {
var discovery = await _httpClient.GetDiscoveryDocumentAsync(_configuration["ApiBaseAddress"]);
if (discovery.IsError)
{
return false;
}
request.Address = discovery.TokenEndpoint;
request.ClientId = _configuration["AuthClientName"];
request.ClientSecret = _configuration["AuthClientSecret"];
var request = new PasswordTokenRequest
{
UserName = "yourUserName",
Password = "yourPassword"
};
var token = await _httpClient.RequestPasswordTokenAsync(request);
}
在 token.AccessToken
中,您有访问令牌 - 需要发送给呼叫 api 的令牌。您在 token.RefreshToken
中也有您的刷新令牌 - 稍后会有用
然后发送呼叫只需将不记名令牌添加到您的 HttpRequestMessage 即可完成
var _httpClient = new HttpClient();
//Configure your http client here
var req= new HttpRequestMessage("http request method", "request uri");
req.SetBearerToken("your access token goes here);
var result = await _httpClient.SendAsync(req);
请记住,在您收到拒绝的权限后,刷新令牌比获取另一个令牌更好(您不需要发送您的凭据)。您使用我之前提到的刷新令牌。
刷新令牌的代码与login/password获取令牌的代码非常相似。只需使用以下 class:
而不是PasswordTokenRequest
class
var request = new RefreshTokenRequest
{
RefreshToken = _refreshToken
};
而 httpClient.RequestPasswordTokenAsync(request)
使用 httpClient.RequestRefreshTokenAsync(request)
。其余代码可能保持相似。
你应该做的是登录后保存收到的令牌,然后将令牌添加到需要授权的请求头中:
var result = mClient.Execute(request);
string resultContent = result.Content.ReadAsStringAsync().Result;
//This token will be used for authorization
var token = JsonConvert.DeserializeObject<TokenModel>(resultContent);
var request = new RestRequest("Usuarios/Test"); //add token to header of request
mClient.AddDefaultHeader("Authorization", string.Format("bearer {0}", token.Access_Token));
var result3 = mClient.Execute(request);
代币模型:
public class TokenModel
{
...
public string Access_Token { get; set; }
...
}
我最终创建了一个基于 reply posted by crrlos in Whosebug in Spanish 的自定义属性。
我会尽我所能翻译它,以便它可以为他人服务
What you can do is create a custom authorization attribute, for that you create a class that inherits
AuthorizeAttribute
and override theAuthorizeCore
method. The modification consists in passing to the route an additional parameter to indicate that it is calling from the task scheduler, if the parameter is not found then it will perform the normal validation, if the parameter is found (it must have a value or if it will not be null ) Then take the credentials of the url and perform the validation, if they are correct return a true allowing access to the method.public class CustomAuthorization : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContextBase httpContext) { //get special parameter indicating that the request was made from the task scheduler var parametro = httpContext.Request.QueryString.Get("parametro_especial"); if(parametro != null) { // get access credentials and validate them // if they are valid, return true } //if they are not valid, or aren't present //try with deffault validate. return base.AuthorizeCore(httpContext); } }
How to use it?
[CustomAuthorization (Roles = "Admin")] public JsonResult CargarTodosLosArticulos() { return null; }