Identity4Server много клиентов SPA лучше всего подходят? - PullRequest
1 голос
/ 09 апреля 2019

Привет, у меня есть такая система:

Api и многие Фронты (курорты) имеют общее меню со ссылками для перехода друг к другу, но это разные реагирующие приложения с разными URL. А Azure Active Directory для проверки подлинности API защищен токеном Bearer.

Примерно так:

enter image description here

Теперь у меня есть требования авторизации с настраиваемыми разрешениями, которые деловые люди хотят назначить каждому пользователю, для действий, которые он может делать или нет, и для обеспечения видимости.

Я хочу использовать Identity4Server с активным каталогом в качестве поставщика открытого идентификатора. Затем используйте 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);
            });

Для приложений реагирования я использую npm "oidc-client": "1.7.0" и подход, аналогичный https://medium.com/@franciscopa91/how-to-implement-oidc-authentication-with-react-context-api-and-react-router-205e13f2d49 Конфигурация Clients: (Поставщик его очень похож, единственное, что изменилось, это 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), он не должен входить снова. Для этого я настраиваю все фронты с одинаковым идентификатором клиента, но я не знаю, является ли это правильным способом сделать это. Теперь мой конфигурационный класс на сервере идентификации:

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 Ответ

1 голос
/ 09 апреля 2019

Вы упомянули

много разных реагирующих приложений с разными URL

, но в вашем фрагменте кода я вижу только Clients(localhost:3000).

В любом случае, спецификация протокола говорит нам регистрировать столько клиентов, сколько нам нужно.SSO является основной обязанностью провайдера идентификации.

Вам просто нужно добавить RequireConsent = false; к своему клиентскому определению в IdSrv, чтобы избежать дополнительного непреднамеренного взаимодействия с пользователем.

Кроме того, в настоящее время рекомендуемым потоком аутентификации для spa-s является "code + pkce",Вы можете взглянуть на эту статью , чтобы получить подробную информацию для перехода.

...