当前位置: 首页 > 编程语言 > C#

Firebase3:使用.net和c#创建自定义身份验证令牌分享

时间:2023-04-11 11:38:53 C#

Firebase3:使用.net和c#创建自定义身份验证令牌在https://firebase.google.com/docs/auth/server/create-custom-tokens中描述)。我的服务器是ASP.NETMVC应用程序。因此,按照说明(https://firebase.google.com/docs/server/setup),我为Firebase应用程序创建了一个服务帐户,并生成了一个“.p12”格式的密钥。然后按照此处的说明(https://firebase.google.com/docs/auth/server/create-custom-tokens#create_custom_tokens_using_a_third-party_jwt_library)我尝试生成一个自定义令牌并将其与我之前收到的密钥匹配继续到签名步骤。对于令牌生成,我使用了Microsoft的SystemIdentityModel.Tokens.Jwt库,因此代码如下所示:varnow=DateTime.UtcNow;vartokenHandler=newJwtSecurityTokenHandler();varkey=newX509AsymmetricSecurityKey(newX509Certificate2(p12path,p12pwd));varsigninCredentials=newSigningCredentials(key,"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256","http://www.w3.org/2001/04/xmlenc#rsa-sha256");Int32nowInUnixTimestamp=(Int32)(now.Subtract(newDateTime(1970,1,1))).TotalSeconds;vartoken=tokenHandler.CreateToken(issuer:serviceAccountEmail,audience:"https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",signingCredentials:signinCredentials,subject:newClaimsIdentity(newClaim[]{新Claim("sub",AccountEmail),newClaim("iat",nowInUnixTimestamp.ToString()),newClaim("exp",(nowInUnixTimestamp+(60*60)).ToString()),newClaim("uid",uid)}));vartokenString=tokenHandler.WriteToken(token);然后尝试使用FirebaseJavascriptSDK在ReactNative应用程序中登录用户,使用以下代码://省略初始化代码firebase.auth().signInWithCustomToken(firebaseJWT).catch(function(error){console.log('ErrorauthenticatingFirebaseuser.代码:'+error.code+'消息:'+error.message);});但是Firebase错误显示:验证Firebase用户代码时出错:auth/invalid-custom-token消息:自定义令牌格式不正确。请检查文档。尝试为令牌过期控制添加不同的声明也无济于事。此外,我尝试使用“dvsekhvalnov/jose-jwt”库生成令牌,但无法使用“RS256”算法。所以问题是:对我做错了什么有什么建议吗?这个纯.NET解决方案适用于我,使用Org.BouncyCastle(https://www.nuget.org/packages/BouncyCastle/)和Jose.JWT(https://www.nuget.org/packages/jose-jwt/)图书馆。我遵循了以下步骤:为了在IIS中工作,我需要更改应用程序的池标识并将“加载用户配置文件”设置为true。到目前为止还没有找到您问题的直接答案,所以现在得到以下解决方案:使用此处的说明生成包含服务帐户详细信息的JSON文件,并使用FirebaseServerSDK创建基本的Node.js服务器,使用以下代码为Firebase生成正确的自定义令牌:varhttp=require('http');varhttpdispatcher=require('httpdispatcher');varfirebase=require('firebase');varconfig={serviceAccount:{projectId:"{projectId}",clientEmail:"{projectServiceEmail}",privateKey:"-----BEGINPRIVATEKEY-----...---ENDPRIVATEKEY-----n"},databaseURL:"https://{projectId}.firebaseio.com"};firebase.initializeApp(配置);常数端口=8080;httpdispatcher.onGet("/firebaseCustomToken",function(req,res){varuid=req.params.uid;if(uid){varcustomToken=firebase.auth().createCustomToken(uid);res.writeHead(200,{'Content-Type':'application/json'});res.end(JSON.stringify({'firebaseJWT':customToken}));}else{res.writeHead(400,{'Content-Type':'text/plain'});res.end('没有指定uid参数');}});functionhandleRequest(request,response){try{//记录请求控制台console.log(request.url)上的uest;//调度httpdispatcher.dispatch(request,response);}catch(err){console.log(err);}}//创建服务器varserver=http.createServer(handleRequest);//启动我们的服务器server.listen(PORT,function(){console.log("Serverlisteningon:http://localhost:%s",PORT);});有些人可能认为这非常有用@Elliveny的代码在本地工作,但在azure中抛出错误:“系统找不到指定的文件”。由于我稍微更改了代码,它现在可以在两台服务器上运行。privatestringEncodeToken(stringuid,Dictionaryclaims){stringjwt=string.Empty;RsaPrivateCrtKeyParameters_rsaParams;使用(StreamReadersr=newStreamReader(GenerateStreamFromString(private_key.Replace(@"n","n")))){varpr=newOrg.BouncyCastle.OpenSsl.PemReader(sr);_rsaParams=(RsaPrivateCrtKeyParameters)pr.ReadObject();}使用(RSACryptoServiceProviderrsa=newRSACryptoServiceProvider()){Dictionarypayload=newDictionary{{"claims",claims},{"uid",uid},{"iat",secondsSinceEpoch(DateTime.UtcNow)},{"exp",secondsSinceEpoch(DateTime.UtcNow.AddSeconds(firebaseTokenExpirySecs))},{"aud",firebasePayloadAUD},{"iss",client_email},{"sub",client_email}};RSAParametersrsaParams=DotNetUtilities.ToRSAParameters(_rsaParams);rsa.ImportParameters(rsaParams);jwt=JWT.Encode(payload,rsa,Jose.JwsAlgorithm.RS256);}返回智威汤逊;}@Elliveny的回答对我很有帮助。我在.NETCore2.0应用程序中使用它,并在接受的答案的基础上构建,我将这个解决方案变成了一个类,可以在应用程序服务容器中注册为单例依赖项,配置通过构造函数传递,以便我们可以使用.NET机密进行本地开发配置,使用环境变量进行生产配置。我还整理了一些流处理。.NETCore开发者须知-你需要使用Portable.BouncyCastle你可以通过使用Jwt.IO解析输出的JWT令牌来测试编码结果以上是C#学习教程:Firebase3:Createcustomauthenticationwith.netandc#如果token分享的全部内容对你很有用,需要多了解C#学习教程,希望大家多多关注——usingJose;使用Org.BouncyCastle.Crypto.Parameters;使用系统;使用System.Collections.Generic;使用System.IO;使用System.Linq;publicclassFirebaseTokenGenerator{//来自服务帐户JSON文件的private_keypublicstaticstringfirebasePrivateKey;//每个人都一样publicstaticstringfirebasePayloadAUD="https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit";//来自服务帐户JSON文件的client_emailpublicstaticstringfirebasePayloadISS;公共静态字符串firebasePayloadSUB;//令牌'exp'-最多3600秒-请参阅https://firebase.google.com/docs/auth/server/create-custom-tokenspublicstaticintfirebaseTokenExpirySecs=3600;私有静态RsaPrivateCrtKeyParameters_rsaParams;公关ivate静态对象_rsaParamsLocker=newobject();publicFirebaseTokenGenerator(stringprivateKey,stringclientEmail){firebasePrivateKey=privateKey??抛出新的ArgumentNullException(nameof(privateKey));firebasePayloadISS=clientEmail??抛出新的ArgumentNullException(nameof(clientEmail));firebasePayloadSUB=clientEmail;}publicstaticstringEncodeToken(stringuid){returnEncodeToken(uid,null);}publicstaticstringEncodeToken(stringuid,Dictionaryclaims){//如果我们还没有确定RsaPrivateCrtKeyParametersif(_rsaParams==null){lock(_rsaParamsLocker){if(_rsaParams==null){using(varstreamWriter=WriteToStreamWithString(firebasePrivateKey.Replace(@"n","n"))){使用(varsr=newStreamReader(streamWriter.BaseStream)){varpr=newOrg.BouncyCastle.OpenSsl.PemReader(sr);_rsaParams=(RsaPrivateCrtKeyParameters)pr.ReadObject();}}}}}varpayload=newDictionary{{"uid",uid},{"i在”,SecondsSinceEpoch(DateTime.UtcNow)},{“exp”,SecondsSinceEpoch(DateTime.UtcNow.AddSeconds(firebaseTokenExpirySecs))},{“aud”,firebasePayloadAUD},{“iss”,firebasePayloadISS},{“sub”,firebasePayloadSUB}};如果(claims!=null&&claims.Any()){payload.Add("claims",claims);}returnJWT.Encode(payload,Org.BouncyCastle.Security.DotNetUtilities.ToRSA(_rsaParams),JwsAlgorithm.RS256);}privatestaticlongSecondsSinceEpoch(DateTimedt){TimeSpant=dt-newDateTime(1970,1,1);return(long)t.TotalSeconds;}privatestaticStreamWriterWriteToStreamWithString(strings){内存流st=newMemoryStream();StreamWriterwriter=newStreamWriter(stream);writer.Write(s);writer.Flush();stream.Position=0;returnwriter;侵权请点击右侧联系管理员删除如需转载请注明出处: