Example #1
0
        private static string IssueToken
            (string sourceApplication, string issuerApplication, string sourceRealm, string targetApplication, string targetRealm,
            string targetApplicationHostName, bool trustedForDelegation, IEnumerable <JsonWebTokenClaim> claims, bool appOnly = false)
        {
            if (null == WebConfigAddInDataRescue.SigningCredentials)
            {
                throw new InvalidOperationException("SigningCredentials was not initialized");
            }

            #region Actor token

            string issuer   = string.IsNullOrEmpty(sourceRealm) ? issuerApplication : string.Format("{0}@{1}", issuerApplication, sourceRealm);
            string nameid   = string.IsNullOrEmpty(sourceRealm) ? sourceApplication : string.Format("{0}@{1}", sourceApplication, sourceRealm);
            string audience = string.Format("{0}/{1}@{2}", targetApplication, targetApplicationHostName, targetRealm);

            List <JsonWebTokenClaim> actorClaims = new List <JsonWebTokenClaim>();
            actorClaims.Add(new JsonWebTokenClaim(JsonWebTokenConstants.ReservedClaims.NameIdentifier, nameid));
            if (trustedForDelegation && !appOnly)
            {
                actorClaims.Add(new JsonWebTokenClaim(ClaimType.trustedfordelegation.ToString(), "true"));
            }

            // Create token
            JsonWebSecurityToken actorToken = new JsonWebSecurityToken(
                issuer: issuer,
                audience: audience,
                validFrom: DateTime.UtcNow,
                validTo: DateTime.UtcNow.Add(HighTrustAccessTokenLifetime),
                signingCredentials: WebConfigAddInDataRescue.SigningCredentials,
                claims: actorClaims);

            string actorTokenString = new JsonWebSecurityTokenHandler().WriteTokenAsString(actorToken);

            if (appOnly)
            {
                actorTokenString = new JsonWebSecurityTokenHandler().WriteTokenAsString(actorToken);
                // App-only token is the same as actor token for delegated case
                return(actorTokenString);
            }

            #endregion Actor token

            #region Outer token

            List <JsonWebTokenClaim> outerClaims = null == claims ? new List <JsonWebTokenClaim>() : new List <JsonWebTokenClaim>(claims);
            outerClaims.Add(new JsonWebTokenClaim(ClaimType.actortoken.ToString(), actorTokenString));

            JsonWebSecurityToken jsonToken = new JsonWebSecurityToken(
                nameid, // outer token issuer should match actor token nameid
                audience,
                DateTime.UtcNow,
                DateTime.UtcNow.Add(HighTrustAccessTokenLifetime),
                outerClaims);

            string accessToken = new JsonWebSecurityTokenHandler().WriteTokenAsString(jsonToken);

            #endregion Outer token

            return(accessToken);
        }
Example #2
0
        /// <summary>
        /// Validate that a specified context token string is intended for this application based on the parameters
        /// specified in web.config. Parameters used from web.config used for validation include ClientId,
        /// HostedAppHostName, ClientSecret, and Realm (if it is specified). If the <paramref name="appHostName"/> is not
        /// null, it is used for validation instead of the web.config's HostedAppHostName. If the token is invalid, an
        /// exception is thrown. If the token is valid, TokenHelper's static STS metadata url is updated based on the token contents
        /// and a JsonWebSecurityToken based on the context token is returned.
        /// </summary>
        /// <param name="contextTokenString">The context token to validate</param>
        /// <param name="appHostName">The URL authority, consisting of  Domain Name System (DNS) host name or IP address and the port number, to use for token audience validation.
        /// If null, HostedAppHostName web.config setting is used instead.</param>
        /// <returns>A JsonWebSecurityToken based on the context token.</returns>
        public static SharePointContextToken ReadAndValidateContextToken(string contextTokenString, string appHostName = null)
        {
            JsonWebSecurityTokenHandler tokenHandler = CreateJsonWebSecurityTokenHandler();
            SecurityToken          securityToken     = tokenHandler.ReadToken(contextTokenString);
            JsonWebSecurityToken   jsonToken         = securityToken as JsonWebSecurityToken;
            SharePointContextToken token             = SharePointContextToken.Create(jsonToken);

            string stsAuthority = (new Uri(token.SecurityTokenServiceUri)).Authority;
            int    firstDot     = stsAuthority.IndexOf('.');

            GlobalEndPointPrefix = stsAuthority.Substring(0, firstDot);
            AcsHostUrl           = stsAuthority.Substring(firstDot + 1);

            tokenHandler.ValidateToken(jsonToken);

            if (appHostName == null)
            {
                appHostName = HostedAppHostName;
            }

            string realm     = Realm ?? token.Realm;
            string principal = GetFormattedPrincipal(ClientId, appHostName, realm);

            if (!StringComparer.OrdinalIgnoreCase.Equals(token.Audience, principal))
            {
                throw new Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException(
                          String.Format(CultureInfo.CurrentCulture,
                                        "\"{0}\" is not the intended audience \"{1}\"", principal, token.Audience));
            }

            return(token);
        }
Example #3
0
        private SharePointContextToken ReadToken(string ContextToken)
        {
            JsonWebSecurityTokenHandler tokenHandler = TokenHelper.CreateJsonWebSecurityTokenHandler();
            SecurityToken          securityToken     = tokenHandler.ReadToken(ContextToken);
            JsonWebSecurityToken   jsonToken         = securityToken as JsonWebSecurityToken;
            SharePointContextToken token             = SharePointContextToken.Create(jsonToken);

            return(token);
        }
Example #4
0
        /// <summary>
        /// Validate that a specified context token string is intended for this application based on the parameters
        /// specified in web.config. Parameters used from web.config used for validation include ClientId,
        /// HostedAppHostNameOverride, HostedAppHostName, ClientSecret, and Realm (if it is specified). If HostedAppHostNameOverride is present,
        /// it will be used for validation. Otherwise, if the <paramref name="appHostName"/> is not
        /// null, it is used for validation instead of the web.config's HostedAppHostName. If the token is invalid, an
        /// exception is thrown. If the token is valid, TokenHelper's static STS metadata url is updated based on the token contents
        /// and a JsonWebSecurityToken based on the context token is returned.
        /// </summary>
        /// <param name="contextTokenString">The context token to validate</param>
        /// <param name="appHostName">The URL authority, consisting of  Domain Name System (DNS) host name or IP address and the port number, to use for token audience validation.
        /// If null, HostedAppHostName web.config setting is used instead. HostedAppHostNameOverride web.config setting, if present, will be used
        /// for validation instead of <paramref name="appHostName"/> .</param>
        /// <returns>A JsonWebSecurityToken based on the context token.</returns>
        public static SharePointContextToken ReadAndValidateContextToken(string contextTokenString,
                                                                         string appHostName = null)
        {
            JsonWebSecurityTokenHandler tokenHandler = CreateJsonWebSecurityTokenHandler();
            SecurityToken          securityToken     = tokenHandler.ReadToken(contextTokenString);
            JsonWebSecurityToken   jsonToken         = securityToken as JsonWebSecurityToken;
            SharePointContextToken token             = SharePointContextToken.Create(jsonToken);

            string stsAuthority = (new Uri(token.SecurityTokenServiceUri)).Authority;
            int    firstDot     = stsAuthority.IndexOf('.');

            GlobalEndPointPrefix = stsAuthority.Substring(0, firstDot);
            AcsHostUrl           = stsAuthority.Substring(firstDot + 1);

            tokenHandler.ValidateToken(jsonToken);

            string[] acceptableAudiences;
            if (!String.IsNullOrEmpty(HostedAppHostNameOverride))
            {
                acceptableAudiences = HostedAppHostNameOverride.Split(';');
            }
            else if (appHostName == null)
            {
                acceptableAudiences = new[] { HostedAppHostName };
            }
            else
            {
                acceptableAudiences = new[] { appHostName };
            }

            bool   validationSuccessful = false;
            string realm = Realm ?? token.Realm;

            foreach (var audience in acceptableAudiences)
            {
                string principal = GetFormattedPrincipal(ClientId, audience, realm);
                if (StringComparer.OrdinalIgnoreCase.Equals(token.Audience, principal))
                {
                    validationSuccessful = true;
                    break;
                }
            }

            if (!validationSuccessful)
            {
                throw new AudienceUriValidationFailedException(
                          String.Format(CultureInfo.CurrentCulture,
                                        "\"{0}\" is not the intended audience \"{1}\"", String.Join(";", acceptableAudiences),
                                        token.Audience));
            }

            return(token);
        }
