最近项目中需要对项目同时支持jwt认证,以及自定义的认证校验方式认证。通过对官方文档了解,得到认证实现主要通过继承 iauthenticationhandler 或 authenticationhandler<toptions>来实现自定义认证的处理。
那么接下来实现一个自定义的认证访问。
1、根据前面内容得知,处理认证通过iauthenticationhandler 实例处理;那么首先添加一个自定义iauthenticationhandler 类型:
/// <summary>/// 方式一:自定义认证处理器/// </summary>public class customerauthenticationhandler : iauthenticationhandler{ private iurrvice _urrvice; public customerauthenticationhandler(iurrvice urrvice) { _urrvice = urrvice; } /// <summary> /// 自定义认证scheme名称 /// </summary> public const string customerschemename = "cusauth"; private authenticationscheme _scheme; private httpcontext _context; /// <summary> /// 认证逻辑:认证校验主要逻辑 /// </summary> /// <returns></returns> public task<authenticateresult> authenticateasync() { authenticateresult result; _context.request.headers.trygetvalue("authorization", out stringvalues values); string valstr = values.tostring(); if (!string.isnullorwhitespace(valstr)) { //认证模拟basic认证:cusauth ywrtaw46ywrtaw4= string[] authval = system.text.encoding.utf8.getstring(convert.fromba64string(valstr.substring(customerschemename.length + 1))).split(':'); var logininfo = new dto.logindto() { urname = authval[0], password = authval[1] }; var validvale = _urr160wifivice.isvalid(logininfo); if (!validvale) result = authenticateresult.fail("未登陆"); el { var ticket = getauthticket(logininfo.urname, "admin"); result = authenticateresult.success(ticket); } } el { result = authenticateresult.fail("未登陆"); } return task.fromresult(result); } /// <summary> /// 未登录时的处理 /// </summary> /// <param name="properties"></param> /// <returns></returns> public task challengeasync(authenticationproperties properties) { _context.respon.statuscode = (int)httpstatuscode.unauthorized; return task.completedtask; } /// <summary> /// 权限不足时处理 /// </summary> /// <param name="properties"></param> /// <returns></returns> public task forbidasync(authenticationproperties properties) { _context.respon.statuscode = (int)httpstatuscode.forbidden; return task.completedtask; } /// <summary> /// 初始化认证 /// </summary> /// <param name="scheme"></param> /// <param name="context"></param> /// <returns></returns> public task initializeasync(authenticationscheme scheme, httpcontext context) { _scheme = scheme; _context = context; return task.completedtask; } #region 认证校验逻辑 /// <summary> /// 生成认证票据 /// </summary> /// <param name="name"></param> /// <param name="role"></param> /// <returns></returns> private authenticationticket getauthticket(string name, string role) { var claimsidentity = new claimsidentity(new claim[] { new claim(claimtypes.name, name), new claim(claimtypes.role, role), }, customerschemename); var principal = new claimsprincipal(claimsidentity); return new authenticationticket(principal, _scheme.name); } #endregion}/// <summary>/// 方式二:继承已实现的基类/// </summary>public class subauthenticationhandler : authenticationhandler<authenticationschemeoptions>{ public subauthenticationhandler(ioptionsmonitor<authenticationschemeoptions> options, iloggerfactory logger, urlencoder encoder, isystemclock clock) : ba(options, logger, encoder, clock) { } protected override task<authenticateresult> handleauthenticateasync() { throw new notimplementedexception(); }}
2、在startup.cs中启用自定义认证:
public void configurervices(irvicecollection rvices){ //other code rvices.addauthentication(o => { x.defaultauthorientaldreamenticatescheme = customerauthenticationhandler.customerschemename; x.defaultchallengescheme = customerauthenticationhandler.customerschemename; o.addscheme<customerauthenticationhandler>(customerauthenticationhandler.customerschemename, customerauthenticationhandler.customerschemename); }); //other code}public void configure(iapplicationbuilder app){ //other code app.urouting(); //在urouting后;uendpoints前添加以下代码 app.uauthentication(); app.uauthorization(); //other code app.uendpoints()}
3、在控制器上添加认证标记,测试验证
//指定认证时,采用customerauthenticationhandler.customerschemename[authorize(authenticationschemes = customerauthenticationhandler.customerschemename)][route("api/[controller]")][apicontroller]public class auditlogcontroller : controllerba{//code}
调用
在实际项目中可能存在,对一个控制器支持多种认证方式如:常用的jwt认证、自定义认证等,那么如何实现呢?
1、在startup的configurervices 方法中添加以下逻辑:
public void configurervices(irvicecollection rvices){ //other code rvices.configure<jwttting>(configuration.getction("jwttting")); var token = configuration.getction("jwttting").get<jwttting>(); //jwt认证 rvices.addauthentication(x => { x.defaultauthenticatescheme = jwtbearerdefaults.authenticationscheme; x.defaultchallengescheme = jwtbearerdefaults.authenticationscheme; //添加自定义认证处理器 x.addscheme<customerauthenticationhandler>(customerauthenticationhandler.customerschemename, customerauthenticationhandler.customerschemename); }体育教师面试).addjwtbearer(x => { x.requirehttpsmetadata = fal; x.savetoken = true; x.tokenvalidationparameters = new tokenvalidationparameters { validateissuersigningkey = true, issuersigningkey = new symmetriccuritykey(encoding.ascii.getbytes(token.cretkey)), validissuer = token.issuer, validaudience = token.audience, validateissuer = fal, validateaudience = fal }; }); //other code}
2、在需要支持多种认证方式的控制器上添加标记:
//指定认证时,采用customerauthenticationhandler.customerschemename[authorize(authenticationschemes = customerauthenticationhandler.customerschemename)][route("api/[controller]")][apicontroller]public class auditlogcontroller : controllerba{//code}//指定认证采用jwt[authorize(authenticationschemes = jwtbearerdefaults.authenticationscheme)]public class weatherforecastcontroller : controllerba{ //code}
这样就支持了两种认证方式
3、一个控制器支持多种认证类型:继承jwt认证处理,并根据scheme那么调用自定义的认证处理器:
/// <summary>/// 方式二:同时支持多种认证方式/// </summary>public class multauthenticationhandler : jwtbearerhandler{ public const string multauthname = "multauth"; iurrvice _urrvice; public multauthenticationhandler(ioptionsmonitor<jwtbeareroptions> options, iloggerfactory logger, urlencoder encoder, isystemclock clock, iurrvice urrvice) : ba(options, logger, encoder, clock) { _urrvice = urrvice; } protected override task<authenticateresult> handleauthenticateasync() { context.request.headers.trygetvalue("authorization", out stringvalues values); string valstr = values.tostring(); if (valstr.startswith(customerauthenticationhandler.customerschemename)) { var result = valid(); if (result != null) return task.fromresult(authenticateresult.success(result)); el return task.fromresult(authenticateresult.fail("未认证")); } el return ba.authenticateasync(); } private authenticationticket valid() { context.request.headers.trygetvalue("authorization", out stringvalues values); string valstr = values.tostring(); if (!string.isnullorwhitespace(valstr)) { //认证模拟basic认证:cusauth ywrtaw46ywrtaw4= string[] authval = system.text.encoding.utf8.getstring(convert.fromba64string(valstr.substring(customerauthenticationhandler.customerschemename.length + 1))).split(':'); var logininfo = new dto.logindto() { urname = authval[0], password = authval[1] }; if (_urrvice.isvalid(logininfo)) return getauthticket(logininfo.urname, "admin"); } return null; } /// <summary> /// 生成认证票据 /// </summary> /// <param name="name"></param> /// <param name="role"></param> /// <returns></returns> private authenticationticket getauthticket(string name, string role) { var claimsid实践单位评价entity = new claimsidentity(new claim[] { new claim(claimtypes.name, name), new claim(claimtypes.role, role), }, customerauthenticationhandler.customerschemename); var principal = new claimsprincipal(claimsidentity); return new authenticationticket(principal, customerauthenticationhandler.customerschemename); }}
.net core中的自定义认证主要通过实现iauthenticationhandler 接口实现,如果要实现多认证方式通过addscheme 应用自定义实现的认证处理器。三个代表的意义
源码:github
到此这篇关于.net core中自定义认证实现的文章就介绍到这了,更多相关.net core 自定义认证内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!
本文发布于:2023-04-04 17:56:46,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/2b46b090013d6e419c916b5e4fed852f.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:.Net Core中自定义认证实现.doc
本文 PDF 下载地址:.Net Core中自定义认证实现.pdf
留言与评论(共有 0 条评论) |