private string cleanSiteUrl(string url)
        {
            ServiceStack.Logging.ILog log = ServiceStack.Logging.LogManager.GetLogger(typeof(OpenIDConnectProvider));
            log.Debug("cleanSiteUrl");
            log.Debug(url);
            string redirUrl = url;

            if (AppHostConfig.Instance.IsInWebClient && url.IndexOf("openidinfo", StringComparison.InvariantCultureIgnoreCase) < 0)
            {
                if (!string.IsNullOrWhiteSpace(redirUrl))
                {
                    Uri uri = new Uri(url);



                    int lastpartStart = uri.AbsolutePath.TrimEnd('/').LastIndexOf('/');

                    log.Debug(lastpartStart);
                    log.Debug(uri.AbsolutePath.Substring(0, lastpartStart));
                    redirUrl = uri.Scheme + "://" + uri.Host + uri.AbsolutePath.Substring(0, lastpartStart) + uri.Query;
                }
            }

            return(redirUrl);
        }
        public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)
        {
            ServiceStack.Logging.ILog log = ServiceStack.Logging.LogManager.GetLogger(typeof(OpenIDConnectProvider));


            var config = getOIDConfig();


            var tokens = Init(authService, ref session, request);

            string redirectUri = authService.Request.GetAbsoluteUrl($"~/auth/openid");

            log.Debug($"redirect uri: {redirectUri}");

            var httpRequest = authService.Request;


            if (httpRequest.GetParam("code") != null)
            {
                WebClient           webClient = new WebClient();
                NameValueCollection formData  = new NameValueCollection();
                formData["code"]          = httpRequest.GetParam("code");
                formData["client_id"]     = this.ConsumerKey;
                formData["redirect_uri"]  = redirectUri.ToLower();
                formData["grant_type"]    = "authorization_code";
                formData["client_secret"] = this.ConsumerSecret;

                string maxAge = httpRequest.GetParam("max_age");
                if (!string.IsNullOrWhiteSpace(maxAge))
                {
                    formData["max_age"] = maxAge;
                }

                string prompt = httpRequest.GetParam("prompt");
                if (!string.IsNullOrWhiteSpace(prompt))
                {
                    formData["prompt"] = maxAge;
                }

                webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
                var response = webClient.UploadValues(config.TokenEndpoint, formData);

                var str = System.Text.Encoding.Default.GetString(response);

                var json = JsonObject.Parse(str);

                try
                {
                    tokens.AccessToken  = json.Get <string>("access_token");
                    tokens.RequestToken = json.Get <string>("id_token");

                    session.AddAuthToken(tokens);

                    setSession(json.Get <string>("id_token"), session);

                    this.SaveSession(authService, session, SessionExpiry);
                }
                catch
                {
                    return(this.Logout(authService, request));
                }

                string redirectTo = authService.Request.GetAbsoluteUrl($"~/");


                string stateId = httpRequest.GetParam("state");

                log.Debug($"stateId: {stateId}");
                if (!string.IsNullOrWhiteSpace(stateId))
                {
                    Guid stateGuid;
                    if (Guid.TryParse(stateId, out stateGuid))
                    {
                        if (redirectUrls.ContainsKey(stateGuid))
                        {
                            if (!string.IsNullOrWhiteSpace(redirectUrls[stateGuid]))
                            {
                                redirectTo = redirectUrls[stateGuid];
                                log.Debug($"redirectTo: {redirectTo}");
                                redirectUrls.Remove(stateGuid);
                            }
                        }
                    }
                    else
                    {
                        string redirUrl = HttpUtility.UrlDecode(stateId);
                        if (redirUrl.StartsWith("http", StringComparison.InvariantCultureIgnoreCase))
                        {
                            redirectTo = redirUrl;
                        }
                    }
                }

                return(OnAuthenticated(authService, session, tokens, httpRequest.FormData.ToDictionary())
                       ?? doRedirect(authService, SuccessRedirectUrlFilter(this, redirectTo)));                                            //Haz Access!
            }
            else
            {
                log.Debug($"referrer: {session.ReferrerUrl}");
                Guid stateId = Guid.NewGuid();
                redirectUrls[stateId] = cleanSiteUrl(session.ReferrerUrl);

                var maxAge = httpRequest.GetParam("max_age");
                if (!string.IsNullOrWhiteSpace(maxAge))
                {
                    maxAge = $"&max_age={maxAge}";
                }

                var prompt = "";
                //if (ServiceDefaults.Instance.Authentication.PromptForLogin)
                //{
                //	prompt = $"&prompt=login";
                //}

                var error = httpRequest.GetParam("f");

                if (!string.IsNullOrWhiteSpace(error))
                {
                    return(HttpError.Unauthorized("AccessToken validation failed."));
                }
                else
                {
                    return(authService.Redirect($"{config.AuthorizationEndpoint}?client_id={this.ConsumerKey}&redirect_uri={redirectUri.ToLower()}&response_type=code&scope=openid%20email&state={stateId}{maxAge}{prompt}"));
                }
            }
        }
        public static string Process(ServiceStack.Logging.ILog Log, string textation, ReplacementsDictionary replacements)
        {
            //kontrola parameterov a ci je co prepisovat
            if (replacements == null || string.IsNullOrEmpty(textation) || textation.IndexOf('{') < 0)
            {
                return(textation);
            }

            //mozem pokracovat
            StringBuilder sb = new StringBuilder(textation.Length);

            int sidx  = -1; //zaciatok tagu
            int sidx1 = -1; //zaciatok tagu
            int eidx  = -1; //index konca tagu

            try
            {
                do
                {
                    //advance to next tag
                    eidx++;
                    sidx  = textation.IndexOf('{', eidx);
                    sidx1 = textation.IndexOf('{', sidx + 1);
                    if (sidx < 0)
                    {
                        break;
                    }

                    if (sidx - eidx > 0)
                    {
                        sb.Append(textation.Substring(eidx, sidx - eidx));
                    }
                    eidx = textation.IndexOf('}', sidx);

                    if (eidx < 0)     //no tag end?
                    {
                        eidx = textation.Length;
                        break;
                    }

                    //get key and replace with value
                    string key = textation.Substring(sidx + 1, eidx - sidx - 1);
                    string value;

                    int fidx = key.IndexOf(';');
                    if (fidx > 0)
                    {
                        if (sidx1 < eidx && sidx1 > 0)
                        {
                            value = "{" + key.Substring(0, fidx) + ";";
                        }
                        else
                        {
                            value = replacements.Get(key.Substring(0, fidx), key.Substring(fidx + 1)); if (value == "{Podpis}")
                            {
                                value = "{Podpis;;;}";
                            }
                        }
                    }
                    else
                    {
                        value = replacements.Get(key);
                    }

                    if (!string.IsNullOrEmpty(value))
                    {
                        sb.Append(value);
                    }
                    if (sidx1 < eidx && sidx1 > 0)
                    {
                        eidx = sidx1 - 1;
                    }
                }while (true);

                //append rest of content
                if (eidx < textation.Length)
                {
                    sb.Append(textation.Substring(eidx));
                }
            }
            catch (Exception ex)
            {
                if (Log != null)
                {
                    Log.Error(ex);
                }
                return(textation);
            }


            return(sb.ToString());
        }