Example #5
0
        private string IssueTenantAccessToken(string tenantId)
        {
            string text  = string.Format("{0}@{1}", this.settings.PartnerId, tenantId);
            string arg   = string.Format("{0}/{1}", this.settings.AcsId, this.settings.AcsUrl.Authority);
            string text2 = string.Format("{0}@{1}", arg, tenantId);
            JsonWebSecurityToken jsonWebSecurityToken = new JsonWebSecurityToken(text, text2, DateTime.UtcNow, DateTime.UtcNow.AddDays(1.0), Enumerable.Empty <JsonWebTokenClaim>(), CertificateStore.GetSigningCredentials(this.settings.CertificateSubject));
            string text3 = string.Format("{0}/{1}@{2}", this.settings.ServiceId, this.settings.ServiceHostName, tenantId);
            OAuth2AccessTokenRequest oauth2AccessTokenRequest = OAuth2MessageFactory.CreateAccessTokenRequestWithAssertion(jsonWebSecurityToken, text3);

            oauth2AccessTokenRequest.Scope = text3;
            OAuth2S2SClient           oauth2S2SClient           = new OAuth2S2SClient();
            OAuth2AccessTokenResponse oauth2AccessTokenResponse = (OAuth2AccessTokenResponse)oauth2S2SClient.Issue(this.settings.AcsUrl.AbsoluteUri, oauth2AccessTokenRequest);

            return(oauth2AccessTokenResponse.AccessToken);
        }
Example #6
0
        private string IssueUserAccessToken(string tenantId, string actorToken, IDictionary <string, string> claims)
        {
            string text  = string.Format("{0}@{1}", this.settings.PartnerId, tenantId);
            string text2 = string.Format("{0}/{1}@{2}", this.settings.ServiceId, this.settings.ServiceHostName, tenantId);
            List <JsonWebTokenClaim> first = new List <JsonWebTokenClaim>
            {
                new JsonWebTokenClaim("actortoken", actorToken),
                new JsonWebTokenClaim(TokenIssuer.ClaimTypeNii, TokenIssuer.ClaimValueNii)
            };
            IEnumerable <JsonWebTokenClaim> source = first.Concat(from claim in claims
                                                                  select new JsonWebTokenClaim(claim.Key, claim.Value));
            JsonWebSecurityToken jsonWebSecurityToken = new JsonWebSecurityToken(text, text2, DateTime.UtcNow, DateTime.UtcNow.AddDays(1.0), source.ToArray <JsonWebTokenClaim>());

            return(new JsonWebSecurityTokenHandler().WriteTokenAsString(jsonWebSecurityToken));
        }
Example #7
0
        private static string GetClaimValue(JsonWebSecurityToken token, string claimType)
        {
            if (token == null)
            {
                throw new ArgumentNullException("token");
            }

            foreach (JsonWebTokenClaim claim in token.Claims)
            {
                if (StringComparer.Ordinal.Equals(claim.ClaimType, claimType))
                {
                    return(claim.Value);
                }
            }

            return(null);
        }
