C# Identity4Server多个SPA客户端的最佳方法?
嗨,我继承了这样一个系统: 一个Api和多个Fronts(SPA)它们共享一个带有链接的公共菜单,以相互导航,但它们是不同的应用程序,具有不同的URL。和Azure Active directory来验证Api是否受承载令牌保护 大概是这样的: 现在,我有了授权需求和自定义权限,业务人员希望将这些权限分配给每个用户,用于他们可以执行或不执行的操作和可见性 我想将Identity4Server与active directory一起用作开放id提供程序。然后使用提供者api获取自定义权限,并将这些权限放入声明中。然后在需要指定角色和声明以完成权限规范的Api impl策略中 大概是这样的: Identity4Server配置:C# Identity4Server多个SPA客户端的最佳方法?,c#,reactjs,asp.net-core,single-page-application,identityserver4,C#,Reactjs,Asp.net Core,Single Page Application,Identityserver4,嗨,我继承了这样一个系统: 一个Api和多个Fronts(SPA)它们共享一个带有链接的公共菜单,以相互导航,但它们是不同的应用程序,具有不同的URL。和Azure Active directory来验证Api是否受承载令牌保护 大概是这样的: 现在,我有了授权需求和自定义权限,业务人员希望将这些权限分配给每个用户,用于他们可以执行或不执行的操作和可见性 我想将Identity4Server与active directory一起用作开放id提供程序。然后使用提供者api获取自定义权限,并将这些
services.AddAuthentication()
.AddOpenIdConnect("oidc", "OpenID Connect", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.SignOutScheme = IdentityServerConstants.SignoutScheme;
options.SaveTokens = true;
options.RequireHttpsMetadata = false;
options.Authority = "https://login.microsoftonline.com/tenant/";
options.ClientId = "ClientId";
options.ClientSecret = "ClientSecret";
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
});
Api:
对于react应用程序,我使用的是npm“oidc客户端”:“1.7.0”和类似的方法
客户端的配置是:(Provider它非常相似唯一改变的是url localhost:3001)
如果用户登录到客户端(localhost:3000)前端,然后导航到提供者(localhost:3001)前端,则不应再次登录。为了实现这一点,我使用相同的客户端id配置了所有前端,但我不知道这是否是正确的方法。现在,identity server中的配置类是:
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "fronts",
ClientSecrets =
{
new Secret("secret".Sha256())
},
ClientName = "All fronts",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
RedirectUris = { "http://localhost:3000/signin-oidc", "http://localhost:3001/signin-oidc" },
PostLogoutRedirectUris = { "http://localhost:3000/signout-callback-oidc", "http://localhost:3001/signout-callback-oidc" },
AllowedCorsOrigins = { "http://localhost:3000", "http://localhost:3001" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api"
}
}
};
}
public静态IEnumerable GetClients()
{
返回新列表
{
新客户
{
ClientId=“fronts”,
客户秘密=
{
新密码(“Secret.Sha256())
},
ClientName=“所有战线”,
AllowedGrantTypes=GrantTypes.Implicit,
AllowAccessTokensViaBrowser=true,
重定向URI={”http://localhost:3000/signin-oidc“http://localhost:3001/signin-oidc“},
PostLogoutRedirectUris={”http://localhost:3000/signout-回调oidc“http://localhost:3001/signout-回调oidc“},
AllowedCorsOrigins={”http://localhost:3000", "http://localhost:3001" },
AllowedScopes=新列表
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
“api”
}
}
};
}
您认为这种配置是正确的方法还是有更好的方法?您提到过
许多不同的应用程序使用不同的URL
但是在您的代码片段中,我只看到客户端(localhost:3000)
不管怎样,协议规范告诉我们注册我们需要的尽可能多的客户端。SSO是身份提供者的主要职责
您只需添加requiresent=false在IdSrv中向客户端def添加代码>,以避免额外的非预期用户交互
此外,目前推荐的spa-s认证流程为“代码+pkce”。您可以查看以获取有关过渡的详细信息。您好,谢谢您的回复。我来看看这篇文章。您还可以看到具有不同url的提供程序(localhost:3001)。我将用spa身份配置更新问题。另外,问题是注册的客户不多,我可以在每个spa站点注册一个客户,问题是如果我登录一个站点并导航到另一个站点,我就不必再次登录。当然!正如我所提到的,IdP的主要任务是为一个用户创建一个会话,并代表同一个用户为下一个应用程序执行静默登录在IdSrv中向客户端def添加代码>,以避免额外的非预期用户交互。将此添加到答案中。还有一件小事:ClientSecret
不是隐式nor代码+PKCE授权类型所必需的ClientSecret
必须秘密保存,而基于浏览器的应用程序代码是设计上公开的。
export const IDENTITY_CONFIG = {
authority: "http://localhost:5000",
clientId: "fronts",
redirect_uri: "http://localhost:3000/signin-oidc",
login: "http://localhost:5000/login",
automaticSilentRenew: false,
loadUserInfo: false,
silent_redirect_uri: "http://localhost:3000/silentrenew",
post_logout_redirect_uri: "http://localhost:3000/signout-callback-oidc",
audience: "fronts",
responseType: "id_token token",
grantType: "password",
scope: "openid api",
webAuthResponseType: "id_token token"
};
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "fronts",
ClientSecrets =
{
new Secret("secret".Sha256())
},
ClientName = "All fronts",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
RedirectUris = { "http://localhost:3000/signin-oidc", "http://localhost:3001/signin-oidc" },
PostLogoutRedirectUris = { "http://localhost:3000/signout-callback-oidc", "http://localhost:3001/signout-callback-oidc" },
AllowedCorsOrigins = { "http://localhost:3000", "http://localhost:3001" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api"
}
}
};
}