c# - 刷新令牌为空,AllowOfflineAccess 为真,范围我有 offline_access
问题描述
刷新令牌始终为空,这是我的代码:
new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
RequireConsent = false,
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
AllowAccessTokensViaBrowser = true,
ClientSecrets = {new Secret("secret".Sha256())},
RedirectUris = { "http://localhost:7002/Account/callback" }, //{ "http://localhost:7002/signin-oidc" }, //
PostLogoutRedirectUris = { "http://localhost:7002/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.OfflineAccess,
"api1"
},
AllowOfflineAccess = true,
AlwaysIncludeUserClaimsInIdToken = true
}
这是我的 MVCClient
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "http://localhost:7000";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.ClientSecret = "secret";
options.ResponseType = "code id_token token";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("api1");
options.Scope.Add("offline_access");
});
我通过创建授权 url 登录,这就是我创建它的方式:
var host = _context.HttpContext.Request.Host.Host;
var discoveryClient = new DiscoveryClient(Configuration["auth:oidc:authority"]);
var disco = await discoveryClient.GetAsync();
var request = new RequestUrl(disco.AuthorizeEndpoint);
authorizeUrl = request.CreateAuthorizeUrl(
clientId: "mvc",
responseType: "code id_token token",
responseMode: OidcConstants.ResponseModes.FormPost,
scope: "openid profile api1 offline_access",
redirectUri: "http://localhost:7002/Account/callback", //"http://localhost:7002/signin-oidc", //
state: CryptoRandom.CreateUniqueId(),
nonce: CryptoRandom.CreateUniqueId(),
acrValues: host);
return Redirect(authorizeUrl);
我被重定向到登录页面,我进行了登录,一旦我登录,并返回到 CallBack()(在 HomeController 中),我得到了除了一个空的 refresh_token 之外的所有内容:
public async Task<IActionResult> Callback()
{
var code = Request.Form["code"];
var tokenType = Request.Form["token_type"];
var idToken = Request.Form["id_token"];
var scope = Request.Form["scope"];
var state = Request.Form["state"];
var session_state = Request.Form["session_state"];
var error = Request.Form["error"];
var expiresAt = Request.Form["expires_in"];
var accessToken = Request.Form["access_token"];
var refreshToken = Request.Form["refresh_token"];
}
回顾一下:refresh_token 是空的 {},而不是 null。为了以其他方式测试它,我在 about 方法中添加了 [authorize],如果我只通过单击那里登录,那么我确实有一个 refresh_token。
我错过了什么吗?
解决方案
您只能通过令牌端点调用获取刷新令牌。您需要/connect/token
使用code
您在回调中返回的调用。
此外,由于您是手动执行请求和回调,因此调用AddOpenIdConnect
.
推荐阅读
- python - 使用过滤器使数字更易于阅读
- google-apps-script - 如何更改 Google Sheets [Google App Script] 中多个工作表的单元格值?
- docker - 将主机目录挂载到容器
- r - 在模块化闪亮应用程序中对齐 ggplots
- laravel - 在 laravel 中向用户生成随机令牌
- android - 如何在 Android Studio 中设置开关或切换按钮的内容描述?
- flutter - Flutter PageView 不断在 setState 值上重建主小部件
- reactjs - 如何在 reactjs 中将状态传递给 LinearStepper?
- c++ - 按名称从 z3::context 中提取 z3::expr
- java - 如何使用 FirebaseRecyclerAdapter 在 5 或 10 CardView 后在 RecyclarView 中添加 AdMob 横幅广告