C# OWIN ASP.NET-如果访问令牌过期,则无法使用刷新令牌生成访问令牌

C# OWIN ASP.NET-如果访问令牌过期,则无法使用刷新令牌生成访问令牌,c#,asp.net,asp.net-web-api,oauth,owin,C#,Asp.net,Asp.net Web Api,Oauth,Owin,当我试图在访问令牌到期之前使用刷新令牌生成访问令牌时,系统会生成一个新令牌,一切正常。但是如果访问令牌过期,请求将返回无效的授权 GrantRefreshToken中的Validated()方法不是使用我从以前的访问令牌存储在字典中的标识生成访问令牌吗 如果最后一个刷新令牌尚未过期,如何阻止客户端使用相同的刷新令牌请求新的访问令牌 这是我的密码: Startup.cs: public partial class Startup { public void Configuration(IA

当我试图在访问令牌到期之前使用刷新令牌生成访问令牌时,系统会生成一个新令牌,一切正常。但是如果访问令牌过期,请求将返回无效的授权

GrantRefreshToken
中的
Validated()
方法不是使用我从以前的访问令牌存储在字典中的标识生成访问令牌吗

如果最后一个刷新令牌尚未过期,如何阻止客户端使用相同的刷新令牌请求新的访问令牌

这是我的密码:

Startup.cs:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,

            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(5),

            Provider = new OAuthProvider(),
            RefreshTokenProvider = new RefreshTokenProvider()
        });
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        app.UseWebApi(config);
    }
}
public class OAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        if (context.UserName == "admin" && context.Password == "123456")
        {
            var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, "Admin"));

            var ticket = new AuthenticationTicket(claimsIdentity, null);
            context.Validated(ticket);
        }
        return Task.FromResult<object>(null);
    }

    public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
    {
        context.Validated(context.Ticket);
        return Task.FromResult<object>(null);
    }
}
public class RefreshTokenProvider : AuthenticationTokenProvider
{
    private static ConcurrentDictionary<string, AuthenticationTicket> _refreshTokens = new ConcurrentDictionary<string, AuthenticationTicket>();

    public override Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        var guid = Guid.NewGuid().ToString();
        _refreshTokens.TryAdd(guid, context.Ticket);

        context.SetToken(guid);
        return Task.FromResult<object>(null);
    }

    public override Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {
        if (_refreshTokens.TryRemove(context.Token, out AuthenticationTicket ticket))
        {
            context.SetTicket(ticket);
        }
        return Task.FromResult<object>(null);
    }
}
public class OAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        try
        {
            var account = AccountRepository.Instance.GetByUsername(context.UserName);
            if (account != null && Global.VerifyHash(context.Password, account.Password))
            {
                var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
                claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, account.Username));
                claimsIdentity.AddClaim(new Claim("DriverId", account.DriverId.ToString()));

                var newTicket = new AuthenticationTicket(claimsIdentity, null);
                context.Validated(newTicket);
            }
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }
}
public class RefreshTokenProvider : AuthenticationTokenProvider
{
    public override Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        var refreshToken = new TokenModel()
        {
            Subject = context.Ticket.Identity.Name,
            Token = GenerateToken(),
            IssuedUtc = DateTime.UtcNow,
            ExpiresUtc = DateTime.UtcNow.AddMinutes(5)
        };

        context.Ticket.Properties.IssuedUtc = refreshToken.IssuedUtc;
        context.Ticket.Properties.ExpiresUtc = refreshToken.ExpiresUtc;

        refreshToken.Ticket = context.SerializeTicket();