Example #8
0
        public IdentityToken(IdentityTokenRequest rawToken, string audience, string authMetadataEndpoint)
        {
            X509Certificate2 currentCertificate = null;

            currentCertificate = AuthMetadata.GetSigningCertificate(new Uri(authMetadataEndpoint));

            JsonWebSecurityTokenHandler jsonTokenHandler =
                GetSecurityTokenHandler(audience, authMetadataEndpoint, currentCertificate);

            SecurityToken        jsonToken = jsonTokenHandler.ReadToken(rawToken.token);
            JsonWebSecurityToken webToken  = (JsonWebSecurityToken)jsonToken;

            x5t = currentCertificate.Thumbprint;
            iss = webToken.Issuer;
            aud = webToken.Audience;
            exp = webToken.ValidTo;
            nbf = webToken.ValidFrom;
            foreach (JsonWebTokenClaim claim in webToken.Claims)
            {
                if (claim.ClaimType.Equals(AuthClaimTypes.AppContextSender))
                {
                    appctxsender = claim.Value;
                }

                if (claim.ClaimType.Equals(AuthClaimTypes.IsBrowserHostedApp))
                {
                    isbrowserhostedapp = claim.Value == "true";
                }

                if (claim.ClaimType.Equals(AuthClaimTypes.AppContext))
                {
                    string[] appContextClaims = claim.Value.Split(',');
                    Dictionary <string, string> appContext =
                        new JavaScriptSerializer().Deserialize <Dictionary <string, string> >(claim.Value);
                    amurl     = appContext[AuthClaimTypes.MsExchAuthMetadataUrl];
                    msexchuid = appContext[AuthClaimTypes.MsExchImmutableId];
                    version   = appContext[AuthClaimTypes.MsExchTokenVersion];
                }
            }
        }
        private static string IssueToken(
            string sourceApplication,
            string issuerApplication,
            string sourceRealm,
            string targetApplication,
            string targetRealm,
            string targetApplicationHostName,
            bool trustedForDelegation,
            IEnumerable<JsonWebTokenClaim> claims,
            bool appOnly = false)
        {
            if (null == SigningCredentials)
            {
                throw new InvalidOperationException("SigningCredentials was not initialized");
            }

            #region Actor token

            string issuer = string.IsNullOrEmpty(sourceRealm) ? issuerApplication : string.Format("{0}@{1}", issuerApplication, sourceRealm);
            string nameid = string.IsNullOrEmpty(sourceRealm) ? sourceApplication : string.Format("{0}@{1}", sourceApplication, sourceRealm);
            string audience = string.Format("{0}/{1}@{2}", targetApplication, targetApplicationHostName, targetRealm);

            List<JsonWebTokenClaim> actorClaims = new List<JsonWebTokenClaim>();
            actorClaims.Add(new JsonWebTokenClaim(JsonWebTokenConstants.ReservedClaims.NameIdentifier, nameid));
            if (trustedForDelegation && !appOnly)
            {
                actorClaims.Add(new JsonWebTokenClaim(TrustedForImpersonationClaimType, "true"));
            }

            // Create token
            JsonWebSecurityToken actorToken = new JsonWebSecurityToken(
                issuer: issuer,
                audience: audience,
                validFrom: DateTime.UtcNow,
                validTo: DateTime.UtcNow.Add(HighTrustAccessTokenLifetime),
                signingCredentials: SigningCredentials,
                claims: actorClaims);

            string actorTokenString = new JsonWebSecurityTokenHandler().WriteTokenAsString(actorToken);

            if (appOnly)
            {
                // App-only token is the same as actor token for delegated case
                return actorTokenString;
            }

            #endregion Actor token

            #region Outer token

            List<JsonWebTokenClaim> outerClaims = null == claims ? new List<JsonWebTokenClaim>() : new List<JsonWebTokenClaim>(claims);
            outerClaims.Add(new JsonWebTokenClaim(ActorTokenClaimType, actorTokenString));

            JsonWebSecurityToken jsonToken = new JsonWebSecurityToken(
                nameid, // outer token issuer should match actor token nameid
                audience,
                DateTime.UtcNow,
                DateTime.UtcNow.Add(HighTrustAccessTokenLifetime),
                outerClaims);

            string accessToken = new JsonWebSecurityTokenHandler().WriteTokenAsString(jsonToken);

            #endregion Outer token

            return accessToken;
        }
        private static string GetClaimValue(JsonWebSecurityToken token, string claimType)
        {
            if (token == null)
            {
                throw new ArgumentNullException("token");
            }

            foreach (JsonWebTokenClaim claim in token.Claims)
            {
                if (StringComparer.Ordinal.Equals(claim.ClaimType, claimType))
                {
                    return claim.Value;
                }
            }

            return null;
        }
        private static string IssueToken(
            string sourceApplication,
            string issuerApplication,
            string sourceRealm,
            string targetApplication,
            string targetRealm,
            string targetApplicationHostName,
            bool trustedForDelegation,
            IEnumerable <JsonWebTokenClaim> claims,
            bool appOnly = false)
        {
            if (null == SigningCredentials)
            {
                throw new InvalidOperationException("SigningCredentials was not initialized");
            }

            #region アクター トークン

            string issuer   = string.IsNullOrEmpty(sourceRealm) ? issuerApplication : string.Format("{0}@{1}", issuerApplication, sourceRealm);
            string nameid   = string.IsNullOrEmpty(sourceRealm) ? sourceApplication : string.Format("{0}@{1}", sourceApplication, sourceRealm);
            string audience = string.Format("{0}/{1}@{2}", targetApplication, targetApplicationHostName, targetRealm);

            List <JsonWebTokenClaim> actorClaims = new List <JsonWebTokenClaim>();
            actorClaims.Add(new JsonWebTokenClaim(JsonWebTokenConstants.ReservedClaims.NameIdentifier, nameid));
            if (trustedForDelegation && !appOnly)
            {
                actorClaims.Add(new JsonWebTokenClaim(TrustedForImpersonationClaimType, "true"));
            }

            // トークンを作成します
            JsonWebSecurityToken actorToken = new JsonWebSecurityToken(
                issuer: issuer,
                audience: audience,
                validFrom: DateTime.UtcNow,
                validTo: DateTime.UtcNow.Add(HighTrustAccessTokenLifetime),
                signingCredentials: SigningCredentials,
                claims: actorClaims);

            string actorTokenString = new JsonWebSecurityTokenHandler().WriteTokenAsString(actorToken);

            if (appOnly)
            {
                // アプリケーション専用トークンはが、委任されたケースのアクター トークンと同じです
                return(actorTokenString);
            }

            #endregion Actor token

            #region 外側トークン

            List <JsonWebTokenClaim> outerClaims = null == claims ? new List <JsonWebTokenClaim>() : new List <JsonWebTokenClaim>(claims);
            outerClaims.Add(new JsonWebTokenClaim(ActorTokenClaimType, actorTokenString));

            JsonWebSecurityToken jsonToken = new JsonWebSecurityToken(
                nameid, // 外部トークンの発行者はアクター トークンの nameid と一致する必要があります
                audience,
                DateTime.UtcNow,
                DateTime.UtcNow.Add(HighTrustAccessTokenLifetime),
                outerClaims);

            string accessToken = new JsonWebSecurityTokenHandler().WriteTokenAsString(jsonToken);

            #endregion Outer token

            return(accessToken);
        }
