我正在使用ASP MVC 5,我必须安排一些任务,因此我想创建一个简单的方法,以从简单的控制台程序C#调用并与Windows一起安排它们任务调度程序。
思考是,我正在使用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($"Loginn{result2.Content}");
//Method that needs Admin permissions
request = new RestRequest("Usuarios/Test");
var result3 = mClient.Execute(request);
Console.WriteLine($"Testn{result3.Content}");
只有授权属性才有可能?或者我需要实施一些令牌方法来授权此调用?
谢谢!
您应该做的是在登录后保存收到的令牌,然后将令牌添加到请求标题中,需要授权:
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; }
...
}
最简单的解决方案是使用BasicAuth-您在每个请求中通过凭据传递凭据,并且每个请求都会单独验证 - 搜索MVC Basic Auth FR示例设置。我是最简单的形式 - 但是,当您以几乎纯文本中的每个呼叫中传递凭据时,也很不安全(这只是您的凭据的基本64(
我建议您使用Identity Server 4使用Bearer令牌授权您的客户端。
首先致电您从服务器请求令牌,然后将其传递给以下请求,然后使用此请求授权您的API呼叫。
请参阅以下有关设置的教程。http://docs.nistityserver.io/en/aspnetcore1/quickstarts/6_aspnet_identity.html
在下面的URL中,您可以在内存用户中看到示例,但也可以使请求。https://neelbhatt.com/2018/03/04/step-by-step-setup-for-the-the-auth-server-and-server-and-the-client-indistityserver4-with-net-net-core-part-ii/part-P>
您还可以使用某种以下代码以较少过时的方式获得令牌:
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);
请记住,在您获得许可后,刷新象征性最好比获得另一个(您不需要发送凭据(。您使用我之前提到的刷新令牌。
刷新令牌的代码与通过登录/密码获取令牌非常相似。只是使用PasswordTokenRequest
类使用以下类:
var request = new RefreshTokenRequest
{
RefreshToken = _refreshToken
};
,而httpClient.RequestPasswordTokenAsync(request)
使用httpClient.RequestRefreshTokenAsync(request)
。代码的其余部分可能保持相似。
我最终创建了一个自定义属性,基于Crrlos在Stackoverflow中发布的西班牙语中发布的答复。
我会尽力翻译它,以便它可以为他人服务
您可以做的是创建一个自定义授权属性,为此 您创建一个继承
AuthorizeAttribute
并覆盖的类AuthorizeCore
方法。修改包括传递给 路由一个附加参数,以指示它是从 任务调度程序,如果找不到参数,则将执行 正常验证,如果找到参数(必须具有值或 如果不会为null(,请拿出URL的凭据 执行验证,如果它们是正确的返回的,则允许 访问该方法。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); } }
如何使用它?
[CustomAuthorization (Roles = "Admin")] public JsonResult CargarTodosLosArticulos() { return null; }