        try
        {
            TokenRepository.Instance.Insert(refreshToken);
            context.SetToken(refreshToken.Token);
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    public override Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {
        try
        {
            var refreshToken = TokenRepository.Instance.Get(context.Token);
            if (refreshToken != null)
            {
                if (TokenRepository.Instance.Delete(refreshToken))
                {
                    context.DeserializeTicket(refreshToken.Ticket);
                }
            }
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    private string GenerateToken()
    {
        HashAlgorithm hashAlgorithm = new SHA256CryptoServiceProvider();

        byte[] byteValue = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString("N"));
        byte[] byteHash = hashAlgorithm.ComputeHash(byteValue);

        return Convert.ToBase64String(byteHash);
    }
}
OAuthProvider.cs:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,

            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(5),

            Provider = new OAuthProvider(),
            RefreshTokenProvider = new RefreshTokenProvider()
        });
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        app.UseWebApi(config);
    }
}
public class OAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        if (context.UserName == "admin" && context.Password == "123456")
        {
            var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, "Admin"));

            var ticket = new AuthenticationTicket(claimsIdentity, null);
            context.Validated(ticket);
        }
        return Task.FromResult<object>(null);
    }

    public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
    {
        context.Validated(context.Ticket);
        return Task.FromResult<object>(null);
    }
}
public class RefreshTokenProvider : AuthenticationTokenProvider
{
    private static ConcurrentDictionary<string, AuthenticationTicket> _refreshTokens = new ConcurrentDictionary<string, AuthenticationTicket>();

    public override Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        var guid = Guid.NewGuid().ToString();
        _refreshTokens.TryAdd(guid, context.Ticket);

        context.SetToken(guid);
        return Task.FromResult<object>(null);
    }

    public override Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {
        if (_refreshTokens.TryRemove(context.Token, out AuthenticationTicket ticket))
        {
            context.SetTicket(ticket);
        }
        return Task.FromResult<object>(null);
    }
}
public class OAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        try
        {
            var account = AccountRepository.Instance.GetByUsername(context.UserName);
            if (account != null && Global.VerifyHash(context.Password, account.Password))
            {
                var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
                claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, account.Username));
                claimsIdentity.AddClaim(new Claim("DriverId", account.DriverId.ToString()));

                var newTicket = new AuthenticationTicket(claimsIdentity, null);
                context.Validated(newTicket);
            }
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }
}
public class RefreshTokenProvider : AuthenticationTokenProvider
{
    public override Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        var refreshToken = new TokenModel()
        {
            Subject = context.Ticket.Identity.Name,
            Token = GenerateToken(),
            IssuedUtc = DateTime.UtcNow,
            ExpiresUtc = DateTime.UtcNow.AddMinutes(5)
        };

        context.Ticket.Properties.IssuedUtc = refreshToken.IssuedUtc;
        context.Ticket.Properties.ExpiresUtc = refreshToken.ExpiresUtc;

        refreshToken.Ticket = context.SerializeTicket();

        try
        {
            TokenRepository.Instance.Insert(refreshToken);
            context.SetToken(refreshToken.Token);
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    public override Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {
        try
        {
            var refreshToken = TokenRepository.Instance.Get(context.Token);
            if (refreshToken != null)
            {
                if (TokenRepository.Instance.Delete(refreshToken))
                {
                    context.DeserializeTicket(refreshToken.Ticket);
                }
            }
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    private string GenerateToken()
    {
        HashAlgorithm hashAlgorithm = new SHA256CryptoServiceProvider();

        byte[] byteValue = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString("N"));
        byte[] byteHash = hashAlgorithm.ComputeHash(byteValue);

        return Convert.ToBase64String(byteHash);
    }
}
公共类OAuthProvider:OAuthAuthorizationServerProvider
{
公共覆盖任务ValidateClientAuthentication(OAuthValidateClientAuthenticationContext)
{
context.Validated();
返回Task.FromResult(空);
}
公共覆盖任务GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentials上下文)
{
if(context.UserName==“admin”&&context.Password==“123456”)
{
var claimsIdentity=新的claimsIdentity(context.Options.AuthenticationType);
AddClaim(新声明(ClaimTypes.Name,context.UserName));
claimsIdentity.AddClaim(新的Claim(ClaimTypes.Role,“Admin”);
var ticket=新的身份验证ticket(claimsIdentity,null);
上下文。已验证(票证);
}
返回Task.FromResult(空);
}
公共覆盖任务GrantRefreshToken(OAuthGrantRefreshTokenContext)
{
context.Validated(context.Ticket);
返回Task.FromResult(空);
}
}
RefreshTokenProvider.cs:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,

            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(5),

            Provider = new OAuthProvider(),
            RefreshTokenProvider = new RefreshTokenProvider()
        });
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        app.UseWebApi(config);
    }
}
public class OAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        if (context.UserName == "admin" && context.Password == "123456")
        {
            var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, "Admin"));

            var ticket = new AuthenticationTicket(claimsIdentity, null);
            context.Validated(ticket);
        }
        return Task.FromResult<object>(null);
    }

    public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
    {
        context.Validated(context.Ticket);
        return Task.FromResult<object>(null);
    }
}
public class RefreshTokenProvider : AuthenticationTokenProvider
{
    private static ConcurrentDictionary<string, AuthenticationTicket> _refreshTokens = new ConcurrentDictionary<string, AuthenticationTicket>();

