Настройка OpenID Connect для .NET Core Web API - PullRequest
0 голосов
/ 26 сентября 2018

У меня есть простое приложение, которое использует Angular в качестве внешнего интерфейса и .NET Core Web API в качестве внутренних служб.Теперь я хочу защитить свой уровень WEB API.Хотя я могу использовать OpenID Connect для этой цели.Но во всех примерах или документации в Интернете используются некоторые системы управления идентификацией (Keycloak, Okta), но я просто хочу использовать свои пользовательские данные из базы данных SQL.

Что-то вроде того, я нажал на WEB API от Angular, чтобы получить сгенерированный токен (используя OpenID?) На основе отправленных пользовательских данных.Я могу просто использовать токен для авторизации пользователей.Я хочу использовать OpenID, чтобы позже я мог использовать другие системы управления идентификацией, если захочу.

мой класс запуска в WEB API

services.AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;

            })
            .AddCookie()
            .AddOpenIdConnect(o =>
            {
                o.ClientId = "sa";
                o.ClientSecret = "sa";
                o.Authority = "https://localhost:44352";
                o.GetClaimsFromUserInfoEndpoint = true;
                o.RequireHttpsMetadata = true;
            });

Я добавил контроллер с атрибутом Authorize и добавил тестовый метод, чтобы посмотреть, что произойдет, когда я нажму на него из Swagger

Iсм. следующую ошибку

IOException: IDX20804: Unable to retrieve document from: 'https://localhost:44352/.well-known/openid-configuration'

Я не уверен, что это за ошибка.

Также я хотел бы спросить, правильно ли я это делаю.Могу ли я использовать тот же API (Authority? Как в (o.Authority = "https://localhost:44352";)) для аутентификации / получения токена).

Ответы [ 2 ]

0 голосов
/ 26 июля 2019
 services.AddAuthentication(options => 
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            }).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
                options =>
                {
                    options.LoginPath = new PathString("/");
                    options.AccessDeniedPath = "/Identity/Account/AccessDenied";
                    options.Cookie = new CookieBuilder()
                    {
                        SecurePolicy = CookieSecurePolicy.SameAsRequest,
                        Path = "/"
                    };
                    options.SlidingExpiration = true;
                    options.ExpireTimeSpan = TimeSpan.FromMinutes(sessionTimeout);

                }).AddOpenIdConnect(options =>
                {
                    options.ClientId = Configuration.GetValue<string>("oidc:ClientId");
                    options.ClientSecret = Configuration["oidc:ClientSecret"];
                    options.CallbackPath = new PathString("/auth/callback");
                    options.GetClaimsFromUserInfoEndpoint = true;
                    options.Authority = Configuration["oidc:Authority"];
                    options.SignedOutRedirectUri = "/";
                    options.RequireHttpsMetadata = false;
                    options.SaveTokens = true;
                    options.UseTokenLifetime = true;
                    var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["oidc:ClientSecret"]));

                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        RequireSignedTokens = true,
                        IssuerSigningKey = signingKey,
                        ValidateAudience = true,
                        ValidateIssuer = true,
                        ValidateIssuerSigningKey = true,
                    };
                    options.ResponseType = OpenIdConnectResponseType.Code;
                    options.AuthenticationMethod = OpenIdConnectRedirectBehavior.RedirectGet;

                    options.Scope.Clear();
                    options.Scope.Add("openid");
                    options.Scope.Add("email");
                    options.Scope.Add("profile");

                    options.Events = new OpenIdConnectEvents()
                    {
                        OnTicketReceived = context =>
                        {
                            var identity = context.Principal.Identity as ClaimsIdentity;
                            if (identity != null)
                            {
                                if (!context.Principal.HasClaim(c => c.Type == ClaimTypes.Name) &&
                                        identity.HasClaim(c => c.Type == "name"))
                                    identity.AddClaim(new Claim(ClaimTypes.Name, identity.FindFirst("name").Value));
                                if (context.Properties.Items.ContainsKey(".TokenNames"))
                                {
                                    string[] tokenNames = context.Properties.Items[".TokenNames"].Split(';');

                                    foreach (var tokenName in tokenNames)
                                    {
                                        string tokenValue = context.Properties.Items[$".Token.{tokenName}"];
                                        identity.AddClaim(new Claim(tokenName, tokenValue));
                                    }
                                }
                            }

                            var cp = new ClaimsPrincipal(identity);
                            context.Principal = cp;
                            return Task.CompletedTask;
                        },
                        //OnTokenValidated = context =>
                        //{

                        //    ClaimsIdentity identity = (ClaimsIdentity)context.Principal.Identity;
                        //    Claim Name = identity.FindFirst("preferred_username");
                        //    Claim gender = identity.FindFirst(ClaimTypes.Gender);
                        //    Claim sub = identity.FindFirst(ClaimTypes.NameIdentifier);
                        //    var claimsToKeep = new List<Claim> { Name, gender, sub };

                        //    var newIdentity = new ClaimsIdentity(claimsToKeep, identity.AuthenticationType);

                        //    context.Principal = new ClaimsPrincipal(newIdentity);

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

                        OnAuthenticationFailed = context =>
                        {
                            context.Response.Redirect("/");
                            context.HandleResponse();
                            return Task.CompletedTask;
                        },
                        OnRedirectToIdentityProvider = context =>
                        {
                            context.ProtocolMessage.SetParameter("pfidpadapterid", Configuration["oidc:pfidpadapterid"]);
                            return Task.FromResult(0);
                        }
                    };
                });
0 голосов
/ 05 марта 2019

Что вам понадобится для OpenIDConnect, так это сервер, который реализует oidc-spec .URL .well-known/... является частью спецификации oidc discovery , которую реализуют такие серверы, как identityserver и keycloak.Он предоставляет стандартизированный список других конечных точек для извлечения токенов, получения информации о пользователе, получения logouturi и т. Д.

Ваш API не имеет такой конечной точки, так что об этом говорит ошибка.

Если вы хотитечтобы реализовать всю oidc-спецификацию самостоятельно, сделайте это, но я бы не советовал, это довольно сложно.Насколько я понимаю, ядро ​​.net реализует только openidconnect-client, и вы можете выбирать реализацию сервера, если она реализует спецификацию.

В качестве альтернативы, посмотрите на JwtBearer, который являетсяболее легкий подход к аутентификации и более простое внедрение (и, что самое приятное, вы можете легко перейти на oidc позже).Хорошие отправные точки могут быть эти blogposts .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...