C# RESTful Owin 自托管的Web API使用FORM实现身份验证
2024-07-24
86
前言
RESTful Web API 使用Owin自托管的程序需要对客户端的访问做身份验证,可以使用FORM身份验证加Cookie来实现,缺点是由于使用了Cookie,不支持跨域的操作。
实现过程
定义FormAuthenticationFilterAttribute类
定义一个FormAuthenticationFilterAttribute,该类继承自AuthorizationFilterAttribute,并重写其OnAuthorization,在该方法中添加从请求头中获取有无登录的Cookie,若有则表示登录成功,否则失败,代码如下:
public class FormAuthenticationFilterAttribute : AuthorizationFilterAttribute
{
private const string UnauthorizedMessage = Unauthorized;
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (actionContext.ActionDescriptor.GetCustomAttributesAllowAnonymousAttribute().Count 0)
{
base.OnAuthorization(actionContext);
return;
}
var ctx = actionContext.Request.GetOwinContext();
if (ctx.Request.User != null ctx.Request.User.Identity.IsAuthenticated)
{
base.OnAuthorization(actionContext);
return;
}
var cookies = actionContext.Request.Headers.GetCookies();
if (cookies == null || cookies.Count 1)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized) { Content = new StringContent(UnauthorizedMessage, Encoding.UTF8) };
return;
}
FormsAuthenticationTicket ticket = GetTicket(cookies);
if (ticket == null)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized) { Content = new StringContent(UnauthorizedMessage, Encoding.UTF8) };
return;
}
if (ticket.Expired)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized) { Content = new StringContent(UnauthorizedMessage, Encoding.UTF8) };
return;
}
base.OnAuthorization(actionContext);
}
private FormsAuthenticationTicket GetTicket(CollectionCookieHeaderValue cookies)
{
FormsAuthenticationTicket ticket = null;
foreach (var item in cookies)
{
var cookie = item.Cookies.SingleOrDefault(c = c.Name == FormsAuthentication.FormsCookieName);
if (cookie != null)
{
ticket = FormsAuthentication.Decrypt(cookie.Value);
break;
}
}
return ticket;
}
添加上述授权过滤器
FormAuthenticationFilterAttribute,也可在global文件中将该类添加到全局过滤器中,同时定义一个登录ACTION,用于登录入口,示例代码如下:
[FormAuthenticationFilter]
[EnableCors(origins: *, headers: *, methods: *)]
[RoutePrefix(api/post/auth)]
public class AuthController : ApiController
{
[AllowAnonymous]
[HttpPost]
[Route(login)]
public HttpResponseMessage DoLogin(string token)
{
var context = Request.GetOwinContext();
if (admin.Equals(token, StringComparison.OrdinalIgnoreCase))
{
//创建票据
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, token, DateTime.Now, DateTime.Now.AddMinutes(1), false, string.Empty);
//加密票据
string authTicket = FormsAuthentication.Encrypt(ticket);
//存储为cookie
context.Response.Cookies.Append(FormsAuthentication.FormsCookieName, authTicket,
new CookieOptions(){ Expires = DateTime.Now.Add(TimeSpan.FromMinutes(1))});
return Request.CreateResponse(HttpStatusCode.OK, 登录成功!);
}
else
{
return Request.CreateResponse(HttpStatusCode.Unauthorized, 登录失败!);
}
}
[HttpGet]
[Route(get-status)]
public HttpResponseMessage GetStatus()
{
return Request.CreateResponse(HttpStatusCode.OK, Authentication);
}
}
测试
可直接在浏览器中访问需要授权的方法(即:Login除外),如:http://192.168.1.100:8088/api/post/auth/get-status,响应结果如下:
可见,没有授权时返回了Unauthorized。
使用Postman进行测试,没有授权时,访问api/post/auth/get-status的响应结果如下:
授权,响应结果如下:
授权成功后,再访问api/post/auth/get-status的响应结果如下:
赞一波!2
相关文章
- 使用SuperWebSocket实现Web消息推送
- 用SignalR和Layui搭建自己的web聊天网站
- 【说站】python API接口如何测试
- 【说站】js有哪些常用的数组api
- 【说站】python 如何调用api
- 【说站】java时间日期API的整理
- 【说站】python如何建立web服务
- 【说站】java中有哪些时间API?
- 什么是.NET渐进式Web应用(PWA)
- ASP.NET MVC与Web Forms的区别
- ASP.NET Core实现多语言本地化Web应用程序
- jwt是什么?.NET Core API如何使用JwtBearer验证
- 使用.NET SDK Betalgo调用OpenAI ChatGPT API 代码示例
- enctype='multipart/form-data'在HTML中是什么意思?
- uniapp 中的交互反馈 API【提示框】
- 禁止添加属性、封闭对象、冻结对象的 API
- 获取ip信息的api有哪些?
- 微信商户号 API 密钥、API 证书配置
- Web网页版Windows源码
- WEB版SQL工具推荐
文章评论
评论问答