    public override Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        var guid = Guid.NewGuid().ToString();
        _refreshTokens.TryAdd(guid, context.Ticket);

        context.SetToken(guid);
        return Task.FromResult<object>(null);
    }

    public override Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {
        if (_refreshTokens.TryRemove(context.Token, out AuthenticationTicket ticket))
        {
            context.SetTicket(ticket);
        }
        return Task.FromResult<object>(null);
    }
}
public class OAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        try
        {
            var account = AccountRepository.Instance.GetByUsername(context.UserName);
            if (account != null && Global.VerifyHash(context.Password, account.Password))
            {
                var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
                claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, account.Username));
                claimsIdentity.AddClaim(new Claim("DriverId", account.DriverId.ToString()));

                var newTicket = new AuthenticationTicket(claimsIdentity, null);
                context.Validated(newTicket);
            }
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }
}
public class RefreshTokenProvider : AuthenticationTokenProvider
{
    public override Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        var refreshToken = new TokenModel()
        {
            Subject = context.Ticket.Identity.Name,
            Token = GenerateToken(),
            IssuedUtc = DateTime.UtcNow,
            ExpiresUtc = DateTime.UtcNow.AddMinutes(5)
        };

        context.Ticket.Properties.IssuedUtc = refreshToken.IssuedUtc;
        context.Ticket.Properties.ExpiresUtc = refreshToken.ExpiresUtc;

        refreshToken.Ticket = context.SerializeTicket();

        try
        {
            TokenRepository.Instance.Insert(refreshToken);
            context.SetToken(refreshToken.Token);
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    public override Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {
        try
        {
            var refreshToken = TokenRepository.Instance.Get(context.Token);
            if (refreshToken != null)
            {
                if (TokenRepository.Instance.Delete(refreshToken))
                {
                    context.DeserializeTicket(refreshToken.Ticket);
                }
            }
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    private string GenerateToken()
    {
        HashAlgorithm hashAlgorithm = new SHA256CryptoServiceProvider();

        byte[] byteValue = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString("N"));
        byte[] byteHash = hashAlgorithm.ComputeHash(byteValue);

        return Convert.ToBase64String(byteHash);
    }
}
公共类RefreshTokenProvider:AuthenticationTokenProvider
{
私有静态ConcurrentDictionary_refreshTokens=新ConcurrentDictionary();
公共重写任务CreateAncy(AuthenticationTokenCreateContext上下文)
{
var guid=guid.NewGuid().ToString();
_refreshTokens.TryAdd(guid,context.Ticket);
SetToken(guid);
返回Task.FromResult(空);
}
公共覆盖任务ReceiveAsync(AuthenticationTokenReceiveContext上下文)
{
if(_refreshtokes.TryRemove(context.Token,out AuthenticationTicket))
{
上下文。设置票证(票证);
}
返回Task.FromResult(空);
}
}
对不起,英语不好,希望你能理解

编辑:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,

            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(5),

            Provider = new OAuthProvider(),
            RefreshTokenProvider = new RefreshTokenProvider()
        });
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        app.UseWebApi(config);
    }
}
public class OAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        if (context.UserName == "admin" && context.Password == "123456")
        {
            var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, "Admin"));

            var ticket = new AuthenticationTicket(claimsIdentity, null);
            context.Validated(ticket);
        }
        return Task.FromResult<object>(null);
    }

    public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
    {
        context.Validated(context.Ticket);
        return Task.FromResult<object>(null);
    }
}
public class RefreshTokenProvider : AuthenticationTokenProvider
{
    private static ConcurrentDictionary<string, AuthenticationTicket> _refreshTokens = new ConcurrentDictionary<string, AuthenticationTicket>();

    public override Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        var guid = Guid.NewGuid().ToString();
        _refreshTokens.TryAdd(guid, context.Ticket);

        context.SetToken(guid);
        return Task.FromResult<object>(null);
    }

    public override Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {
        if (_refreshTokens.TryRemove(context.Token, out AuthenticationTicket ticket))
        {
            context.SetTicket(ticket);
        }
        return Task.FromResult<object>(null);
    }
}
public class OAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        try
        {
            var account = AccountRepository.Instance.GetByUsername(context.UserName);
            if (account != null && Global.VerifyHash(context.Password, account.Password))
            {
                var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
                claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, account.Username));
                claimsIdentity.AddClaim(new Claim("DriverId", account.DriverId.ToString()));

                var newTicket = new AuthenticationTicket(claimsIdentity, null);
                context.Validated(newTicket);
            }
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }
}
public class RefreshTokenProvider : AuthenticationTokenProvider
{
    public override Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        var refreshToken = new TokenModel()
        {
            Subject = context.Ticket.Identity.Name,
            Token = GenerateToken(),
            IssuedUtc = DateTime.UtcNow,
            ExpiresUtc = DateTime.UtcNow.AddMinutes(5)
        };

        context.Ticket.Properties.IssuedUtc = refreshToken.IssuedUtc;
        context.Ticket.Properties.ExpiresUtc = refreshToken.ExpiresUtc;

        refreshToken.Ticket = context.SerializeTicket();

        try
        {
            TokenRepository.Instance.Insert(refreshToken);
            context.SetToken(refreshToken.Token);
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    public override Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {
        try
        {
            var refreshToken = TokenRepository.Instance.Get(context.Token);
            if (refreshToken != null)
            {
                if (TokenRepository.Instance.Delete(refreshToken))
                {
                    context.DeserializeTicket(refreshToken.Ticket);
                }
            }
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    private string GenerateToken()
    {
        HashAlgorithm hashAlgorithm = new SHA256CryptoServiceProvider();

        byte[] byteValue = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString("N"));
        byte[] byteHash = hashAlgorithm.ComputeHash(byteValue);

        return Convert.ToBase64String(byteHash);
    }
}
我修改了代码以实现数据库支持,并将刷新令牌过期时间设置为5分钟。出于测试目的,过期时间很短

结果如下:

OAuthProvider.cs:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,

            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(5),

            Provider = new OAuthProvider(),
            RefreshTokenProvider = new RefreshTokenProvider()
        });
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        app.UseWebApi(config);
    }
}
public class OAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        if (context.UserName == "admin" && context.Password == "123456")
        {
            var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, "Admin"));

            var ticket = new AuthenticationTicket(claimsIdentity, null);
            context.Validated(ticket);
        }
        return Task.FromResult<object>(null);
    }

    public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
    {
        context.Validated(context.Ticket);
        return Task.FromResult<object>(null);
    }
}
public class RefreshTokenProvider : AuthenticationTokenProvider
{
    private static ConcurrentDictionary<string, AuthenticationTicket> _refreshTokens = new ConcurrentDictionary<string, AuthenticationTicket>();

    public override Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        var guid = Guid.NewGuid().ToString();
        _refreshTokens.TryAdd(guid, context.Ticket);