Example #12
0
        private static OAuth2AccessTokenRequest CreateAccessTokenRequestWithAssertion(JsonWebSecurityToken token, Microsoft.IdentityModel.Tokens.SecurityTokenHandlerCollection securityTokenHandlers, string resource)
        {
            Utility.VerifyNonNullArgument("token", token);
            Utility.VerifyNonNullArgument("securityTokenHandlers", securityTokenHandlers);
            JsonWebSecurityTokenHandler jsonWebSecurityTokenHandler = securityTokenHandlers[typeof(JsonWebSecurityToken)] as JsonWebSecurityTokenHandler;

            if (jsonWebSecurityTokenHandler == null)
            {
                throw new System.ArgumentException("The input security token handlers collection does not contain a handler for JWT tokens.", "securityTokenHandlers");
            }
            string assertion = jsonWebSecurityTokenHandler.WriteTokenAsString(token);

            return(new OAuth2AccessTokenRequest
            {
                GrantType = "http://oauth.net/grant_type/jwt/1.0/bearer",
                Assertion = assertion,
                Resource = resource
            });
        }
Example #13
0
 public SharePointContextToken(string issuer, string audience, DateTime validFrom, DateTime validTo, IEnumerable <JsonWebTokenClaim> claims, SecurityToken issuerToken, JsonWebSecurityToken actorToken)
     : base(issuer, audience, validFrom, validTo, claims, issuerToken, actorToken)
 {
 }
 public static SharePointContextToken Create(JsonWebSecurityToken contextToken)
 {
     return new SharePointContextToken(contextToken.Issuer, contextToken.Audience, contextToken.ValidFrom, contextToken.ValidTo, contextToken.Claims);
 }
Example #15
0
        /// <summary>
        /// This method needs to be called from a code behind of the SharePoint app startup page (default.aspx). It registers the calling
        /// SharePoint app by calling a specific "Register" api in your WebAPI service.
        ///
        /// Note:
        /// Given that method is async you'll need to add the  Async="true" page directive to the page that uses this method.
        /// </summary>
        /// <param name="page">The page object, needed to insert the services token cookie and read the querystring</param>
        /// <param name="apiRequest">Route to the "Register" API</param>
        /// <param name="serviceEndPoint">Optional Uri to the WebAPI service endpoint. If null then the assumption is taken that the WebAPI is hosted together with the page making this call</param>
        public static async void RegisterWebAPIService(this Page page, string apiRequest, Uri serviceEndPoint = null)
        {
            if (page == null)
            {
                throw new ArgumentNullException("page");
            }

            if (string.IsNullOrEmpty(apiRequest))
            {
                throw new ArgumentNullException("apiRequest");
            }

            if (!page.IsPostBack)
            {
                if (page.Request.QueryString.AsString(SERVICES_TOKEN, string.Empty).Equals(string.Empty))
                {
                    // Construct a JsonWebSecurityToken so we can fetch the cachekey...implementation is copied from tokenhelper approach
                    string cacheKey     = string.Empty;
                    string contextToken = TokenHelper.GetContextTokenFromRequest(page.Request);
                    JsonWebSecurityTokenHandler tokenHandler = TokenHelper.CreateJsonWebSecurityTokenHandler();
                    SecurityToken        securityToken       = tokenHandler.ReadToken(contextToken);
                    JsonWebSecurityToken jsonToken           = securityToken as JsonWebSecurityToken;
                    string appctx = GetClaimValue(jsonToken, "appctx");
                    if (appctx != null)
                    {
                        ClientContext ctx = new ClientContext("http://tempuri.org");
                        Dictionary <string, object> dict = (Dictionary <string, object>)ctx.ParseObjectFromJsonString(appctx);
                        cacheKey = (string)dict["CacheKey"];
                    }

                    // Remove special chars (=, +, /, {}) from cachekey as there's a flaw in CookieHeaderValue when the
                    // cookie is read. This flaw replaces special chars with a space.
                    cacheKey = RemoveSpecialCharacters(cacheKey);

                    bool httpOnly = true;
                    if (serviceEndPoint != null)
                    {
                        if (!serviceEndPoint.Host.Equals(page.Request.Url.Host, StringComparison.InvariantCultureIgnoreCase))
                        {
                            httpOnly = false;
                        }
                    }
                    else
                    {
                        serviceEndPoint = new Uri(String.Format("{0}://{1}:{2}", page.Request.Url.Scheme, page.Request.Url.Host, page.Request.Url.Port));
                    }

                    // Write the cachekey in a cookie
                    HttpCookie cookie = new HttpCookie(SERVICES_TOKEN)
                    {
                        Value    = cacheKey,
                        Secure   = true,
                        HttpOnly = httpOnly,
                    };

                    page.Response.AppendCookie(cookie);

                    //Register the ClientContext
                    WebAPIContext sharePointServiceContext = new WebAPIContext()
                    {
                        CacheKey          = cacheKey,
                        ClientId          = TokenHelper.ClientId,
                        ClientSecret      = TokenHelper.ClientSecret,
                        Token             = contextToken,
                        HostWebUrl        = page.Request.QueryString.AsString("SPHostUrl", null),
                        AppWebUrl         = page.Request.QueryString.AsString("SPAppWebUrl", null),
                        HostedAppHostName = String.Format("{0}:{1}", page.Request.Url.Host, page.Request.Url.Port),
                    };

                    using (var client = new HttpClient())
                    {
                        client.BaseAddress = serviceEndPoint;
                        client.DefaultRequestHeaders.Accept.Clear();
                        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                        HttpResponseMessage response = await client.PutAsJsonAsync(apiRequest, sharePointServiceContext);

                        if (!response.IsSuccessStatusCode)
                        {
                            Log.Error(CoreResources.Service_RegistrationFailed, apiRequest, serviceEndPoint.ToString(), cacheKey);
                            throw new Exception(String.Format("Service registration failed: {0}", response.StatusCode));
                        }

                        Log.Info(CoreResources.Services_Registered, apiRequest, serviceEndPoint.ToString(), cacheKey);
                    }
                }
            }
        }
