Ich habe vor kurzem Setup IdentityServer v3 und läuft wie ein Traum, aber ich habe Probleme mit der OWIN-Middleware.Refresh Tokens mit OWIN Middleware und IdentityServer v3
Ich möchte den hybriden Fluss verwenden, damit ich Token im Backend aktualisieren kann, ohne dass der Benutzer zurück zum IdentityServer umleiten muss, um alle 5 Minuten ein neues Zugriffstoken zu erhalten Lebensdauer von 1 Stunde auf dem Server).
Ich verwende die folgende Konfiguration beim Start und ich bekomme die Token in Ordnung, aber es scheint nie zu versuchen und aktualisieren Sie das Access Token, sobald es abgelaufen ist. Benötige ich irgendwo eine benutzerdefinierte Logik, um meine Token zu aktualisieren?
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
ClientSecret = clientSecret, //Not sure what this does?
Authority = "https://auth.example.com",
RedirectUri = "http://website.example.com",
PostLogoutRedirectUri = "http://website.example.com",
ResponseType = "code id_token token",
Scope = "openid profile email write read offline_access",
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = async n =>
{
// filter "protocol" claims
var claims = new List<Claim>(from c in n.AuthenticationTicket.Identity.Claims
where c.Type != "iss" &&
c.Type != "aud" &&
c.Type != "nbf" &&
c.Type != "exp" &&
c.Type != "iat" &&
c.Type != "nonce" &&
c.Type != "c_hash" &&
c.Type != "at_hash"
select c);
// get userinfo data
var userInfoClient = new UserInfoClient(
new Uri(n.Options.Authority + "/connect/userinfo"),
n.ProtocolMessage.AccessToken);
var userInfo = await userInfoClient.GetAsync();
userInfo.Claims.ToList().ForEach(ui => claims.Add(new Claim(ui.Item1, ui.Item2)));
// get access and refresh token
var tokenClient = new OAuth2Client(
new Uri(n.Options.Authority + "/connect/token"),
clientId,
clientSecret);
var response = await tokenClient.RequestAuthorizationCodeAsync(n.Code, n.RedirectUri);
claims.Add(new Claim("access_token", response.AccessToken));
claims.Add(new Claim("expires_at", DateTime.UtcNow.AddSeconds(response.ExpiresIn).ToLocalTime().ToString(CultureInfo.InvariantCulture)));
claims.Add(new Claim("refresh_token", response.RefreshToken));
claims.Add(new Claim("id_token", n.ProtocolMessage.IdToken));
//Does this help?
n.AuthenticationTicket.Properties.AllowRefresh = true;
n.AuthenticationTicket = new AuthenticationTicket(
new ClaimsIdentity(
claims.Distinct(new ClaimComparer()),
n.AuthenticationTicket.Identity.AuthenticationType),
n.AuthenticationTicket.Properties);
},
RedirectToIdentityProvider = async n =>
{
// if signing out, add the id_token_hint
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
{
var id = n.OwinContext.Authentication.User.FindFirst("id_token");
if (id != null)
{
var idTokenHint = id.Value;
n.ProtocolMessage.IdTokenHint = idTokenHint;
}
}
}
}
});
ich auch die folgenden in meinem ApiClient (RestSharp) verwendet, die zu meiner Ressource api spricht
public class MyTokenAuthenticator : IAuthenticator
{
public void Authenticate(IRestClient client, IRestRequest request)
{
var tokenClaim = ClaimsPrincipal.Current.Claims.FirstOrDefault(c => c.Type.Equals("access_token"));
if (tokenClaim != null && !String.IsNullOrWhiteSpace(tokenClaim.Value))
request.AddHeader("Authorization", String.Format("Bearer {0}", tokenClaim.Value));
}
}
Meiner Meinung nach bis Ortszeit wartet größer oder gleich Zugriffstoken Ablaufzeit ist nicht die beste Idee. Stellen Sie sich eine Situation vor, in der diese Bedingung AccessToken nur wenige Millisekunden vor Ablauf als gültig betrachtet. Wenn Sie ein solches AccessToken an einen anderen Dienst senden, könnte es zurückgewiesen werden, da es in der Zwischenzeit abgelaufen ist. Wenn Sie den Claim "expires_at" hinzufügen, können Sie auch etwas wie den "refresh_at" Claim als Halbzeitspanne zwischen jetzt und "expires_at" hinzufügen. Eine solche Lösung würde sicherstellen, dass Access Token nicht abläuft, bevor Sie es verwenden können. – Gilmor
Ich erlaube normalerweise, durch Konfiguration, ich Minute, um zu überprüfen, wenn Token abgelaufen ist: zum Beispiel, wenn das Token in weniger als 1 Minute ausläuft, werde ich fortfahren und es aktualisieren. – jahansha