private string GenerateOutputToken(ClaimsRequestParameter claimsRequested, string requestClientId) { //This logic will re-issue the claims requested by Azure AD. //Insert here the specific logic for your custom providers List <Claim> claims = new List <Claim>(); foreach (var claimRequested in claimsRequested.IdToken) { string claimValue = claimRequested.Value.Value ?? claimRequested.Value.Values?.FirstOrDefault(); claims.Add(new Claim(claimRequested.Key, claimValue)); } ; //JWT audience must match the client id that was requested string audience = requestClientId; string issuer = Settings.Default.ExtensionClaimsIssuer; //TODO: Add the configuration setting in your Azure Subscription or web.config file string certWithPrivateKeyString = ConfigurationManager.AppSettings["ExtensionClaimsSigningCertificateString"]; X509Certificate2 signingCert = new X509Certificate2( Convert.FromBase64String(certWithPrivateKeyString), (string)null, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); X509SecurityKey securityKey = new X509SecurityKey(signingCert) { KeyId = Base64UrlEncoder.Encode(signingCert.GetCertHash()) }; RSACryptoServiceProvider cryptoServiceProvider = (RSACryptoServiceProvider)signingCert.PrivateKey; SigningCredentials signingCredentials = new SigningCredentials(new RsaSecurityKey(cryptoServiceProvider), SecurityAlgorithms.RsaSha256); signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.RsaSha256); JwtSecurityToken jwtToken = new JwtSecurityToken ( issuer: issuer, audience: audience, claims: claims, signingCredentials: signingCredentials, expires: DateTime.Now.AddDays(1) ); JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); string tokenString = tokenHandler.WriteToken(jwtToken); return(tokenString); }
public HttpResponseMessage Index(AuthorizeModel azureAdAuthorizeRequest) { try { //Input Syntax Validation if (azureAdAuthorizeRequest.Id_Token_Hint == null) { throw new InvalidDataException("id_token_hint is required."); } if (azureAdAuthorizeRequest.Response_Type != "id_token") { throw new InvalidDataException("Unsupported response type."); } if (azureAdAuthorizeRequest.Response_Mode != "form_post") { throw new InvalidDataException("Unsupported response mode."); } string requestClientId = azureAdAuthorizeRequest.Client_Id; //Validate the client id of the request is allowed if (!Settings.Default.AllowedExtensionClientIds.Contains(requestClientId)) { throw new InvalidDataException("Unauthorized client."); } if (!Settings.Default.AzureADAllowedRedirectUris.Contains(azureAdAuthorizeRequest.Redirect_Uri)) { throw new InvalidDataException("Unauthorized redirect uri."); } //End of input Syntax Validation //Validate and parse the original id_token_hint. We need to extract the 'sub' claim and reply it back JwtSecurityToken idTokenHint = ValidateIdTokenHint(azureAdAuthorizeRequest.Id_Token_Hint); string originalSub = idTokenHint.Claims.First(c => c.Type == "sub").Value; //Analyze the claims requested by Azure AD into the provider //In this sample, we will simply echo back exactly what Azure AD Requested. //In real examples, the provider would execute some custom logic ClaimsRequestParameter requestedControlClaims = JsonConvert.DeserializeObject <ClaimsRequestParameter>(azureAdAuthorizeRequest.Claims); if (requestedControlClaims.IdToken == null) { throw new InvalidDataException("Unsupported claims request parameter."); } //In addition to the Sub is required to be returned requestedControlClaims.IdToken.Add( "sub", new ClaimsRequestParameter.ClaimProperties() { Value = originalSub } ); //We will prepare the output here right away. If user interaction is required, return the proper redirections //to views to challenge user. NameValueCollection dataToSend = new NameValueCollection(); dataToSend.Add("state", azureAdAuthorizeRequest.State); dataToSend.Add("id_token", GenerateOutputToken(requestedControlClaims, requestClientId)); Uri redirectUri = new Uri(azureAdAuthorizeRequest.Redirect_Uri); string formPost = BuildFormPostWithDataToSend(dataToSend, redirectUri); var response = Request.CreateResponse(HttpStatusCode.OK); response.Content = new StringContent(formPost, Encoding.UTF8, "text/html"); response.Headers.Location = redirectUri; return(response); } catch (Exception e) { return(new HttpResponseMessage() { Content = new StringContent( JsonConvert.SerializeObject(e, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }), Encoding.UTF8, "application/json") }); } }