Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在服务器端处理新的刷新令牌?_C#_Model View Controller_Identityserver4 - Fatal编程技术网

C# 如何在服务器端处理新的刷新令牌?

C# 如何在服务器端处理新的刷新令牌?,c#,model-view-controller,identityserver4,C#,Model View Controller,Identityserver4,我有两个项目。一个是处理用户和身份验证的身份服务器4。第二个需要使用第一个登录并请求令牌来访问API。 当我需要刷新令牌时,我现在不知道如何处理新的访问令牌。如何将新令牌设置为身份验证asp.net核心。所有刷新过程都是在AuthorizationHandler上进行的 我试图修改关于身份的声明,但不起作用。我试图将访问令牌和刷新令牌存储在我自己的cookie中,但我遇到了问题,因为当我刷新令牌时,我只能在下一个请求中使用它们(我没有实现修改请求。cookies仅修改response.cooki

我有两个项目。一个是处理用户和身份验证的身份服务器4。第二个需要使用第一个登录并请求令牌来访问API。 当我需要刷新令牌时,我现在不知道如何处理新的访问令牌。如何将新令牌设置为身份验证asp.net核心。所有刷新过程都是在AuthorizationHandler上进行的

我试图修改关于身份的声明,但不起作用。我试图将访问令牌和刷新令牌存储在我自己的cookie中,但我遇到了问题,因为当我刷新令牌时,我只能在下一个请求中使用它们(我没有实现修改请求。cookies仅修改response.cookies)

public static async Task SetToken(TokenKind token,string value, HttpContext context)
{
    context.Response.Cookies.Append(GetTokenCookieName(token), value);
}


public static async Task<string> GetRefreshTokenAsync(HttpContext context)
{
    return await SearchToken(TokenKind.Refresh,context);
}


private static async Task<string> SearchToken(TokenKind token, HttpContext context)
{
    var tokenName = GetTokenName(token);
    var test = context.Request.Cookies;
    var apiToken = context.Request.Cookies.FirstOrDefault(x => x.Key == GetTokenCookieName(token)).Value;
    if (apiToken == null)
    {
        // Save token into cookie
        var tokenValue  = await context.GetTokenAsync(GetTokenName(TokenKind.Access));
        await SetToken(TokenKind.Access, tokenValue, context);

        var refreshTokenValue = await context.GetTokenAsync(GetTokenName(TokenKind.Refresh));
        await SetToken(TokenKind.Refresh, refreshTokenValue, context);

        switch (token)
        {
            case TokenKind.Access:
                return tokenValue;
            case TokenKind.Refresh:
                return refreshTokenValue;
            default:
                return null;
                break;
        }
    }
    else
    {
        return apiToken;
    }
}


