gpt4 book ai didi

c# - 如何在 web api 中使用过滤器传递带有错误消息的状态

转载 作者:行者123 更新时间:2023-11-30 22:51:23 25 4
gpt4 key购买 nike

我不知道我遗漏了哪里,如果用户名和密码错误,我将无法发送错误消息。我的服务运行良好,如果用户 ID 和密码与 200 状态不匹配并且手动创建的状态成功,我可以手动发送错误消息。这是我的代码,我创建了 HandleRequest

public class HandleRequest : Attribute, IAuthenticationFilter
{
public string Realm { get; set; }




public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
//throw new NotImplementedException();
HttpRequestMessage request = context.Request;
AuthenticationHeaderValue authorization = request.Headers.Authorization;

string status = await SendAsync(request, cancellationToken);


if (context.Request.RequestUri.LocalPath == "/Login/UserLogin")
{
return;
}
else if (authorization == null)
{
// No authentication was attempted (for this authentication method).
// Do not set either Principal (which would indicate success) or ErrorResult (indicating an error).
context.ErrorResult = new AuthenticationFailureResult("Null auth token..", request);
return;
}
else if (status == "Success")
{
return;
}
else
{
context.ErrorResult = new AuthenticationFailureResult("Invalid auth token..", request);
return;
}
}


public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
Challenge(context);
return Task.FromResult(0);
}

private void Challenge(HttpAuthenticationChallengeContext context)
{
string parameter;

if (String.IsNullOrEmpty(Realm))
{
parameter = null;
}
else
{
// A correct implementation should verify that Realm does not contain a quote character unless properly
// escaped (precededed by a backslash that is not itself escaped).
parameter = "realm=\"" + Realm + "\"";
}

context.ChallengeWith("Basic", parameter);
}

public virtual bool AllowMultiple
{
get { return false; }
}




private static bool TryRetrieveToken(HttpRequestMessage request, out string token)
{
token = null;
IEnumerable<string> authzHeaders;
if (!request.Headers.TryGetValues("Authorization", out authzHeaders) || authzHeaders.Count() > 1)
{
return false;
}
var bearerToken = authzHeaders.ElementAt(0);
token = bearerToken.StartsWith("Bearer ") ? bearerToken.Substring(7) : bearerToken;
return true;
}

public async Task<string> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{

string status = "";
HttpStatusCode statusCode;
string token;
//determine whether a jwt exists or not
if (!TryRetrieveToken(request, out token))
{
statusCode = HttpStatusCode.Unauthorized;
//allow requests with no token - whether a action method needs an authentication can be set with the claimsauthorization attribute
//return base.SendAsync(request, cancellationToken);
}

try
{
string sec = WebConfigurationManager.AppSettings["sec"];
var now = DateTime.UtcNow;
var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));


SecurityToken securityToken;
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
TokenValidationParameters validationParameters = new TokenValidationParameters()
{
ValidAudience = "http://localhost:1987",
ValidIssuer = "http://localhost:1987",
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
LifetimeValidator = this.LifetimeValidator,
IssuerSigningKey = securityKey
};
//extract and assign the user of the jwt
Thread.CurrentPrincipal = handler.ValidateToken(token, validationParameters, out securityToken);
HttpContext.Current.User = handler.ValidateToken(token, validationParameters, out securityToken);


var identity = (ClaimsPrincipal)Thread.CurrentPrincipal;


var id = int.Parse(identity.Claims.Where(c => c.Type == "id")
.Select(c => c.Value).SingleOrDefault());


bool isValidToken = IsValidToken(id, userName, type);
if (isValidToken == true)
{
status = "Success";
}
else
{
statusCode = HttpStatusCode.Unauthorized;
status = "Unauthorized";
}

}
catch (SecurityTokenValidationException e)
{
e.Message.ToString();
statusCode = HttpStatusCode.Unauthorized;
status = "Unauthorized";
}
catch (Exception ex)
{
ex.Message.ToString();
statusCode = HttpStatusCode.InternalServerError;
status = "InternalServerError";
}

return status;
}
public bool LifetimeValidator(DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters)
{
if (expires != null)
{
if (DateTime.UtcNow < expires) return true;
}
return false;
}

private bool IsValidToken(int? id, string userName, string type)
{
bool isValid = false;
using (MCSDEMOEntities con = new MCSDEMOEntities())
{
var GetUserDatails = (from u in con.ios_Users
where u.ID == id && u.LOGIN == userName && u.TYPEDESCR == type
select u).ToList();
if (GetUserDatails.Count == 1)
{
isValid = true;
}
else
{
isValid = false;
}
}

return isValid;
}


}





public static class HttpRequestHeadersExtensions
{
public static void Set(this HttpRequestHeaders headers, string name, string value)
{
if (headers.Contains(name)) headers.Remove(name);
headers.Add(name, value);
}
}