        context.SetToken(guid);
        return Task.FromResult<object>(null);
    }

    public override Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {
        if (_refreshTokens.TryRemove(context.Token, out AuthenticationTicket ticket))
        {
            context.SetTicket(ticket);
        }
        return Task.FromResult<object>(null);
    }
}
public class OAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        try
        {
            var account = AccountRepository.Instance.GetByUsername(context.UserName);
            if (account != null && Global.VerifyHash(context.Password, account.Password))
            {
                var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
                claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, account.Username));
                claimsIdentity.AddClaim(new Claim("DriverId", account.DriverId.ToString()));

                var newTicket = new AuthenticationTicket(claimsIdentity, null);
                context.Validated(newTicket);
            }
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }
}
public class RefreshTokenProvider : AuthenticationTokenProvider
{
    public override Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        var refreshToken = new TokenModel()
        {
            Subject = context.Ticket.Identity.Name,
            Token = GenerateToken(),
            IssuedUtc = DateTime.UtcNow,
            ExpiresUtc = DateTime.UtcNow.AddMinutes(5)
        };

        context.Ticket.Properties.IssuedUtc = refreshToken.IssuedUtc;
        context.Ticket.Properties.ExpiresUtc = refreshToken.ExpiresUtc;

        refreshToken.Ticket = context.SerializeTicket();

        try
        {
            TokenRepository.Instance.Insert(refreshToken);
            context.SetToken(refreshToken.Token);
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    public override Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {
        try
        {
            var refreshToken = TokenRepository.Instance.Get(context.Token);
            if (refreshToken != null)
            {
                if (TokenRepository.Instance.Delete(refreshToken))
                {
                    context.DeserializeTicket(refreshToken.Ticket);
                }
            }
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    private string GenerateToken()
    {
        HashAlgorithm hashAlgorithm = new SHA256CryptoServiceProvider();

        byte[] byteValue = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString("N"));
        byte[] byteHash = hashAlgorithm.ComputeHash(byteValue);

        return Convert.ToBase64String(byteHash);
    }
}
公共类OAuthProvider:OAuthAuthorizationServerProvider
{
公共覆盖任务ValidateClientAuthentication(OAuthValidateClientAuthenticationContext)
{
context.Validated();
返回Task.FromResult(空);
}
公共覆盖任务GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentials上下文)
{
尝试
{
var account=AccountRepository.Instance.GetByUsername(context.UserName);
if(account!=null&&Global.VerifyHash(context.Password,account.Password))
{
var claimsIdentity=新的claimsIdentity(context.Options.AuthenticationType);
AddClaim(新的索赔(ClaimTypes.Name,account.Username));
AddClaim(新的Claim(“DriverId”,account.DriverId.ToString());
var newTicket=newauthenticationticket(claimsIdentity,null);
上下文验证(newTicket);
}
}
捕获{}
返回Task.FromResult(空);
}
公共覆盖任务GrantRefreshToken(OAuthGrantRefreshTokenContext)
{
context.Validated();
返回Task.FromResult(空);
}
}
RefreshTokenProvider.cs:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,

            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(5),

            Provider = new OAuthProvider(),
            RefreshTokenProvider = new RefreshTokenProvider()
        });
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        app.UseWebApi(config);
    }
}
public class OAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        if (context.UserName == "admin" && context.Password == "123456")
        {
            var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, "Admin"));

            var ticket = new AuthenticationTicket(claimsIdentity, null);
            context.Validated(ticket);
        }
        return Task.FromResult<object>(null);
    }

    public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
    {
        context.Validated(context.Ticket);
        return Task.FromResult<object>(null);
    }
}
public class RefreshTokenProvider : AuthenticationTokenProvider
{
    private static ConcurrentDictionary<string, AuthenticationTicket> _refreshTokens = new ConcurrentDictionary<string, AuthenticationTicket>();

    public override Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        var guid = Guid.NewGuid().ToString();
        _refreshTokens.TryAdd(guid, context.Ticket);

