AspNetCore3.1_Secutiry源码解析_7_Authentication_其他
程序员文章站
2022-04-14 16:11:42
title: "AspNetCore3" date: 2020 03 26T13:23:27+08:00 draft: false 系列文章目录 "AspNetCore3.1_Secutiry源码解析_1_目录" "AspNetCore3.1_Secutiry源码解析_2_Authenticatio ......
title: "aspnetcore3"
date: 2020-03-26t13:23:27+08:00
draft: false
系列文章目录
- aspnetcore3.1_secutiry源码解析_1_目录
- aspnetcore3.1_secutiry源码解析_2_authentication_核心流程
- aspnetcore3.1_secutiry源码解析_3_authentication_cookies
- aspnetcore3.1_secutiry源码解析_4_authentication_jwtbear
- aspnetcore3.1_secutiry源码解析_5_authentication_oauth
- aspnetcore3.1_secutiry源码解析_6_authentication_openidconnect
- aspnetcore3.1_secutiry源码解析_7_authentication_其他
- aspnetcore3.1_secutiry源码解析_8_authorization_核心项目
- aspnetcore3.1_secutiry源码解析_9_authorization_policy
简介
secutiry的认证目录还有这些项目,基本都是具体的oauth2.0服务商或者其他用的比较少的认证架构,简单看一下,了解一下。
- microsoft.aspnetcore.authentication.certificate
- microsoft.aspnetcore.authentication.facebook
- microsoft.aspnetcore.authentication.google
- microsoft.aspnetcore.authentication.microsoftaccount
- microsoft.aspnetcore.authentication.negotiate
- microsoft.aspnetcore.authentication.twitter
- microsoft.aspnetcore.authentication.wsfederation
oauth2.0服务商
facebook, google,microsoftaccount这几个都可以归为一类,都是oauth2.0的服务商。国内用的比较多的是qq,weixin。我们看一下facebook的代码,其他的原理都是大同小异的,根据不同厂商的差异稍作调整就可以了。
twitter似乎是用的oauth1.0协议。
依赖注入
配置类: facebookoptions,处理器类:facebookhandler
public static class facebookauthenticationoptionsextensions { public static authenticationbuilder addfacebook(this authenticationbuilder builder) => builder.addfacebook(facebookdefaults.authenticationscheme, _ => { }); public static authenticationbuilder addfacebook(this authenticationbuilder builder, action<facebookoptions> configureoptions) => builder.addfacebook(facebookdefaults.authenticationscheme, configureoptions); public static authenticationbuilder addfacebook(this authenticationbuilder builder, string authenticationscheme, action<facebookoptions> configureoptions) => builder.addfacebook(authenticationscheme, facebookdefaults.displayname, configureoptions); public static authenticationbuilder addfacebook(this authenticationbuilder builder, string authenticationscheme, string displayname, action<facebookoptions> configureoptions) => builder.addoauth<facebookoptions, facebookhandler>(authenticationscheme, displayname, configureoptions); }
配置类 - facebookoptions
配置类继承自oauthoptions,构造函数根据facebook做了一些定制处理,如claim的映射等。
/// <summary> /// configuration options for <see cref="facebookhandler"/>. /// </summary> public class facebookoptions : oauthoptions { /// <summary> /// initializes a new <see cref="facebookoptions"/>. /// </summary> public facebookoptions() { callbackpath = new pathstring("/signin-facebook"); sendappsecretproof = true; authorizationendpoint = facebookdefaults.authorizationendpoint; tokenendpoint = facebookdefaults.tokenendpoint; userinformationendpoint = facebookdefaults.userinformationendpoint; scope.add("email"); fields.add("name"); fields.add("email"); fields.add("first_name"); fields.add("last_name"); claimactions.mapjsonkey(claimtypes.nameidentifier, "id"); claimactions.mapjsonsubkey("urn:facebook:age_range_min", "age_range", "min"); claimactions.mapjsonsubkey("urn:facebook:age_range_max", "age_range", "max"); claimactions.mapjsonkey(claimtypes.dateofbirth, "birthday"); claimactions.mapjsonkey(claimtypes.email, "email"); claimactions.mapjsonkey(claimtypes.name, "name"); claimactions.mapjsonkey(claimtypes.givenname, "first_name"); claimactions.mapjsonkey("urn:facebook:middle_name", "middle_name"); claimactions.mapjsonkey(claimtypes.surname, "last_name"); claimactions.mapjsonkey(claimtypes.gender, "gender"); claimactions.mapjsonkey("urn:facebook:link", "link"); claimactions.mapjsonsubkey("urn:facebook:location", "location", "name"); claimactions.mapjsonkey(claimtypes.locality, "locale"); claimactions.mapjsonkey("urn:facebook:timezone", "timezone"); } /// <summary> /// check that the options are valid. should throw an exception if things are not ok. /// </summary> public override void validate() { if (string.isnullorempty(appid)) { throw new argumentexception(string.format(cultureinfo.currentculture, resources.exception_optionmustbeprovided, nameof(appid)), nameof(appid)); } if (string.isnullorempty(appsecret)) { throw new argumentexception(string.format(cultureinfo.currentculture, resources.exception_optionmustbeprovided, nameof(appsecret)), nameof(appsecret)); } base.validate(); } // facebook uses a non-standard term for this field. /// <summary> /// gets or sets the facebook-assigned appid. /// </summary> public string appid { get { return clientid; } set { clientid = value; } } // facebook uses a non-standard term for this field. /// <summary> /// gets or sets the facebook-assigned app secret. /// </summary> public string appsecret { get { return clientsecret; } set { clientsecret = value; } } /// <summary> /// gets or sets if the appsecret_proof should be generated and sent with facebook api calls. /// this is enabled by default. /// </summary> public bool sendappsecretproof { get; set; } /// <summary> /// the list of fields to retrieve from the userinformationendpoint. /// https://developers.facebook.com/docs/graph-api/reference/user /// </summary> public icollection<string> fields { get; } = new hashset<string>(); }
处理器类
重写了oauthhanlder的创建凭据方法,其他的都是使用的父类实现。
public class facebookhandler : oauthhandler<facebookoptions> { public facebookhandler(ioptionsmonitor<facebookoptions> options, iloggerfactory logger, urlencoder encoder, isystemclock clock) : base(options, logger, encoder, clock) { } protected override async task<authenticationticket> createticketasync(claimsidentity identity, authenticationproperties properties, oauthtokenresponse tokens) { var endpoint = queryhelpers.addquerystring(options.userinformationendpoint, "access_token", tokens.accesstoken); if (options.sendappsecretproof) { endpoint = queryhelpers.addquerystring(endpoint, "appsecret_proof", generateappsecretproof(tokens.accesstoken)); } if (options.fields.count > 0) { endpoint = queryhelpers.addquerystring(endpoint, "fields", string.join(",", options.fields)); } var response = await backchannel.getasync(endpoint, context.requestaborted); if (!response.issuccessstatuscode) { throw new httprequestexception($"an error occurred when retrieving facebook user information ({response.statuscode}). please check if the authentication information is correct and the corresponding facebook graph api is enabled."); } using (var payload = jsondocument.parse(await response.content.readasstringasync())) { var context = new oauthcreatingticketcontext(new claimsprincipal(identity), properties, context, scheme, options, backchannel, tokens, payload.rootelement); context.runclaimactions(); await events.creatingticket(context); return new authenticationticket(context.principal, context.properties, scheme.name); } } private string generateappsecretproof(string accesstoken) { using (var algorithm = new hmacsha256(encoding.ascii.getbytes(options.appsecret))) { var hash = algorithm.computehash(encoding.ascii.getbytes(accesstoken)); var builder = new stringbuilder(); for (int i = 0; i < hash.length; i++) { builder.append(hash[i].tostring("x2", cultureinfo.invariantculture)); } return builder.tostring(); } } protected override string formatscope(ienumerable<string> scopes) { // facebook deviates from the oauth spec here. they require comma separated instead of space separated. // https://developers.facebook.com/docs/reference/dialogs/oauth // http://tools.ietf.org/html/rfc6749#section-3.3 return string.join(",", scopes); } protected override string formatscope() => base.formatscope(); }
microsoft.aspnetcore.authentication.certificate
这个项目是3.1新加的,是做证书校验的,具体的不细说了,不太懂,有兴趣的看巨硬文档
microsoft.aspnetcore.authentication.negotiate
这个也是新增的项目,是做windows校验的,文档如下
microsoft.aspnetcore.authentication.wsfederation
windows的azure active directory认证
推荐阅读
-
AspNetCore3.1_Secutiry源码解析_7_Authentication_其他
-
AspNetCore3.1_Secutiry源码解析_8_Authorization_授权框架
-
AspNetCore3.1_Secutiry源码解析_6_Authentication_OpenIdConnect
-
AspNetCore3.1_Secutiry源码解析_5_Authentication_OAuth
-
AspNetCore3.1_Secutiry源码解析_6_Authentication_OpenIdConnect
-
AspNetCore3.1_Secutiry源码解析_7_Authentication_其他
-
AspNetCore3.1_Secutiry源码解析_8_Authorization_授权框架
-
AspNetCore3.1_Secutiry源码解析_5_Authentication_OAuth