Untitled
unknown
plain_text
3 years ago
14 kB
6
Indexable
using System;
using System.Configuration;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Helpers;
using Abp.Extensions;
using Abp.Owin;
using Hangfire;
using IdentityModel;
using IdentityModel.Client;
using Microsoft.AspNet.Identity;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Facebook;
using Microsoft.Owin.Security.Google;
using Microsoft.Owin.Security.Notifications;
using Microsoft.Owin.Security.OpenIdConnect;
using Microsoft.Owin.Security.Twitter;
using Nascence.BodynitsPortal.Web;
using Nascence.BodynitsPortal.WebApi.Controllers;
using NLog;
using Owin;
[assembly: OwinStartup(typeof(Startup))]
namespace Nascence.BodynitsPortal.Web
{
public class Startup
{
private static Logger _logger = LogManager.GetCurrentClassLogger();
public void Configuration(IAppBuilder app)
{
app.UseAbp();
app.UseOAuthBearerAuthentication(AccountController.OAuthBearerOptions);
app.UseKentorOwinCookieSaver();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login")
});
//app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
//if (IsTrue("ExternalAuth.Facebook.IsEnabled"))
//{
// app.UseFacebookAuthentication(CreateFacebookAuthOptions());
//}
//if (IsTrue("ExternalAuth.Twitter.IsEnabled"))
//{
// app.UseTwitterAuthentication(CreateTwitterAuthOptions());
//}
//if (IsTrue("ExternalAuth.Google.IsEnabled"))
//{
// app.UseGoogleAuthentication(CreateGoogleAuthOptions());
//}
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
if (IsTrue("ExternalAuth.OpenId.IsEnabled"))
{
app.UseOpenIdConnectAuthentication(CreateOpenIdOptions());
}
app.MapSignalR();
//Enable it to use HangFire dashboard (uncomment only if it's enabled in BodynitsPortalWebModule)
//app.UseHangfireDashboard();
}
private static OpenIdConnectAuthenticationOptions CreateOpenIdOptions()
{
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
var options = new OpenIdConnectAuthenticationOptions
{
Authority = AppHelper.IdentityHelper.OpenIdAuthority,
ClientId = AppHelper.IdentityHelper.OpenIdClientId,
PostLogoutRedirectUri = AppHelper.IdentityHelper.OpenIdPostLogoutRedirectUri,
RedirectUri = AppHelper.IdentityHelper.OpenIdRedirectUri,
RequireHttpsMetadata = false,
SignInAsAuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
UseTokenLifetime = false,
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = (n) =>
{
// if signing out, add the id_token_hint
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
{
var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
}
else if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
{
var tenancyName = "DEF";
if (tenancyName != null)
{
//n.ProtocolMessage.Parameters.Add("tenancy_name", tenancyName.Last());
n.ProtocolMessage.Parameters.Add("tenancy_name", tenancyName);
HttpCookie tenancyNameCookie = new HttpCookie("tenancyNameCookie");
//tenancyNameCookie["tenancy_name"] = tenancyName.Last();
tenancyNameCookie["tenancy_name"] = tenancyName;
var response = HttpContext.Current.Response;
response.Cookies.Add(tenancyNameCookie);
}
// set PKCE parameters
var codeVerifier = CryptoRandom.CreateUniqueId(32);
string codeChallenge;
using (var sha256 = SHA256.Create())
{
var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
codeChallenge = Base64Url.Encode(challengeBytes);
}
n.ProtocolMessage.SetParameter("code_challenge", codeChallenge);
n.ProtocolMessage.SetParameter("code_challenge_method", "S256");
// remember code_verifier (adapted from OWIN nonce cookie)
RememberCodeVerifier(n, codeVerifier);
}
return Task.FromResult(0);
},
AuthenticationFailed = (n) =>
{
try
{
_logger.Info("Authentication Failed");
_logger.Info(n.Exception);
_logger.Info(n.Response?.StatusCode);
_logger.Info(n.Response?.ReasonPhrase);
n.HandleResponse();
n.Response.Redirect("/Application/Index");
return Task.FromResult(0);
}
catch (Exception ex)
{
throw ex;
};
},
AuthorizationCodeReceived = async n =>
{
var client = new HttpClient();
// get code_verifier
var codeVerifier = RetrieveCodeVerifier(n);
// attach code_verifier
n.TokenEndpointRequest.SetParameter("code_verifier", codeVerifier);
var tokenResponse = await client.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest()
{
Address = AppHelper.IdentityHelper.OpenIdTokenEndpoint,
ClientId = AppHelper.IdentityHelper.OpenIdClientId,
ClientSecret = AppHelper.IdentityHelper.OpenIdClientSecret,
Code = n.Code,
RedirectUri = n.RedirectUri,
CodeVerifier = codeVerifier,
});
if (tokenResponse.IsError)
{
throw new Exception(tokenResponse.Error);
}
var userInfoResponse = await client.GetUserInfoAsync(new UserInfoRequest()
{
Address = AppHelper.IdentityHelper.OpenIdUserInfoEndpoint,
Token = tokenResponse.AccessToken,
});
// create new identity
var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
id.AddClaims(userInfoResponse.Claims);
id.AddClaim(new Claim("access_token", tokenResponse.AccessToken));
id.AddClaim(new Claim("expires_at", DateTime.Now.AddSeconds(tokenResponse.ExpiresIn).ToLocalTime().ToString()));
id.AddClaim(new Claim("iss", n.AuthenticationTicket.Identity.FindFirst("iss").Value));
id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
id.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity.FindFirst("sid").Value));
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, userInfoResponse.Claims.FirstOrDefault(x => x.Type == "preferred_username").Value));
n.AuthenticationTicket = new AuthenticationTicket(
new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType, ClaimTypes.NameIdentifier, "role"),
n.AuthenticationTicket.Properties);
}
}
};
var clientSecret = ConfigurationManager.AppSettings["ExternalAuth.OpenId.ClientSecret"];
if (!clientSecret.IsNullOrEmpty())
{
options.ClientSecret = clientSecret;
}
return options;
}
private static void RememberCodeVerifier(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> n, string codeVerifier)
{
var properties = new AuthenticationProperties();
properties.Dictionary.Add("cv", codeVerifier);
n.Options.CookieManager.AppendResponseCookie(
n.OwinContext,
GetCodeVerifierKey(n.ProtocolMessage.State),
Convert.ToBase64String(Encoding.UTF8.GetBytes(n.Options.StateDataFormat.Protect(properties))),
new CookieOptions
{
SameSite = SameSiteMode.None,
HttpOnly = true,
Secure = n.Request.IsSecure,
Expires = DateTime.UtcNow + n.Options.ProtocolValidator.NonceLifetime
});
}
private static string RetrieveCodeVerifier(AuthorizationCodeReceivedNotification n)
{
string key = GetCodeVerifierKey(n.ProtocolMessage.State);
string codeVerifierCookie = n.Options.CookieManager.GetRequestCookie(n.OwinContext, key);
if (codeVerifierCookie != null)
{
var cookieOptions = new CookieOptions
{
SameSite = SameSiteMode.None,
HttpOnly = true,
Secure = n.Request.IsSecure
};
n.Options.CookieManager.DeleteCookie(n.OwinContext, "cv", cookieOptions);
}
var cookieProperties = n.Options.StateDataFormat.Unprotect(Encoding.UTF8.GetString(Convert.FromBase64String(codeVerifierCookie)));
cookieProperties.Dictionary.TryGetValue("cv", out var codeVerifier);
return codeVerifier;
}
private static string GetCodeVerifierKey(string state)
{
using (var hash = SHA256.Create())
{
return OpenIdConnectAuthenticationDefaults.CookiePrefix + "cv." + Convert.ToBase64String(hash.ComputeHash(Encoding.UTF8.GetBytes(state)));
}
}
private static FacebookAuthenticationOptions CreateFacebookAuthOptions()
{
var options = new FacebookAuthenticationOptions
{
AppId = ConfigurationManager.AppSettings["ExternalAuth.Facebook.AppId"],
AppSecret = ConfigurationManager.AppSettings["ExternalAuth.Facebook.AppSecret"]
};
options.Scope.Add("email");
options.Scope.Add("public_profile");
return options;
}
private static TwitterAuthenticationOptions CreateTwitterAuthOptions()
{
return new TwitterAuthenticationOptions
{
ConsumerKey = ConfigurationManager.AppSettings["ExternalAuth.Twitter.ConsumerKey"],
ConsumerSecret = ConfigurationManager.AppSettings["ExternalAuth.Twitter.ConsumerSecret"]
};
}
private static GoogleOAuth2AuthenticationOptions CreateGoogleAuthOptions()
{
return new GoogleOAuth2AuthenticationOptions
{
ClientId = ConfigurationManager.AppSettings["ExternalAuth.Google.ClientId"],
ClientSecret = ConfigurationManager.AppSettings["ExternalAuth.Google.ClientSecret"]
};
}
private static bool IsTrue(string appSettingName)
{
return string.Equals(
ConfigurationManager.AppSettings[appSettingName],
"true",
StringComparison.InvariantCultureIgnoreCase);
}
}
}Editor is loading...