Example #16
0
        /// <summary>
        /// This method needs to be called from a code behind of the SharePoint app startup page (default.aspx). It registers the calling
        /// SharePoint app by calling a specific "Register" api in your WebAPI service.
        ///
        /// Note:
        /// Given that method is async you'll need to add the  Async="true" page directive to the page that uses this method.
        /// </summary>
        /// <param name="context">The HttpContextBase object, needed to insert the services token cookie and read the querystring</param>
        /// <param name="apiRequest">Route to the "Register" API</param>
        /// <param name="serviceEndPoint">Optional Uri to the WebAPI service endpoint. If null then the assumption is taken that the WebAPI is hosted together with the page making this call</param>
        public static void RegisterWebAPIService(HttpContextBase context, string apiRequest, Uri serviceEndPoint = null)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (string.IsNullOrEmpty(apiRequest))
            {
                throw new ArgumentNullException("apiRequest");
            }

            HttpRequestBase request = context.Request;

            try
            {
                if (request.QueryString.AsString(SERVICES_TOKEN, string.Empty).Equals(string.Empty))
                {
                    // Construct a JsonWebSecurityToken so we can fetch the cachekey...implementation is copied from tokenhelper approach
                    string cacheKey     = string.Empty;
                    string contextToken = TokenHelper.GetContextTokenFromRequest(request);
                    JsonWebSecurityTokenHandler tokenHandler = TokenHelper.CreateJsonWebSecurityTokenHandler();
                    SecurityToken        securityToken       = tokenHandler.ReadToken(contextToken);
                    JsonWebSecurityToken jsonToken           = securityToken as JsonWebSecurityToken;

                    string appctx = GetClaimValue(jsonToken, "appctx");
                    if (appctx != null)
                    {
                        ClientContext ctx = new ClientContext("http://tempuri.org");
                        Dictionary <string, object> dict = (Dictionary <string, object>)ctx.ParseObjectFromJsonString(appctx);
                        cacheKey = (string)dict["CacheKey"];
                    }

                    // Remove special chars (=, +, /, {}) from cachekey as there's a flaw in CookieHeaderValue when the
                    // cookie is read. This flaw replaces special chars with a space.
                    cacheKey = RemoveSpecialCharacters(cacheKey);

                    bool httpOnly = true;
                    if (serviceEndPoint != null)
                    {
                        if (!serviceEndPoint.Host.Equals(context.Request.Url.Host, StringComparison.InvariantCultureIgnoreCase))
                        {
                            httpOnly = false;
                        }
                    }
                    else
                    {
                        serviceEndPoint = new Uri(String.Format("{0}://{1}:{2}", context.Request.Url.Scheme, context.Request.Url.Host, context.Request.Url.Port));
                    }

                    // Write the cachekey in a cookie
                    HttpCookie cookie = new HttpCookie(SERVICES_TOKEN)
                    {
                        Value    = cacheKey,
                        Secure   = true,
                        HttpOnly = httpOnly,
                    };

                    context.Response.AppendCookie(cookie);

                    //Register the ClientContext
                    WebAPIContext sharePointServiceContext = new WebAPIContext()
                    {
                        CacheKey          = cacheKey,
                        ClientId          = TokenHelper.ClientId,
                        ClientSecret      = TokenHelper.ClientSecret,
                        Token             = contextToken,
                        HostWebUrl        = context.Request.QueryString.AsString("SPHostUrl", null),
                        AppWebUrl         = context.Request.QueryString.AsString("SPAppWebUrl", null),
                        HostedAppHostName = String.Format("{0}:{1}", context.Request.Url.Host, context.Request.Url.Port),
                    };

                    WebAPIHelper.AddToCache(sharePointServiceContext);
                }
            }
            catch (Exception ex)
            {
                throw new UnauthorizedAccessException("The context token cannot be validated.", ex);
            }
        }
