Beispiel #1
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);
        }
        private static JsonWebSecurityTokenHandler CreateJsonWebSecurityTokenHandler(string clientSecret)
        {
            JsonWebSecurityTokenHandler handler = new JsonWebSecurityTokenHandler();

            handler.Configuration = new Microsoft.IdentityModel.Tokens.SecurityTokenHandlerConfiguration();
            handler.Configuration.AudienceRestriction  = new Microsoft.IdentityModel.Tokens.AudienceRestriction(AudienceUriMode.Never);
            handler.Configuration.CertificateValidator = X509CertificateValidator.None;

            List <byte[]> securityKeys = new List <byte[]>();

            securityKeys.Add(Convert.FromBase64String(clientSecret));

            List <SecurityToken> securityTokens = new List <SecurityToken>();

            securityTokens.Add(new MultipleSymmetricKeySecurityToken(securityKeys));

            handler.Configuration.IssuerTokenResolver =
                SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
                    new ReadOnlyCollection <SecurityToken>(securityTokens),
                    false);
            SymmetricKeyIssuerNameRegistry issuerNameRegistry = new SymmetricKeyIssuerNameRegistry();

            foreach (byte[] securitykey in securityKeys)
            {
                issuerNameRegistry.AddTrustedIssuer(securitykey, GetAcsPrincipalName(""));
            }
            handler.Configuration.IssuerNameRegistry = issuerNameRegistry;
            return(handler);
        }
Beispiel #3
0
        private JsonWebSecurityTokenHandler GetSecurityTokenHandler(string audience,
                                                                    string authMetadataEndpoint,
                                                                    X509Certificate2 currentCertificate)
        {
            JsonWebSecurityTokenHandler jsonTokenHandler = new JsonWebSecurityTokenHandler();

            jsonTokenHandler.Configuration = new Microsoft.IdentityModel.Tokens.SecurityTokenHandlerConfiguration();

            jsonTokenHandler.Configuration.AudienceRestriction = new Microsoft.IdentityModel.Tokens.AudienceRestriction(AudienceUriMode.Always);
            jsonTokenHandler.Configuration.AudienceRestriction.AllowedAudienceUris.Add(
                new Uri(audience, UriKind.RelativeOrAbsolute));

            jsonTokenHandler.Configuration.CertificateValidator = X509CertificateValidator.None;

            jsonTokenHandler.Configuration.IssuerTokenResolver =
                SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
                    new ReadOnlyCollection <SecurityToken>(new List <SecurityToken>(
                                                               new SecurityToken[]
            {
                new X509SecurityToken(currentCertificate)
            })), false);

            Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry issuerNameRegistry =
                new Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry();
            issuerNameRegistry.AddTrustedIssuer(currentCertificate.Thumbprint, Config.ExchangeApplicationIdentifier);
            jsonTokenHandler.Configuration.IssuerNameRegistry = issuerNameRegistry;

            return(jsonTokenHandler);
        }
Beispiel #4
0
        private JsonWebSecurityTokenHandler CreateJsonWebSecurityTokenHandler()
        {
            JsonWebSecurityTokenHandler handler = new JsonWebSecurityTokenHandler();

            handler.Configuration = new SecurityTokenHandlerConfiguration();
            handler.Configuration.AudienceRestriction  = new AudienceRestriction(AudienceUriMode.Never);
            handler.Configuration.CertificateValidator = X509CertificateValidator.None;

            List <byte[]> securityKeys = new List <byte[]>();

            securityKeys.Add(Convert.FromBase64String(_clientSecret));
            if (!string.IsNullOrEmpty(_secondaryClientSecret))
            {
                securityKeys.Add(Convert.FromBase64String(_secondaryClientSecret));
            }

            List <SecurityToken> securityTokens = new List <SecurityToken>();

            securityTokens.Add(new MultipleSymmetricKeySecurityToken(securityKeys));

            handler.Configuration.IssuerTokenResolver =
                SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
                    new ReadOnlyCollection <SecurityToken>(securityTokens),
                    false);
            SymmetricKeyIssuerNameRegistry issuerNameRegistry = new SymmetricKeyIssuerNameRegistry();

            foreach (byte[] securitykey in securityKeys)
            {
                issuerNameRegistry.AddTrustedIssuer(securitykey, GetAcsPrincipalName(_serviceNamespace));
            }
            handler.Configuration.IssuerNameRegistry = issuerNameRegistry;
            return(handler);
        }
        private JsonWebSecurityTokenHandler GetSecurityTokenHandler(string audience,
            string authMetadataEndpoint,
            X509Certificate2 currentCertificate)
        {
            JsonWebSecurityTokenHandler jsonTokenHandler = new JsonWebSecurityTokenHandler();
            jsonTokenHandler.Configuration = new Microsoft.IdentityModel.Tokens.SecurityTokenHandlerConfiguration();

            jsonTokenHandler.Configuration.AudienceRestriction = new Microsoft.IdentityModel.Tokens.AudienceRestriction(AudienceUriMode.Always);
            jsonTokenHandler.Configuration.AudienceRestriction.AllowedAudienceUris.Add(
              new Uri(audience, UriKind.RelativeOrAbsolute));

            jsonTokenHandler.Configuration.CertificateValidator = X509CertificateValidator.None;

            jsonTokenHandler.Configuration.IssuerTokenResolver =
              SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
                new ReadOnlyCollection<SecurityToken>(new List<SecurityToken>(
                  new SecurityToken[]
            {
              new X509SecurityToken(currentCertificate)
            })), false);

            Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry issuerNameRegistry =
                new Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry();
            issuerNameRegistry.AddTrustedIssuer(currentCertificate.Thumbprint, Config.ExchangeApplicationIdentifier);
            jsonTokenHandler.Configuration.IssuerNameRegistry = issuerNameRegistry;

            return jsonTokenHandler;
        }
