Exemple #1
0
        // Получаем данные из ЕСИА
        public async Task <ActionResult> EsiaPage()
        {
            var esiaToken = Session["esiaToken"];

            if (esiaToken != null)
            {
                // Создаем ЕСИА клиента с маркером доступа для получения данных
                var esiaClient = new EsiaClient(Esia.GetOptions(), (EsiaToken)esiaToken);

                // ВАЖНО! Указанная в параметрах ЕСИА (Esia.GetOptions()) область доступа может не предоставить необходимые данные. В данном примере используется полный доступ
                // Получим данные о пользователе
                var personInfo = await esiaClient.GetPersonInfoAsync();

                // Пользователь не подтвержден - выводим ошибку
                if (!personInfo.Trusted)
                {
                    return(View("Error"));
                }

                // Получаем контакты
                var contacts = await esiaClient.GetPersonContactsAsync();

                // Получаем документы пользователя
                var docs = await esiaClient.GetPersonDocsAsync();

                // Получаем адреса пользователя
                var addrs = await esiaClient.GetPersonAddrsAsync();

                // Получаем транспортные средства
                var vehicles = await esiaClient.GetPersonVehiclesAsync();

                // Получаем детей
                var kids = await esiaClient.GetPersonKidsAsync();

                foreach (var child in kids)
                {
                    // Получаем документы ребенка
                    var childDoc = await esiaClient.GetPersonChildDocsAsync(child.Id);
                }

                // Отобразим данные на форме
                ViewBag.Person   = personInfo;
                ViewBag.Contacts = contacts;
                ViewBag.Docs     = docs;
                ViewBag.Addrs    = addrs;
                ViewBag.Vehicles = vehicles;
                ViewBag.Kids     = kids;
            }
            else
            {
                return(View("Error"));
            }

            return(View());
        }
        public async Task <IActionResult> OnGetCallbackAsync(string returnUrl = null, string remoteError = null)
        {
            returnUrl = returnUrl ?? Url.Content("~/");
            if (remoteError != null)
            {
                ErrorMessage = $"Error from external provider: {remoteError}";
                return(RedirectToPage("./Login", new { ReturnUrl = returnUrl }));
            }
            var info = await _signInManager.GetExternalLoginInfoAsync();

            if (info == null)
            {
                ErrorMessage = "Error loading external login information.";
                return(RedirectToPage("./Login", new { ReturnUrl = returnUrl }));
            }

            // Need EsiaAuthenticationOptions.SaveTokens set to true
            var client     = new EsiaClient(new EsiaRestOptions(), info.AuthenticationTokens.First(c => c.Name == "access_token").Value);
            var personInfo = await client.GetPersonInfoAsync();

            // Sign in the user with this external login provider if the user already has a login.
            var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent : false, bypassTwoFactor : true);

            if (result.Succeeded)
            {
                _logger.LogInformation("{Name} logged in with {LoginProvider} provider.", info.Principal.Identity.Name, info.LoginProvider);
                return(LocalRedirect(returnUrl));
            }
            if (result.IsLockedOut)
            {
                return(RedirectToPage("./Lockout"));
            }
            else
            {
                // If the user does not have an account, then ask the user to create an account.
                ReturnUrl           = returnUrl;
                ProviderDisplayName = info.ProviderDisplayName;
                if (info.Principal.HasClaim(c => c.Type == ClaimTypes.Email))
                {
                    Input = new InputModel
                    {
                        Email = info.Principal.FindFirstValue(ClaimTypes.Email)
                    };
                }
                return(Page());
            }
        }
Exemple #3
0
        protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties,
                                                                               OAuthTokenResponse tokens)
        {
            var esiaClient = new EsiaClient(Options.RestOptions, tokens.AccessToken, Backchannel);

            // Get owner personal information and contacts. If requested scope does not allow some information, corresponding properties will be null
            var personInfo = await esiaClient.GetPersonInfoAsync();

            var contactsInfo = await esiaClient.GetPersonContactsAsync();

            identity.AddClaims(new[]
            {
                new Claim(ClaimTypes.NameIdentifier, esiaClient.Token.SbjId, ClaimValueTypes.String, Scheme.Name),
                new Claim("urn:esia:sbj_id", esiaClient.Token.SbjId, ClaimValueTypes.String, Scheme.Name),
                new Claim(ClaimTypes.AuthenticationMethod, "ESIA", ClaimValueTypes.String, Scheme.Name)
            });

            if (personInfo != null)
            {
                // Set some claims from personal info
                if (!String.IsNullOrEmpty(personInfo.Name))
                {
                    identity.AddClaim(new Claim(ClaimTypes.Name, personInfo.Name, ClaimValueTypes.String, Scheme.Name));
                }

                identity.AddClaim(new Claim("urn:esia:trusted", personInfo.Trusted.ToString(), ClaimValueTypes.Boolean, Scheme.Name));
            }

            if (contactsInfo != null)
            {
                // Set email claim from contacts
                var email = contactsInfo.FirstOrDefault(c => c.ContactType == ContactType.Email);

                if (email != null)
                {
                    identity.AddClaim(new Claim(ClaimTypes.Email, email.Value, ClaimValueTypes.String, Scheme.Name));
                }
            }

            var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel,
                                                         tokens, new JsonElement());

            await Events.CreatingTicket(context);

            return(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name));
        }