Beispiel #4
0
        /// <summary>
        /// Validates the token
        /// </summary>
        /// <param name="expectedAudience">The valid audience value to check</param>
        /// <returns></returns>
        public async Task <SsoTokenValidationResult> Validate()
        {
            ServiceStack.Logging.ILog log    = ServiceStack.Logging.LogManager.GetLogger(typeof(AddInSsoToken));
            SsoTokenValidationResult  result = new SsoTokenValidationResult();

            log.Debug("before get well known");
            OpenIdConnectConfiguration config = await GetOIDConnectConfig(_wellKnownUri);


            // Issuer will always be Azure, but it will contain the tenant ID of the
            // Office 365 organization the user belongs to. We can get that from the "tid" claim

            var preferredName = Claims.FirstOrDefault(claim => claim.Type == "email");

            if (preferredName == null)
            {
                preferredName = Claims.FirstOrDefault(claim => claim.Type == "upn");
            }

            if (preferredName == null)
            {
                preferredName = Claims.FirstOrDefault(claim => claim.Type == "preferred_username");
            }

            if (preferredName == null)
            {
                result.Message = "Preferred name not found.";
                return(result);
            }


            var exp = Claims.FirstOrDefault(claim => claim.Type == "exp");

            if (exp != null)
            {
                result.Exp = Int64.Parse(exp.Value);
            }


            // Use System.IdentityModel.Tokens.Jwt library to validate the token
            JwtSecurityTokenHandler   tokenHandler = new JwtSecurityTokenHandler();
            TokenValidationParameters tvp          = new TokenValidationParameters();

            tvp.ValidateIssuer           = true;
            tvp.ValidIssuer              = GetIssuerUri();
            tvp.ValidateAudience         = true;
            tvp.ValidAudience            = _clientId;
            tvp.ValidateIssuerSigningKey = true;
            tvp.IssuerSigningKeys        = config.SigningKeys as IEnumerable <Microsoft.IdentityModel.Tokens.SecurityKey>;
            tvp.ValidateLifetime         = true;


            try
            {
                var claimsPrincipal = tokenHandler.ValidateToken(RawData, tvp, out Microsoft.IdentityModel.Tokens.SecurityToken validatedToken);
                System.Security.Claims.ClaimsPrincipal.ClaimsPrincipalSelector = () => {
                    (claimsPrincipal.Identity as ClaimsIdentity).BootstrapContext = new BootstrapContext(this.RawData);
                    return(claimsPrincipal);
                };

                // If no exception, all standard checks passed
                result.IsValid        = true;
                result.LifetimeResult = result.SignatureResult = result.AudienceResult = result.IssuerResult = "passed";
                result.PreferredName  = preferredName.Value;
            }
            catch (SecurityTokenInvalidAudienceException ex)
            {
                result.AudienceResult = "failed";
                result.Message        = ex.Message;
            }
            catch (SecurityTokenInvalidIssuerException ex)
            {
                result.IssuerResult = "failed";
                result.Message      = ex.Message;
            }
            catch (SecurityTokenInvalidLifetimeException ex)
            {
                result.LifetimeResult = "failed";
                result.Message        = ex.Message;
            }
            catch (Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException ex)
            {
                result.LifetimeResult = "failed";
                result.Message        = ex.Message;
            }
            catch (SecurityTokenInvalidSignatureException ex)
            {
                result.SignatureResult = "failed";
                result.Message         = ex.Message;
            }
            catch (Microsoft.IdentityModel.Tokens.SecurityTokenValidationException ex)
            {
                result.Message = ex.Message;
            }


            return(result);
        }