Beispiel #6
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);
        }
Beispiel #7
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);
        }
Beispiel #8
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);
        }
Beispiel #9
0
        private static OAuth2AccessTokenRequest CreateAccessTokenRequestWithAssertion(System.IdentityModel.Tokens.GenericXmlSecurityToken token, string resource)
        {
            Utility.VerifyNonNullArgument("token", token);
            OAuth2AccessTokenRequest    oAuth2AccessTokenRequest    = new OAuth2AccessTokenRequest();
            JsonWebSecurityTokenHandler jsonWebSecurityTokenHandler = new JsonWebSecurityTokenHandler();

            System.Xml.XmlReader reader = new System.Xml.XmlNodeReader(token.TokenXml);
            string text;
            string jsonTokenString = jsonWebSecurityTokenHandler.GetJsonTokenString(reader, out text);

            oAuth2AccessTokenRequest.GrantType = OAuth2MessageFactory.GetTokenType(token);
            oAuth2AccessTokenRequest.Assertion = jsonTokenString;
            oAuth2AccessTokenRequest.Resource  = resource;
            return(oAuth2AccessTokenRequest);
        }
Beispiel #10
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
            });
        }
Beispiel #11
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];
                }
            }
        }
Beispiel #12
0
        private static JsonWebSecurityTokenHandler CreateJsonWebSecurityTokenHandler()
        {
            JsonWebSecurityTokenHandler handler = new JsonWebSecurityTokenHandler();

            handler.Configuration = new Microsoft.IdentityModel.Tokens.SecurityTokenHandlerConfiguration();
            handler.Configuration.AudienceRestriction  = new Microsoft.IdentityModel.Tokens.AudienceRestriction(AudienceUriMode.Never);
            handler.Configuration.CertificateValidator = X509CertificateValidator.None;

            byte[] key = Convert.FromBase64String(ClientSecret);
            handler.Configuration.IssuerTokenResolver =
                SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
                    new ReadOnlyCollection <SecurityToken>(new List <SecurityToken>(
                                                               new SecurityToken[]
            {
                new SimpleSymmetricKeySecurityToken(key)
            })),
                    false);
            SymmetricKeyIssuerNameRegistry issuerNameRegistry = new SymmetricKeyIssuerNameRegistry();

            issuerNameRegistry.AddTrustedIssuer(key, GetAcsPrincipalName(ServiceNamespace));
            handler.Configuration.IssuerNameRegistry = issuerNameRegistry;
            return(handler);
        }
        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 JsonWebSecurityTokenHandler CreateJsonWebSecurityTokenHandler()
        {
            JsonWebSecurityTokenHandler handler = new JsonWebSecurityTokenHandler();
            handler.Configuration = new SecurityTokenHandlerConfiguration();
            handler.Configuration.AudienceRestriction = new AudienceRestriction(AudienceUriMode.Never);
            handler.Configuration.CertificateValidator = X509CertificateValidator.None;

            List<byte[]> securityKeys = new List<byte[]>();
            securityKeys.Add(Convert.FromBase64String(ClientSecret));
            if (!string.IsNullOrEmpty(SecondaryClientSecret))
            {
                securityKeys.Add(Convert.FromBase64String(SecondaryClientSecret));
            }

            List<SecurityToken> securityTokens = new List<SecurityToken>();
            securityTokens.Add(new MultipleSymmetricKeySecurityToken(securityKeys));

            handler.Configuration.IssuerTokenResolver =
                SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
                new ReadOnlyCollection<SecurityToken>(securityTokens),
                false);
            SymmetricKeyIssuerNameRegistry issuerNameRegistry = new SymmetricKeyIssuerNameRegistry();
            foreach (byte[] securitykey in securityKeys)
            {
                issuerNameRegistry.AddTrustedIssuer(securitykey, GetAcsPrincipalName(ServiceNamespace));
            }
            handler.Configuration.IssuerNameRegistry = issuerNameRegistry;
            return handler;
        }
Beispiel #15
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);
        }
Beispiel #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);
            }
        }
Beispiel #17
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);
                    }
                }
            }
        }
        private static JsonWebSecurityTokenHandler CreateJsonWebSecurityTokenHandler()
        {
            JsonWebSecurityTokenHandler handler = new JsonWebSecurityTokenHandler();
            handler.Configuration = new Microsoft.IdentityModel.Tokens.SecurityTokenHandlerConfiguration();
            handler.Configuration.AudienceRestriction = new Microsoft.IdentityModel.Tokens.AudienceRestriction(AudienceUriMode.Never);
            handler.Configuration.CertificateValidator = X509CertificateValidator.None;

            byte[] key = Convert.FromBase64String(ClientSecret);
            handler.Configuration.IssuerTokenResolver =
                SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
                new ReadOnlyCollection<SecurityToken>(new List<SecurityToken>(
                    new SecurityToken[]
                            {
                                new SimpleSymmetricKeySecurityToken( key )
                            })),
                false);
            SymmetricKeyIssuerNameRegistry issuerNameRegistry = new SymmetricKeyIssuerNameRegistry();
            issuerNameRegistry.AddTrustedIssuer(key, GetAcsPrincipalName(ServiceNamespace));
            handler.Configuration.IssuerNameRegistry = issuerNameRegistry;
            return handler;
        }
        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);
        }