ADFS何时以及如何使用刷新令牌[UseOpenIdConnectAuthentication-ASP.NET MVC5



在Startup.Auth.cs中,在AuthorizationCodeReceived通知中,我同时收到accessToken(生存期1h(和refreshToken(24h(。问题是我不知道何时请求新的访问令牌以及如何请求。一个完整的代码示例将非常有用,因为我是一个noob,关于adfs和owin。

在某个时候,用户会被重定向到adfs,然后返回到网站,但他们会丢失会话并出现错误。

这是完整的代码转储:

public partial class Startup
{
private readonly string authority = ConfigurationManager.AppSettings["auth:Authority"];
private readonly string clientId = ConfigurationManager.AppSettings["auth:ClientId"];
private readonly string clientSecret = ConfigurationManager.AppSettings["auth:ClientSecret"];
private readonly string metadataAddress = ConfigurationManager.AppSettings["auth:MetadataAddress"];
private readonly string postLogoutRedirectUri = ConfigurationManager.AppSettings["auth:PostLogoutRedirectUri"];
private readonly string redirectUri = ConfigurationManager.AppSettings["auth:RedirectUri"];
private readonly string tokenEndpoint = ConfigurationManager.AppSettings["auth:TokenEndpoint"];
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
CookieHttpOnly = true
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = this.authority,
ClientId = this.clientId,
ClientSecret = this.clientSecret,
MetadataAddress = this.metadataAddress,
RedirectUri = this.redirectUri,
ResponseType = "code id_token",
Scope = "offline_access openid profile customscope",
RequireHttpsMetadata = false, //bool.Parse(ConfigurationManager.AppSettings["IsProduction"]),
PostLogoutRedirectUri = this.postLogoutRedirectUri,
SignInAsAuthenticationType = "Cookies",
AuthenticationMode = AuthenticationMode.Active,
UseTokenLifetime = false,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = async n =>
{
// use the code to get the access and refresh token
var tokenClient = new TokenClient(
this.tokenEndpoint,
this.clientId,
this.clientSecret);
var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, n.RedirectUri);
if (tokenResponse.IsError)
{
throw new Exception(tokenResponse.Error);
}
var handler = new JwtSecurityTokenHandler();
var identityToken = handler.ReadJwtToken(tokenResponse.IdentityToken);
var upn = identityToken.Claims.ToList().FirstOrDefault(c => c.Type == "upn")?.Value;
var localUser = new UserReader().GetByUpn(upn);
// mandatory for logout user
var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
if (localUser?.Id != null)
{
id.AddClaim(new Claim(ClaimTypes.Upn, localUser.Upn));
id.AddClaim(new Claim("Id", localUser.Id.ToString()));
id.AddClaim(new Claim("Name", localUser.Name));
id.AddClaim(new Claim("RoleId", localUser.Role.Id.ToString()));
id.AddClaim(new Claim("RoleName", localUser.Role.Name));
id.AddClaim(new Claim("IsOffice", localUser.Role.IsOffice.ToString()));
id.AddClaim(new Claim("IsInvestment", localUser.Role.IsInvestment.ToString()));
}
id.AddClaim(new Claim("identityToken", tokenResponse.IdentityToken));
id.AddClaim(new Claim("access_token", tokenResponse.AccessToken));
id.AddClaim(new Claim("expires_at",
DateTime.UtcNow.AddSeconds(tokenResponse.ExpiresIn).ToString(CultureInfo.InvariantCulture)));
id.AddClaim(new Claim("refresh_token", tokenResponse.RefreshToken));
id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
id.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity.FindFirst("sid").Value));
n.AuthenticationTicket = new AuthenticationTicket(
new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType, "name",
"role"),
n.AuthenticationTicket.Properties);
},
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
{
// valoarea idTokenHint nu persistă și fără, nu face redirect către login, imediat după log-out
var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
}
n.ProtocolMessage.PostLogoutRedirectUri = this.postLogoutRedirectUri;
return Task.FromResult(0);
},
AuthenticationFailed = (context) =>
{
if (context.Exception.Message.Contains("IDX21323") || context.Exception.Message.Contains("IDX10311"))
{
// Cateodata da eroare ca nu gaseste nonce cookie, si atunci trebuie relogat la ADFS
context.HandleResponse();
context.OwinContext.Authentication.Challenge();
}

return Task.FromResult(0);
}
}
});
}
}

要使用刷新令牌,请使用向ADFS令牌端点发出POST请求

grant_type=refresh_token

包括刷新令牌以及客户端凭据。

例如

https://ADFS租户/oauth/token?grant_type=refresh_token&client_id=client_id&client_secret=client_secret&refresh_token=refresh_token

问题是MSAL库应该为您处理此问题。

你不需要写代码。

请查看此处ADAL/MSAL下的代码示例。

最新更新