/// <summary> /// Creates header value for insufficient claims. /// </summary> /// <param name="authenticationConfig"></param> /// <param name="claims"></param> /// <param name="scopes"></param> /// <returns></returns> internal static string CreateResponseHeader(AuthenticationConfig authenticationConfig, string claims, IEnumerable <string> scopes = null) { string authorization_uri = $"{authenticationConfig.Authority}/oauth2/v2.0/authorize"; IDictionary <string, string> parameters = new Dictionary <string, string>() { { Constants.Realm, "" }, { Constants.AuthorizationUri, authorization_uri }, { Constants.Claims, claims }, { Constants.Scopes, string.Join(",", scopes != null? string.Join("%20", scopes):"") }, { Constants.Error, Constants.InsufficientClaims }, }; string parameterString = string.Join("; ", parameters.Select(p => $"{p.Key}=\"{p.Value}\"")); return(parameterString); }
/// <summary> /// Checks if the access token has acrs claim with acrsValue. /// If does not exists then adds WWW-Authenticate and throws UnauthorizedAccessException exception. /// </summary> /// <param name="acrsValue"></param> /// <param name="httpResponse"></param> public static void EnsureUserHasAuthenticationContextClassReference(string acrsValue, string additionalInfo = null) { AuthenticationConfig authenticationConfig = new AuthenticationConfig(); HttpContext context = HttpContext.Current; ClaimsPrincipal claimsPrincipal = ClaimsPrincipal.Current; string authenticationContextClassReferencesClaim = "acrs"; if (context == null || context.User == null || claimsPrincipal.Claims == null || !claimsPrincipal.Claims.Any()) { throw new ArgumentNullException("No Usercontext is available to pick claims from"); } Claim acrsClaim = claimsPrincipal.FindFirst(authenticationContextClassReferencesClaim); if (acrsClaim == null || acrsClaim.Value != acrsValue) { context.Response.StatusCode = (int)HttpStatusCode.Forbidden; //string message = string.Format(CultureInfo.InvariantCulture, "The presented access tokens had insufficient claims. Please request for claims requested in the WWW-Authentication header and try again."); var base64str = Convert.ToBase64String(Encoding.UTF8.GetBytes("{\"access_token\":{\"acrs\":{\"essential\":true,\"value\":\"" + acrsValue + "\"}}}")); // Create response header as per https://tools.ietf.org/html/rfc6750#section-3.1 var authenticateHeader = CommonUtil.CreateResponseHeader(authenticationConfig, base64str); context.Response.Headers.Add("WWW-Authenticate", authenticateHeader); string message = $"The claim 'acrs' is either missing or does not have the value(s) '{acrsValue}'.Please redirect the user to the authorization server for additional processing."; // Create response content with error details. InsufficientClaimsResponse insufficientClaimsResponse = CommonUtil.CreateErrorResponseMessage(message, additionalInfo); if (insufficientClaimsResponse != null) { context.Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(insufficientClaimsResponse)); } context.Response.End(); throw new UnauthorizedAccessException(message); } }
public TokenAcquisition(AuthenticationConfig authConfig, CacheType cacheType = CacheType.InMemoryCache) { this.AuthenticationConfig = authConfig; }
public static void EnableTokenAcquisitionToCallDownstreamApi(this IAppBuilder app, AuthenticationConfig authenticationConfig, IEnumerable <string> initialScopes = null, CacheType cacheType = CacheType.InMemoryCache) { ApplicationBuilders applicationBuilders = new ApplicationBuilders(cacheType); app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { ClientId = authenticationConfig.ClientId, Authority = authenticationConfig.Authority, PostLogoutRedirectUri = authenticationConfig.PostLogoutRedirectUri, RedirectUri = authenticationConfig.RedirectUri, TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, NameClaimType = IdentityConstants.PreferredUserName }, ResponseType = "code", Scope = $"{IdentityConstants.DefaultScopes} {string.Join(" ", initialScopes)}", Notifications = new OpenIdConnectAuthenticationNotifications() { AuthorizationCodeReceived = async context => { // Call MSAL.NET AcquireTokenByAuthorizationCode and cache the token in Token Cache var application = applicationBuilders.BuildConfidentialClientApplication(authenticationConfig); var result = await application.AcquireTokenByAuthorizationCode(initialScopes, context.ProtocolMessage.Code) .ExecuteAsync(); context.HandleCodeRedemption(null, result.IdToken); }, AuthenticationFailed = arg => { arg.HandleResponse(); arg.Response.Redirect("/?errormessage=" + arg.Exception.Message); return(Task.FromResult(0)); }, RedirectToIdentityProvider = OnRedirectToIdentityProvider } }); }
/// <summary> /// Configures the web application to just sign-in a user and get an id_token /// </summary> /// <param name="app"></param> /// <param name="authenticationConfig"></param> public static void AddMicrosoftIdentityWebAppAuthentication(this IAppBuilder app, AuthenticationConfig authenticationConfig) { app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { ClientId = authenticationConfig.ClientId, Authority = authenticationConfig.Authority, PostLogoutRedirectUri = authenticationConfig.PostLogoutRedirectUri, RedirectUri = authenticationConfig.RedirectUri, Scope = IdentityConstants.DefaultScopes, ResponseType = "id_token", TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, NameClaimType = IdentityConstants.PreferredUserName }, }); }