private async Task<bool> RefreshToken(AuthorizationFilterContext mvcContext, HttpClient client)
{
    var refreshToken = await TokenUtils.GetRefreshTokenAsync(mvcContext.HttpContext);
    //await mvcContext.HttpContext.GetTokenAsync("refresh_token");

    var variables = new Dictionary<string, string>
            {
                { "grant_type", "refresh_token" },
                { "client_id", _configuration["ApplicationOptions:ClientId"] },
                { "client_secret", _configuration["ApplicationOptions:ClientSecret"] },
                { "refresh_token", refreshToken }
            };
    var content = new FormUrlEncodedContent(variables);

    var url = _configuration["ApplicationOptions:AuthorizeServer"] + "/connect/token";
    var response = await client.PostAsync(url, content);

    if (response.IsSuccessStatusCode == false)
    {
        var errorString = await response.Content.ReadAsStringAsync();
        var errorData = JsonConvert.DeserializeObject<dynamic>(errorString);
        return false;
    }

    var contentAsString = await response.Content.ReadAsStringAsync();
    var responseData = JsonConvert.DeserializeObject<dynamic>(contentAsString);
    var newAccessToken = (string)responseData.access_token;
    var newRefreshToken = (string)responseData.refresh_token;

    await TokenUtils.SetAccessToken(newAccessToken, mvcContext.HttpContext);
    await TokenUtils.SetRefreshToken(newRefreshToken, mvcContext.HttpContext);

    var result = await mvcContext.HttpContext.AuthenticateAsync();
    if (result.Succeeded)
    {
        result.Properties.StoreTokens(new List<AuthenticationToken>
                {
                    new AuthenticationToken
                    {
                        Name = OpenIdConnectParameterNames.AccessToken,
                        Value = newAccessToken
                    },
                    new AuthenticationToken
                    {
                        Name = OpenIdConnectParameterNames.RefreshToken,
                        Value = newRefreshToken
                    }
                });
        return true;
    }
    else
    {
        return false;
    }
}
公共静态异步任务SetToken(TokenKind标记、字符串值、HttpContext上下文)
{
context.Response.Cookies.Append(GetTokenCookieName(token),value);
}
公共静态异步任务GetRefreshTokenAsync(HttpContext上下文)
{
return wait-SearchToken(TokenKind.Refresh,context);
}
专用静态异步任务SearchToken(TokenKind token,HttpContext上下文)
{
var tokenName=GetTokenName(令牌);
var test=context.Request.Cookies;
var apiToken=context.Request.Cookies.FirstOrDefault(x=>x.Key==GetTokenCookieName(token)).Value;
if(apiToken==null)
{
//将令牌保存到cookie中
var tokenValue=await context.GetTokenAsync(GetTokenName(TokenKind.Access));
等待SetToken(TokenKind.Access、tokenValue、context);
var refreshtTokenValue=wait context.GetTokenAsync(GetTokenName(TokenKind.Refresh));
等待SetToken(TokenKind.Refresh、refreshTokenValue、context);
交换机(令牌)
{
案例类型。访问:
返回令牌值;
案例类型。刷新:
返回值;
违约:
返回null;
打破
}
}
其他的
{
返回令牌;
}
}
专用异步任务刷新令牌(AuthorizationFilterContext mvcContext,HttpClient客户端)
{
var refreshToken=await-TokenUtils.getrefreshttokenasync(mvcContext.HttpContext);
//等待mvcContext.HttpContext.GetTokenAsync(“刷新令牌”);
var变量=新字典
{
{“授权类型”,“刷新令牌”},
{“client_id”,_配置[“ApplicationOptions:ClientId”]},
{“client_secret”,_配置[“ApplicationOptions:ClientSecret”]},
{“刷新令牌”,刷新令牌}
};
var内容=新的FormUrlEncodedContent(变量);
var url=_配置[“应用程序选项:授权服务器”]+“/connect/token”;
var response=wait client.PostAsync(url、内容);
if(response.issusccessstatuscode==false)
{
var errorString=await response.Content.ReadAsStringAsync();
var errorData=JsonConvert.DeserializeObject(errorString);
返回false;
}
var contentAsString=await response.Content.ReadAsStringAsync();
var responseData=JsonConvert.DeserializeObject(contentAsString);
var newAccessToken=(字符串)responseData.access\u令牌;
var newRefreshToken=(字符串)responseData.refresh\u标记;
wait TokenUtils.SetAccessToken(newAccessToken,mvcContext.HttpContext);
wait TokenUtils.SetRefreshToken(newRefreshToken,mvcContext.HttpContext);
var result=await mvcContext.HttpContext.AuthenticateAsync();
if(result.successed)
{
result.Properties.StoreTokens(新列表
{
新身份验证令牌
{
Name=OpenIdConnectParameterNames.AccessToken,
值=newAccessToken
},
新身份验证令牌
{
Name=OpenIdConnectParameterNames.RefreshToken,
Value=newRefreshToken
}
});
返回true;
}
其他的
{
返回false;
}
}

我想知道存储(或替换实际访问令牌)的好方法是什么使用.net core身份验证。我确信我没有用正确的方法进行验证。最后,我希望正确处理我的令牌和我的刷新令牌,以避免要求用户再次登录。现在,使用我的解决方案,我的项目在需要刷新令牌时将拒绝访问,并将授予下一个请求(因为cookie需要从用户处重新发送)。

感谢Ruard van Elburg,我找到了解决方案(以下是解决方案) 这就是我用来替换代币的东西:

// Save the information in the cookie
var info = await mvcContext.HttpContext.AuthenticateAsync("Cookies");

info.Properties.UpdateTokenValue("refresh_token", newRefreshToken);
info.Properties.UpdateTokenValue("access_token", newAccessToken);
info.Properties.UpdateTokenValue("expires_at", expiresAt.ToString("o", CultureInfo.InvariantCulture));

await mvcContext.HttpContext.SignInAsync("Cookies", info.Principal, info.Properties);

这里的问题和我的答案可能会帮助你:非常感谢。它很好!你是对的。我会这样做!请不要在问题中插入你的答案-这就是答案部分的目的。很抱歉,当我必须发布正确答案时,我不知道如何处理。谢谢你的编辑。