我正在开发一个简单的 API 来处理 Firebase 进行的身份验证 - 稍后用于 Android 客户端。
因此,在 Firebase 控制台中,我启用了 Facebook 和 Google 登录方法并创建了一个示例 html 页面,我可以用它来测试登录方法 - 下一个函数由按钮调用:
function loginFacebook() {
var provider = new firebase.auth.FacebookAuthProvider();
var token = "";
firebase.auth().signInWithPopup(provider).then(function (result) {
var token = result.credential.accessToken;
var user = result.user;
alert("login OK");
user.getToken().then(function (t) {
token = t;
loginAPI();
});
}).catch(function (error) {
var errorCode = error.code;
var errorMessage = error.message;
alert(errorCode + " - " + errorMessage);
});
}
接下来,我使用 token 并通过 jQuery 的简单 ajax 调用将其发送到我的 API:
function loginAPI()
{
$.ajax({
url: "http://localhost:58041/v1/Users/",
dataType: 'json',
type: 'GET',
beforeSend: function (xhr) {
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Authorization", "Bearer " + token);
},
error: function (ex) {
console.log(ex.status + " - " + ex.statusText);
},
success: function (data) {
console.log(data);
return data;
}
});
}
下一站:API 后端 - 使用 .NET Core 编写。
在 Startup 下,我配置了 JwtBearer Auth(包 Microsoft.AspNetCore.Authentication.JwtBearer
):
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
IncludeErrorDetails = true,
Authority = "https://securetoken.google.com/PROJECT-ID",
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "https://securetoken.google.com/PROJECT-ID",
ValidateAudience = true,
ValidAudience = "PROJECT-ID",
ValidateLifetime = true,
},
});
这里是 Controller 代码 - 带有 [Authorize]
属性:
[Authorize]
[Route("v1/[controller]")]
public class UsersController : Controller
{
private readonly ILogger _logger;
private readonly UserService _userService;
public UsersController(ILogger<UsersController> logger, UserService userService)
{
_logger = logger;
_userService = userService;
}
[HttpGet]
public async Task<IList<User>> Get()
{
return await _userService.GetAll();
}
}
API 响应为 200 OK(HttpContext.User.Identity.IsAuthenticated
在 Controller 中为 true
),但我认为不应该。我的问题是我不完全确定这是安全的。
这是如何检查 JWT token 的签名部分的?我看到很多代码示例提到了 x509 或 RS256 算法,它们在哪里适合这个?不应该使用 TokenValidationParameters
类中的 IssuerSigningKey
或 TokenDecryptionKey
检查某种证书或私钥吗?我缺少什么?
关于该问题的相关知识来源:
最佳答案
Firebase 使用 RSA256 非对称 key 密码系统,这意味着它有公钥和私钥。 签署 token 使用私钥,而验证 token 使用公钥。
下图说明了 token 签名是如何发生的。
在登录和访问安全端点期间,涉及以下步骤。
- 当我们的应用程序启动时(之后还会定期启动)
JwtBearerMiddleware
调用https://securetoken.google.com/my-firebase-project/.well-known/openid -configuration
,它可以在其中访问 Google 当前的公钥。 重要的是,当我们使用公钥非对称密码系统时,公钥不会保密,而是公开发布。 - 客户使用他们的凭据通过 Firebase 登录(这些是客户自己的凭据,它们与用于签署 token 的 key 无关)。
- 如果登录成功,Firebase 会为客户端构建一个 JWT token 。此 token 的一个关键部分是它是使用 key 对的私钥签名的。与公钥不同,私钥永远不会公开,它作为 secret 保存在 Google 的基础架构中。
- 客户端收到 JWT token 。
- 客户端调用我们的 Api 上的安全端点,并将 token 放入
Authorization
header 中。 此时,管道中的JwtBearerMiddleware
会检查此 token ,并验证它是否有效(如果它是使用 Google 的私钥签名的)。这里要意识到的重要一点是,为了进行验证,我们的 Api 不需要访问私钥。只需要公钥即可。验证后,中间件相应地填充HttpContext.User
和HttpContext.User.Identity.IsAuthenticated
。
您可以在 RSA Wikipedia page 上找到关于这个概念的更简单的描述。 ,以及有关 Firebase + ASP.NET 的更多信息,请参见 my blog post .
关于c# - 使用 .NET Core 的 Firebase 身份验证 (JWT),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42336950/