Example #17
0
        private static string GetACSToken(OrganizationId tenantID, IConfigurationSession dataSession, ExecutionLog logger, Task task)
        {
            string             result           = null;
            LocalTokenIssuer   localTokenIssuer = new LocalTokenIssuer(tenantID);
            LocalConfiguration configuration    = ConfigProvider.Instance.Configuration;
            Uri    uri           = null;
            string text          = null;
            string applicationId = configuration.ApplicationId;
            string text2         = null;

            foreach (PartnerApplication partnerApplication in configuration.PartnerApplications)
            {
                if (partnerApplication.Enabled && partnerApplication.Name.Contains("Intune"))
                {
                    text2 = partnerApplication.ApplicationIdentifier;
                    break;
                }
            }
            foreach (AuthServer authServer in configuration.AuthServers)
            {
                if (authServer.Enabled && authServer.Type == AuthServerType.MicrosoftACS)
                {
                    text = authServer.IssuerIdentifier;
                    uri  = new Uri(authServer.TokenIssuingEndpoint);
                    break;
                }
            }
            if (localTokenIssuer.SigningCert == null)
            {
                logger.LogOneEntry(task.GetType().Name, string.Empty, ExecutionLog.EventType.Error, "No certificate found.", null);
            }
            if (text2 == null)
            {
                logger.LogOneEntry(task.GetType().Name, string.Empty, ExecutionLog.EventType.Error, "No partnerId found.", null);
            }
            if (uri == null)
            {
                logger.LogOneEntry(task.GetType().Name, string.Empty, ExecutionLog.EventType.Error, "No authorizationEndpoint found.", null);
            }
            if (string.IsNullOrEmpty(text))
            {
                logger.LogOneEntry(task.GetType().Name, string.Empty, ExecutionLog.EventType.Error, "No issuerIdentifier found.", null);
            }
            if (localTokenIssuer.SigningCert != null && text2 != null && uri != null && !string.IsNullOrEmpty(text))
            {
                string arg  = applicationId;
                string arg2 = text2;
                string intuneResourceUrl = UnifiedPolicyConfiguration.GetInstance().GetIntuneResourceUrl(dataSession);
                string arg3      = text;
                string authority = uri.Authority;
                string text3     = string.Format("{0}@{1}", arg, tenantID.ToExternalDirectoryOrganizationId());
                string text4     = string.Format("{0}/{1}@{2}", arg3, authority, tenantID.ToExternalDirectoryOrganizationId());
                string text5     = string.Format("{0}/{1}@{2}", arg2, intuneResourceUrl, tenantID.ToExternalDirectoryOrganizationId());
                X509SigningCredentials   x509SigningCredentials   = new X509SigningCredentials(localTokenIssuer.SigningCert, "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", "http://www.w3.org/2001/04/xmlenc#sha256");
                JsonWebSecurityToken     jsonWebSecurityToken     = new JsonWebSecurityToken(text3, text4, DateTime.UtcNow, DateTime.UtcNow.AddMinutes(5.0), new List <JsonWebTokenClaim>(), x509SigningCredentials);
                OAuth2AccessTokenRequest oauth2AccessTokenRequest = OAuth2MessageFactory.CreateAccessTokenRequestWithAssertion(jsonWebSecurityToken, text5);
                OAuth2S2SClient          oauth2S2SClient          = new OAuth2S2SClient();
                try
                {
                    OAuth2AccessTokenResponse oauth2AccessTokenResponse = (OAuth2AccessTokenResponse)oauth2S2SClient.Issue(uri.AbsoluteUri, oauth2AccessTokenRequest);
                    if (oauth2AccessTokenResponse != null)
                    {
                        result = "Bearer " + oauth2AccessTokenResponse.AccessToken;
                    }
                }
                catch (RequestFailedException ex)
                {
                    ex.ToString();
                    WebException    ex2             = (WebException)ex.InnerException;
                    HttpWebResponse httpWebResponse = (HttpWebResponse)ex2.Response;
                    Stream          responseStream  = httpWebResponse.GetResponseStream();
                    Encoding        encoding        = Encoding.GetEncoding("utf-8");
                    string          text6           = "Auth service call failed: ";
                    if (responseStream != null)
                    {
                        StreamReader streamReader = new StreamReader(responseStream, encoding);
                        char[]       array        = new char[256];
                        for (int k = streamReader.Read(array, 0, 256); k > 0; k = streamReader.Read(array, 0, 256))
                        {
                            text6 += new string(array, 0, k);
                        }
                    }
                    logger.LogOneEntry(task.GetType().Name, string.Empty, ExecutionLog.EventType.Error, text6, ex);
                }
            }
            return(result);
        }
