/// <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); }
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); }
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; }
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); }
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); }
/// <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); }
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); }
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 }); }
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 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; }
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); }
/// <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); } }
/// <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); }