Exemple #4
0
        public EsiaAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, EsiaAuthenticationOptions options) : base(next, options)
        {
            if (String.IsNullOrWhiteSpace(Options.EsiaOptions.ClientId))
            {
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Resources.ErrorParamMustBeProvided, "ClientId"));
            }

            if (String.IsNullOrWhiteSpace(Options.EsiaOptions.Scope))
            {
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Resources.ErrorParamMustBeProvided, "Scope"));
            }

            if (String.IsNullOrWhiteSpace(Options.EsiaOptions.RequestType))
            {
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Resources.ErrorParamMustBeProvided, "RequestType"));
            }

            if (Options.EsiaOptions.SignProvider == null)
            {
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Resources.ErrorParamMustBeProvided, "SignProvider"));
            }

            _logger = app.CreateLogger <EsiaAuthenticationMiddleware>();

            if (Options.DataFormat == null)
            {
                IDataProtector dataProtecter = app.CreateDataProtector(typeof(EsiaAuthenticationMiddleware).FullName, Options.AuthenticationType, "v1");

                Options.DataFormat = new PropertiesDataFormat(dataProtecter);
            }

            if (Options.Provider == null)
            {
                Options.Provider = new EsiaAuthenticationProvider();
            }

            if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType))
            {
                Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType();
            }

            _esiaClient = new EsiaClient(Options.EsiaOptions);
        }
Exemple #5
0
        /// <summary>
        /// Core authentication logic
        /// </summary>
        /// <returns>AuthenticationTicket</returns>
        protected override async Task <AuthenticationTicket> AuthenticateCoreAsync()
        {
            AuthenticationProperties properties = null;

            try
            {
                IReadableStringCollection query = Request.Query;

                properties = UnpackDataParameter(query);

                if (properties == null)
                {
                    _logger.WriteWarning("Invalid return data");

                    return(null);
                }

                // Anti-CSRF
                if (!ValidateCorrelationId(properties, _logger))
                {
                    return(new AuthenticationTicket(null, properties));
                }

                var queryValues = await ParseRequestAsync(query);

                string value = queryValues["error"];

                // ESIA error response
                if (value != null)
                {
                    var description = queryValues["error_description"];

                    _logger.WriteWarning($"ESIA Error '{value}'. {description}");

                    return(new AuthenticationTicket(null, properties));
                }

                value = queryValues["state"];

                // Checking response state with request state (fron options)
                if (value == null || value != Options.EsiaOptions.State.ToString("D"))
                {
                    _logger.WriteWarning("State parameter is missing or invalid");

                    return(new AuthenticationTicket(null, properties));
                }

                // Authentication code
                string authCode = queryValues["code"];

                if (String.IsNullOrWhiteSpace(authCode))
                {
                    _logger.WriteWarning("Code parameter is missing or invalid");

                    return(new AuthenticationTicket(null, properties));
                }

                // Get access token response from authentication code
                var tokenResponse = await _esiaClient.GetOAuthTokenAsync(authCode, BuildCallbackUri(""));

                // Check token signature if Options.VerifyTokenSignature is true
                if (Options.VerifyTokenSignature && !_esiaClient.VerifyToken(tokenResponse.AccessToken))
                {
                    _logger.WriteWarning("Token signature is invalid");

                    return(new AuthenticationTicket(null, properties));
                }

                // Create EsiaToken class instance from token response and set it to esia client
                _esiaClient.Token = EsiaClient.CreateToken(tokenResponse);

                // Get owner personal information and contacts. If requested scope does not allow some information, corresponding properties will be null
                var personInfo = await _esiaClient.GetPersonInfoAsync(SendStyles.None);

                var contactsInfo = await _esiaClient.GetPersonContactsAsync(SendStyles.None);

                var context = new EsiaAuthenticatedContext(Context, _esiaClient.Token, personInfo, contactsInfo);

                context.Identity = new ClaimsIdentity(
                    new[]
                {
                    new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.AuthenticationType),
                    new Claim("urn:esia:sbj_id", context.Id, ClaimValueTypes.String, Options.AuthenticationType),
                    new Claim(ClaimTypes.AuthenticationMethod, "ESIA", ClaimValueTypes.String, Options.AuthenticationType)
                },
                    Options.AuthenticationType,
                    ClaimsIdentity.DefaultNameClaimType,
                    ClaimsIdentity.DefaultRoleClaimType);

                if (personInfo != null)
                {   // Set some claims from personal info
                    context.Identity.AddClaim(new Claim(ClaimTypes.Name, personInfo.Name, ClaimValueTypes.String, Options.AuthenticationType));
                    context.Identity.AddClaim(new Claim("urn:esia:trusted", personInfo.Trusted.ToString(), ClaimValueTypes.Boolean, Options.AuthenticationType));
                }

                if (contactsInfo != null)
                {   // Set email claim from contacts
                    var email = contactsInfo.FirstOrDefault(c => c.ContactType == ContactType.Email);

                    if (email != null)
                    {
                        context.Identity.AddClaim(new Claim(ClaimTypes.Email, email.Value, ClaimValueTypes.String, Options.AuthenticationType));
                    }
                }

                // Call provider autenticated callback
                await Options.Provider.Authenticated(context);

                context.Properties = properties;

                return(new AuthenticationTicket(context.Identity, context.Properties));
            }
            catch (Exception ex)
            {
                _logger.WriteError("Authentication failed", ex);

                return(new AuthenticationTicket(null, properties));
            }
        }
Exemple #6
0
 public EsiaAuthenticationHandler(EsiaClient esiaClient, ILogger logger)
 {
     _esiaClient = esiaClient;
     _logger     = logger;
 }