MVC客户端(IdentityServer)自动获取access_token
Automatically get access_token in MVC client (IdentityServer)
我像在“创建 MVC 客户端”中一样编写“MVC 客户端”https://identityserver4.readthedocs.io/en/latest/quickstarts/2_interactive_aspnetcore.html#creating-an-mvc-client
我的主要目标是在 access_token 过期时用 refresh_token 获得新的。
我需要它不是为了 API 访问,而是为了“MVC 客户端”authentication/authorization.
所以,我想在“MVC 客户端”问题重定向到 IdentityServer 到它的登录页面之前(http://localhost:5000/connect/authorize?client_id=mvc&redirect_uri=bla,bla,bla)只是拦截它并发送而不是它只是获取新的 access_token(使用 refresh_token) w/o 用户需要输入他的凭据。
所以,我只需要在“MVC 客户端”决定 access_token 不再有效并尝试重定向到 IdentityServer 登录之前获取任何事件。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies", options => {
options.Cookie.Name = "MyCookie";
options.Cookie.MaxAge = new TimeSpan(0, 0, 60);
options.ExpireTimeSpan = new TimeSpan(0, 0, 60);
options.SlidingExpiration = false;
//options.Cookie.s ExpireTimeSpan = new TimeSpan(0, 0, 1);
options.Events = new Func<CookieAuthenticationEvents>(() =>
{
var cookieAuthenticationEvents = new CookieAuthenticationEvents( );
var f = cookieAuthenticationEvents.OnRedirectToLogin;
var f1 = cookieAuthenticationEvents.OnValidatePrincipal;
var f2 = cookieAuthenticationEvents.OnSignedIn;
cookieAuthenticationEvents.OnRedirectToLogin = ( context ) =>
{
return f(context);
};
cookieAuthenticationEvents.OnValidatePrincipal = ( context ) =>
{
return f1(context);
};
cookieAuthenticationEvents.OnSignedIn = ( context ) =>
{
return f2(context);
};
return cookieAuthenticationEvents;
}
)( );
})
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.ClientSecret = "secret";
options.ResponseType = "code";
options.SaveTokens = true;
options.Scope.Add("email");
options.Scope.Add("api1");
options.Scope.Add("offline_access");
// options.Events = new Func<>
options.Events = new Func<OpenIdConnectEvents>(() =>
{
var openIdConnectEvents = new OpenIdConnectEvents( );
var f = openIdConnectEvents.OnAuthenticationFailed;
var f1 = openIdConnectEvents.OnAccessDenied;
var f2 = openIdConnectEvents.OnTokenValidated;
var f3 = openIdConnectEvents.OnAccessDenied;
openIdConnectEvents.OnAuthenticationFailed = ( context ) =>
{
return f(context);
};
openIdConnectEvents.OnAccessDenied = ( context ) =>
{
return f1(context);
};
openIdConnectEvents.OnTokenValidated = ( context ) =>
{
return f2(context);
};
openIdConnectEvents.OnAccessDenied = ( context ) =>
{
return f3(context);
};
return openIdConnectEvents;
}
)( );
});
}
在 "return f3(context);" 的每一行上,我都设置了断点,希望在到达 IdentityServer 的登录页面之前击中它——运气不好。
这是客户端配置。
new Client
{
ClientId = "mvc",
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.Code,
RequireConsent = false,
RequirePkce = true,
// where to redirect to after login
RedirectUris = { "http://localhost:5002/signin-oidc" },
// where to redirect to after logout
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"api1"
},
AlwaysIncludeUserClaimsInIdToken = true,
AllowOfflineAccess = true,
AccessTokenLifetime = 150,
AuthorizationCodeLifetime = 150,
UserSsoLifetime = 150
}
如何操作 - 自动刷新令牌w/o MVC 客户端身份验证的用户交互(不适用于 API 访问)
我找到了解决办法。这里是:
https://github.com/leastprivilege/AspNetCoreSecuritySamples/tree/aspnetcore21/AutomaticTokenManagement
这里的重点是重写这个方法
public override async Task ValidatePrincipal ( CookieValidatePrincipalContext context )
来自 class
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationEvents
我像在“创建 MVC 客户端”中一样编写“MVC 客户端”https://identityserver4.readthedocs.io/en/latest/quickstarts/2_interactive_aspnetcore.html#creating-an-mvc-client 我的主要目标是在 access_token 过期时用 refresh_token 获得新的。 我需要它不是为了 API 访问,而是为了“MVC 客户端”authentication/authorization.
所以,我想在“MVC 客户端”问题重定向到 IdentityServer 到它的登录页面之前(http://localhost:5000/connect/authorize?client_id=mvc&redirect_uri=bla,bla,bla)只是拦截它并发送而不是它只是获取新的 access_token(使用 refresh_token) w/o 用户需要输入他的凭据。
所以,我只需要在“MVC 客户端”决定 access_token 不再有效并尝试重定向到 IdentityServer 登录之前获取任何事件。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies", options => {
options.Cookie.Name = "MyCookie";
options.Cookie.MaxAge = new TimeSpan(0, 0, 60);
options.ExpireTimeSpan = new TimeSpan(0, 0, 60);
options.SlidingExpiration = false;
//options.Cookie.s ExpireTimeSpan = new TimeSpan(0, 0, 1);
options.Events = new Func<CookieAuthenticationEvents>(() =>
{
var cookieAuthenticationEvents = new CookieAuthenticationEvents( );
var f = cookieAuthenticationEvents.OnRedirectToLogin;
var f1 = cookieAuthenticationEvents.OnValidatePrincipal;
var f2 = cookieAuthenticationEvents.OnSignedIn;
cookieAuthenticationEvents.OnRedirectToLogin = ( context ) =>
{
return f(context);
};
cookieAuthenticationEvents.OnValidatePrincipal = ( context ) =>
{
return f1(context);
};
cookieAuthenticationEvents.OnSignedIn = ( context ) =>
{
return f2(context);
};
return cookieAuthenticationEvents;
}
)( );
})
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.ClientSecret = "secret";
options.ResponseType = "code";
options.SaveTokens = true;
options.Scope.Add("email");
options.Scope.Add("api1");
options.Scope.Add("offline_access");
// options.Events = new Func<>
options.Events = new Func<OpenIdConnectEvents>(() =>
{
var openIdConnectEvents = new OpenIdConnectEvents( );
var f = openIdConnectEvents.OnAuthenticationFailed;
var f1 = openIdConnectEvents.OnAccessDenied;
var f2 = openIdConnectEvents.OnTokenValidated;
var f3 = openIdConnectEvents.OnAccessDenied;
openIdConnectEvents.OnAuthenticationFailed = ( context ) =>
{
return f(context);
};
openIdConnectEvents.OnAccessDenied = ( context ) =>
{
return f1(context);
};
openIdConnectEvents.OnTokenValidated = ( context ) =>
{
return f2(context);
};
openIdConnectEvents.OnAccessDenied = ( context ) =>
{
return f3(context);
};
return openIdConnectEvents;
}
)( );
});
}
在 "return f3(context);" 的每一行上,我都设置了断点,希望在到达 IdentityServer 的登录页面之前击中它——运气不好。
这是客户端配置。
new Client
{
ClientId = "mvc",
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.Code,
RequireConsent = false,
RequirePkce = true,
// where to redirect to after login
RedirectUris = { "http://localhost:5002/signin-oidc" },
// where to redirect to after logout
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"api1"
},
AlwaysIncludeUserClaimsInIdToken = true,
AllowOfflineAccess = true,
AccessTokenLifetime = 150,
AuthorizationCodeLifetime = 150,
UserSsoLifetime = 150
}
如何操作 - 自动刷新令牌w/o MVC 客户端身份验证的用户交互(不适用于 API 访问)
我找到了解决办法。这里是: https://github.com/leastprivilege/AspNetCoreSecuritySamples/tree/aspnetcore21/AutomaticTokenManagement
这里的重点是重写这个方法
public override async Task ValidatePrincipal ( CookieValidatePrincipalContext context )
来自 class
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationEvents