Identity4Server是许多SPA客户端的最佳方法吗?

时间:2019-04-09 09:59:51

标签: c# reactjs asp.net-core single-page-application identityserver4

嗨,我继承了这样的系统:

Api和许多Fronts(spa)共享一个共同的菜单,这些菜单带有可相互导航的链接,但它们是不同的React应用程序,具有不同的URL。用于验证Api的Azure Active Directory受Bearer令牌保护。

类似这样的东西:

enter image description here

现在,我具有授权要求,这些授权要求是业务人员要分配给每个用户的自定义权限,以执行他们可以执行的操作以及可见性。

我想将Identity4Server与活动目录一起用作开放ID提供程序。然后使用提供者api获取自定义权限,并将这些权限放入声明中。然后,在Api隐含策略中,要求指定角色和声明以完成权限规范。

类似这样的东西:

enter image description here

Identity4Server配置:

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:

services
                .AddAuthentication(configure =>
                {
                    configure.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    configure.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(options =>
                {
                    options.Audience = "api";
                    options.Authority = "http://localhost:5000";
                    options.RequireHttpsMetadata = false;
                });

var clientsPolicy = new AuthorizationPolicyBuilder()
                .AddAuthenticationSchemes("Bearer")
                .AddRequirements(new ClaimsAuthorizationRequirement("ClientsModule", new[] { "1" }))
                .RequireRole("Admin")
                .Build();

            services.AddAuthorization(options =>
            {
                options.AddPolicy("Clients", clientsPolicy);
            });

对于React应用程序,我正在使用此npm“ oidc-client”:“ 1.7.0”和类似的方法https://medium.com/@franciscopa91/how-to-implement-oidc-authentication-with-react-context-api-and-react-router-205e13f2d49 客户端的配置是:(提供程序非常相似,唯一的更改是url localhost:3001)

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"
};

如果用户先登录到客户端(localhost:3000),然后再导航到提供程序(localhost:3001),则不应再次登录。为此,我为所有战线配置了相同的客户端ID,但我不知道这是否是正确的方法。现在我在身份服务器中的配置类是:

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"
                    }
                }
            };
        }

您认为此配置是正确的方法还是有更好的方法?

1 个答案:

答案 0 :(得分:1)

您提到

  

许多不同的React应用,具有不同的URL

,但是在您的代码段中,我仅看到q=+{!v=$q1} +{!v=$q2} +{!v=$q3} {!func sum($q1,$q2,$q3)}

无论如何,协议规范要求我们注册所需数量的客户端。 SSO是身份提供者的主要责任。

您只需要在IdSrv中的客户端定义中添加Clients(localhost:3000)即可避免不必要的用户交互。

此外,如今,spa-s的推荐身份验证流是“ code + pkce”。您可以查看this article,以获得有关过渡的详细信息。