        context.SetToken(guid);
        return Task.FromResult<object>(null);
    }

    public override Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {
        if (_refreshTokens.TryRemove(context.Token, out AuthenticationTicket ticket))
        {
            context.SetTicket(ticket);
        }
        return Task.FromResult<object>(null);
    }
}
public class OAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        try
        {
            var account = AccountRepository.Instance.GetByUsername(context.UserName);
            if (account != null && Global.VerifyHash(context.Password, account.Password))
            {
                var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
                claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, account.Username));
                claimsIdentity.AddClaim(new Claim("DriverId", account.DriverId.ToString()));

                var newTicket = new AuthenticationTicket(claimsIdentity, null);
                context.Validated(newTicket);
            }
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }
}
public class RefreshTokenProvider : AuthenticationTokenProvider
{
    public override Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        var refreshToken = new TokenModel()
        {
            Subject = context.Ticket.Identity.Name,
            Token = GenerateToken(),
            IssuedUtc = DateTime.UtcNow,
            ExpiresUtc = DateTime.UtcNow.AddMinutes(5)
        };

        context.Ticket.Properties.IssuedUtc = refreshToken.IssuedUtc;
        context.Ticket.Properties.ExpiresUtc = refreshToken.ExpiresUtc;

        refreshToken.Ticket = context.SerializeTicket();

        try
        {
            TokenRepository.Instance.Insert(refreshToken);
            context.SetToken(refreshToken.Token);
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    public override Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {
        try
        {
            var refreshToken = TokenRepository.Instance.Get(context.Token);
            if (refreshToken != null)
            {
                if (TokenRepository.Instance.Delete(refreshToken))
                {
                    context.DeserializeTicket(refreshToken.Ticket);
                }
            }
        }
        catch { }

        return Task.FromResult<object>(null);
    }

    private string GenerateToken()
    {
        HashAlgorithm hashAlgorithm = new SHA256CryptoServiceProvider();

        byte[] byteValue = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString("N"));
        byte[] byteHash = hashAlgorithm.ComputeHash(byteValue);

        return Convert.ToBase64String(byteHash);
    }
}
公共类RefreshTokenProvider:AuthenticationTokenProvider
{
公共重写任务CreateAncy(AuthenticationTokenCreateContext上下文)
{
var refreshttoken=new-TokenModel()
{
主题=context.Ticket.Identity.Name,
令牌=GenerateToken(),
IssuedUtc=DateTime.UtcNow,
ExpiresUtc=DateTime.UtcNow.AddMinutes(5)
};
context.Ticket.Properties.IssuedUtc=refreshToken.IssuedUtc;
context.Ticket.Properties.ExpiresUtc=refreshToken.ExpiresUtc;
refreshToken.Ticket=context.SerializeTicket();
尝试
{
TokenRepository.Instance.Insert(刷新令牌);
SetToken(refreshToken.Token);
}
捕获{}
返回Task.FromResult(空);
}
公共覆盖任务ReceiveAsync(AuthenticationTokenReceiveContext上下文)
{
尝试
{
var refreshttoken=TokenRepository.Instance.Get(context.Token);
if(刷新令牌!=null)
{
if(TokenRepository.Instance.Delete(refreshttoken))
{
DeserializeTicket(refreshToken.Ticket);
}
}
}
捕获{}
返回Task.FromResult(空);
}
私有字符串GenerateToken()
{
HashAlgorithm HashAlgorithm=新的SHA256CryptoServiceProvider();
byte[]byteValue=Encoding.UTF8.GetBytes(Guid.NewGuid().ToString(“N”));
byte[]byteHash=hashAlgorithm.ComputeHash(字节值);
返回Convert.tobase64字符串(字节哈希);
}
}

谢谢你的支持

刷新令牌似乎与访问令牌具有相同的过期时间。因此,您需要延长刷新令牌的过期时间:

public override Task CreateAsync(AuthenticationTokenCreateContext context)
{
    var form = context.Request.ReadFormAsync().Result;
    var grantType = form.GetValues("grant_type");

    if (grantType[0] != "refresh_token")
    {
        ...

        // One day
        int expire = 24 * 60 * 60;
        context.Ticket.Properties.ExpiresUtc = new DateTimeOffset(DateTime.Now.AddSeconds(expire));
    }
    base.Create(context);
}
--更新--

我已将代码更新为ans