public static class HttpAuthenticationChallengeContextExtensions
{
public static void ChallengeWith(this HttpAuthenticationChallengeContext context, string scheme)
{
ChallengeWith(context, new AuthenticationHeaderValue(scheme));
}

public static void ChallengeWith(this HttpAuthenticationChallengeContext context, string scheme, string parameter)
{
ChallengeWith(context, new AuthenticationHeaderValue(scheme, parameter));
}

public static void ChallengeWith(this HttpAuthenticationChallengeContext context, AuthenticationHeaderValue challenge)
{
if (context == null)
{
throw new ArgumentNullException("context");
}

context.Result = new AddChallengeOnUnauthorizedResult(challenge, context.Result);
}
}


public class AddChallengeOnUnauthorizedResult : IHttpActionResult
{
public AuthenticationHeaderValue Challenge { get; private set; }
public IHttpActionResult InnerHttpResult { get; private set; }

public AddChallengeOnUnauthorizedResult(AuthenticationHeaderValue challenge, IHttpActionResult innerResult)
{
Challenge = challenge;
InnerHttpResult = innerResult;
}

public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
HttpResponseMessage response = await InnerHttpResult.ExecuteAsync(cancellationToken);

if (response.StatusCode == HttpStatusCode.Unauthorized)
{
// Only add one challenge per authentication scheme.
if (!response.Headers.WwwAuthenticate.Any((h) => h.Scheme == Challenge.Scheme))
{
response.Headers.WwwAuthenticate.Add(Challenge);
}
}

return response;
}
}

public class AuthenticationFailureResult : IHttpActionResult
{
public string ReasonPhrase { get; private set; }
public HttpRequestMessage Request { get; private set; }

public AuthenticationFailureResult(string reasonPhrase, HttpRequestMessage request)
{
ReasonPhrase = reasonPhrase;
Request = request;
}

public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
return Task.FromResult(execute());
}

private HttpResponseMessage execute()
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
response.RequestMessage = Request;
response.ReasonPhrase = ReasonPhrase;
return response;
}
}

我的 webapi 配置文件

  public static void Register(HttpConfiguration config)
{
// Web API configuration and services

// Web API routes
config.MapHttpAttributeRoutes();

//check each request
config.Filters.Add(new HandleRequest());

// configuration for json reponse
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));

//LoginController
// Login Model

config.Routes.MapHttpRoute(
name: "LoginApi",
routeTemplate: "{controller}/{action}",
defaults: new { controller = "Login", action = "UserLogin", id = RouteParameter.Optional }
);
}

和我的登录 Controller

  public class LoginController : ApiController
{
LoginModel logMod = new LoginModel();
LoginResponse logResp = new LoginResponse();


[HttpPost]
public LoginResponse UserLogin(LoginRequest logReq)
{
logResp = logMod.UserLogin(logReq );
return logResp;
}
}

登录模型类

        public  LoginResponse UserLogin(LoginRequest LogReq)
{

LoginResponse logResp = new LoginResponse();
try
{
if (LogReq.userName != "" && LogReq.password != "")
{
using (MCSDEMOEntities DataModel = new MCSDEMOEntities())
{
var UserDetails = (from user in DataModel.ios_Users
where (user.LOGIN == LogReq.userName && user.PASSWORD == LogReq.password && user.ACTIVE != 0)
select new
{
user.ID,
user.TYPEDESCR,
user.USERNAME
}).ToList();
if (UserDetails.Count != 0)
{
foreach (var Udetails in UserDetails)
{
logResp.id = Udetails.ID;
logResp.type = Udetails.TYPEDESCR;
logResp.userName = Udetails.USERNAME;
}
//create jwt token.
logResp.userToken = createToken(logResp.id, logResp.type, LogReq.userName);
logResp.Status = "Success";
}
else
{
logResp.Status = "401";
//throw new HttpResponseException("Customer Name cannot be empty", HttpStatusCode.BadRequest);
// throw new AuthenticationFailureResult("","")
}
}
}
else
{
logResp.Status = "No Condition Match";
}

}
catch (Exception ex)
{
logResp.Status = ex.Message.ToString();
}

return logResp;
}

在上面的代码中,它很好地执行了服务,但即使用户 ID 和密码不匹配,它也会发送 http-200 ok 消息和我的状态 - json 中的 401。我想通过代码 401 传递 http

最佳答案

您需要从您的 api 返回 HttpResponseMessage 以便您可以使用其他信息(如状态)包装您的响应对象

    [HttpPost]
public HttpResponseMessage UserLogin(LoginRequest logReq)
{
logResp = logMod.UserLogin(logReq );
// Decide based on your logic. This is
// a mock example.
var status = HttpStatusCode.OK
return Request.CreateResponse(HttpStatusCode.OK, logResp);
}

您可以在此处找到更多信息:https://learn.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/action-results

引用自:

HttpResponseMessage Convert directly to an HTTP response

Other type Write the serialized return value into the response body; return 200 (OK).

关于c# - 如何在 web api 中使用过滤器传递带有错误消息的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59243234/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com