Example #18
0
        private static string IssueToken(
            string sourceApplication,
            string issuerApplication,
            string sourceRealm,
            string targetApplication,
            string targetRealm,
            string targetApplicationHostName,
            bool trustedForDelegation,
            IEnumerable <JsonWebTokenClaim> claims,
            bool appOnly          = false,
            bool addSamlClaim     = false,
            string samlClaimType  = "",
            string samlClaimValue = "")
        {
            if (null == SigningCredentials)
            {
                throw new InvalidOperationException("SigningCredentials was not initialized");
            }

            #region Actor token

            var issuer = string.IsNullOrEmpty(sourceRealm)
                ? issuerApplication
                : string.Format("{0}@{1}", issuerApplication, sourceRealm);
            var nameid = string.IsNullOrEmpty(sourceRealm)
                ? sourceApplication
                : string.Format("{0}@{1}", sourceApplication, sourceRealm);
            var audience = string.Format("{0}/{1}@{2}", targetApplication, targetApplicationHostName, targetRealm);

            var actorClaims = new List <JsonWebTokenClaim>();
            actorClaims.Add(new JsonWebTokenClaim(JsonWebTokenConstants.ReservedClaims.NameIdentifier, nameid));
            if (trustedForDelegation && !appOnly)
            {
                actorClaims.Add(new JsonWebTokenClaim(TrustedForImpersonationClaimType, "true"));
            }


            if (addSamlClaim)
            {
                actorClaims.Add(new JsonWebTokenClaim(samlClaimType, samlClaimValue));
            }

            // Create token
            var actorToken = new JsonWebSecurityToken(
                issuer,
                audience,
                DateTime.UtcNow,
                DateTime.UtcNow.AddMinutes(TokenLifetimeMinutes),
                signingCredentials: SigningCredentials,
                claims: actorClaims);

            var actorTokenString = new JsonWebSecurityTokenHandler().WriteTokenAsString(actorToken);

            if (appOnly)
            {
                return(actorTokenString);
            }

            #endregion Actor token

            #region Outer token

            var outerClaims = null == claims ? new List <JsonWebTokenClaim>() : new List <JsonWebTokenClaim>(claims);
            outerClaims.Add(new JsonWebTokenClaim(ActorTokenClaimType, actorTokenString));

            if (addSamlClaim)
            {
                outerClaims.Add(new JsonWebTokenClaim(samlClaimType, samlClaimValue));
            }

            var jsonToken = new JsonWebSecurityToken(
                nameid, // outer token issuer should match actor token nameid
                audience,
                DateTime.UtcNow,
                DateTime.UtcNow.AddMinutes(10),
                outerClaims);

            var accessToken = new JsonWebSecurityTokenHandler().WriteTokenAsString(jsonToken);

            #endregion Outer token

            return(accessToken);
        }
 public SharePointContextToken(string issuer, string audience, DateTime validFrom, DateTime validTo, IEnumerable<JsonWebTokenClaim> claims, SecurityToken issuerToken, JsonWebSecurityToken actorToken)
     : base(issuer, audience, validFrom, validTo, claims, issuerToken, actorToken)
 {
 }
Example #20
0
 public static SharePointContextToken Create(JsonWebSecurityToken contextToken)
 {
     return(new SharePointContextToken(contextToken.Issuer, contextToken.Audience, contextToken.ValidFrom, contextToken.ValidTo, contextToken.Claims));
 }