using Autofac; using Autofac.Integration.Mvc; using Autofac.Integration.WebApi; using IdentityServer3.AccessTokenValidation; using Microsoft.Owin; using Owin; using Microsoft.Owin.Security.Authorization.Infrastructure; using System.IdentityModel.Claims; using System.Configuration; using System.Web.Http; using System.Web.Mvc; using webapi.Helpers; using Microsoft.Owin.Security.Authorization; using System.Threading.Tasks; using System.Linq; [assembly: OwinStartup(typeof(webapi.Startup))] namespace webapi { public class Startup { // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864 public void Configuration(IAppBuilder app) { // Autofac config var config = new HttpConfiguration(); var builder = new ContainerBuilder(); WebApiConfig.Register(config); AutofacConfig.Register(builder); LoggerConfig.Register(builder); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); //Set the MVC DependencyResolver //config.DependencyResolver = new AutofacWebApiDependencyResolver(container); GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver((IContainer)container); //Set the WebApi DependencyResolver config.EnsureInitialized(); // require authentication for all controllers config.Filters.Add(new System.Web.Http.AuthorizeAttribute()); ConfigureJwtBearerAuth(app); // Register the Autofac middleware FIRST, then the Autofac MVC middleware. app.UseAutofacMiddleware(container); app.UseAutofacMvc(); app.UseAutofacWebApi(config); app.RegisterCors(ConfigurationManager.AppSettings[Constants.CORS_ORIGINS]); // app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); app.UseSerilogHttpRequestLogging(); app.UseWebApi(config); } private void ConfigureJwtBearerAuth(IAppBuilder app) { //app.UseOAuthBearerAuthentication(config => //{ // config.AuthenticationScheme = "Bearer"; // config.AutomaticAuthentication = true; //}); //var issuer = ConfigurationManager.AppSettings[Constants.JWT_IDENTITY_SERVER]; //var audience = "api"; // "099153c2625149bc8ecb3e85e03f0022"; //var secret = TextEncodings.Base64Url.Decode("YXBpc2VjcmV0"); //apisecret")); // "IxrAjDoa2FqElO7IhrSrUJELhUckePEPVpaePlS_Xaw"); // options.Configuration = new Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration() // { // Issuer = "https://tv.domain.com/trust/domain" // }; // app.UseJwtBearerAuthentication( // new JwtBearerAuthenticationOptions // { // AutomaticAuthenticate = true; // AutomaticChallenge = true; // // You also need to update /wwwroot/app/scripts/app.js // options.Authority = Configuration["jwt:authority"]; // options.Audience = Configuration["jwt:audience"]; //} // }); // Api controllers with an [Authorize] attribute will be validated with JWT //app.UseJwtBearerAuthentication( // new JwtBearerAuthenticationOptions // { // //AuthenticationMode = AuthenticationMode.Active, // //AllowedAudiences = new[] { audience }, // TokenValidationParameters = new TokenValidationParameters() // { // ValidAudience = "api", //ConfigurationManager.AppSettings[Constants.JWT_AUDIENCE], // ValidIssuer = ConfigurationManager.AppSettings[Constants.JWT_ISSUER], // //IssuerSigningKey = new SymmetricSecurityKey(secret) , //ConfigurationManager.AppSettings[Constants.JWT_AUDIENCE].ConfigHelper.GetSymmetricSecurityKey(), // ValidateLifetime = false, // //ValidateAudience = false, // ValidateIssuerSigningKey = false, // //SignatureValidator = (token, e) => // //{ // // return new SecurityToken(); // //} // }, // //IssuerSecurityKeyProviders = new IIssuerSecurityKeyProvider[] // //{ // // new SymmetricKeyIssuerSecurityKeyProvider(issuer, secret) // //}, // Provider = new OAuthBearerAuthenticationProvider // { // OnRequestToken = (OAuthRequestTokenContext context) => // { // var idContext = new OAuthValidateIdentityContext(context.OwinContext, null, null); // //this.ValidateIdentity(idContext); // return Task.FromResult(0); // }, // OnApplyChallenge = c1 => // { // return Task.FromResult(null); // }, // OnValidateIdentity = context => // { // context.Ticket.Identity.AddClaim(new System.Security.Claims.Claim("newCustomClaim", "newValue")); // return Task.FromResult(null); // } // } // }); //app.UseJwtBearerAuthentication( // new JwtBearerAuthenticationOptions // { // AllowedAudiences = new[] { ConfigurationManager.AppSettings[Constants.JWT_IDENTITY_SERVER] }, // AuthenticationMode = AuthenticationMode.Active, // //TokenHandler = ()=>{ // //}, // TokenValidationParameters = new TokenValidationParameters() // { // //ValidAudience = ConfigurationManager.AppSettings[Constants.JWT_AUDIENCE], // //ValidIssuer = ConfigurationManager.AppSettings[Constants.JWT_ISSUER], // //IssuerSigningKey = ConfigurationManager.AppSettings[Constants.JWT_AUDIENCE].ConfigHelper.GetSymmetricSecurityKey(), // ValidateLifetime = false, // ValidateAudience = false, // //ValidateIssuerSigningKey = false, // //SignatureValidator = (token, e) => // //{ // // return new SecurityToken(); // //} // } // }); //app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions //{ // AuthenticationMode = AuthenticationMode.Active, // TokenValidationParameters = new TokenValidationParameters // { // AuthenticationType = "Bearer", // ValidIssuer = ConfigurationManager.AppSettings[Constants.JWT_AUDIENCE] ,//"https://validissuer.blahblah.com/", // ValidAudience = ConfigurationManager.AppSettings[Constants.JWT_AUDIENCE], // //IssuerSigningKey = new InMemorySymmetricSecurityKey(Encoding.UTF8.GetBytes("MySecret")), // ValidateIssuerSigningKey = false, // } //}); //var options = new IdentityServerBearerTokenAuthenticationOptions //{ // Authority = https://www.test.domain/identity, // AuthenticationType = "Bearer", // RequiredScopes = new[] { "DataAPI" } //}; //app.UseIdentityServerBearerTokenAuthentication(options); //JwtSecurityTokenHandler.InboundClaimTypeMap.Clear(); //app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions() //{ // Authority = "https://demo.identityserver.io", // ClientId = "api", // ClientSecret = "secret", // RequiredScopes = new[] { "api" }, // ValidationMode = ValidationMode.ValidationEndpoint ////}); //JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary(); //app.UseCookieAuthentication(new CookieAuthenticationOptions //{ // AuthenticationType = "Cookies" //}); //JwtSecurityTokenHandler.InboundClaimTypeMap.Clear(); // accept access tokens from identityserver and require a scope of 'api1' app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions { //Authority = "http://win-jphfo4kpi87:5000", Authority = ConfigurationManager.AppSettings[Constants.JWT_IDENTITY_SERVER], ValidationMode = ValidationMode.Both, //RequiredScopes = new[] { ConfigurationManager.AppSettings[Constants.JWT_AUDIENCE] } //"api1" } }); app.UseAuthorization(options => { //If IsAdmin = true, IsPropertyManager flag may be ignored options.AddPolicy("IsAdmin", policy => policy.RequireClaim("isAdmin", true.ToString())); //If IsAmin = false and IsPropertyManager = true options.AddPolicy("IsPropertyManager", policy => policy.RequireClaim("isAdmin", false.ToString()) .RequireClaim("isPropertyManager", true.ToString())); options.AddPolicy("IsPropertyManagerOrAdmin", policy => policy.Requirements.Add(new IsAdminOrPMeRequirement())); options.Dependencies = AuthorizationDependencies.Create(options, new IsAdminOrPMHandler()); }); // configure web api //var config = new HttpConfiguration(); //config.MapHttpAttributeRoutes(); //app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions //{ // Authority = "http://localhost:5000", // ValidationMode = ValidationMode.ValidationEndpoint, // RequiredScopes = new[] { "api1" } //}); //app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions //{ // ClientId = "service.client", // Authority = "http://win-jphfo4kpi87:5000", //"http://localhost:5010/", // //RedirectUri = "https://localhost:44300/", // //PostLogoutRedirectUri = "https://localhost:44300/", // //ResponseType = "code id_token client_credentials", // //Scope = "openid profile read write offline_access api", // Scope = "api", // RequireHttpsMetadata = false, // //TokenValidationParameters = new TokenValidationParameters // //{ // // NameClaimType = "name", // // RoleClaimType = "role" // //}, // TokenValidationParameters = new TokenValidationParameters // { // RequireSignedTokens = false, //true, // //IssuerSigningKey = new X509SecurityKey(cert), // //ValidAudience = "katanaclient", // //ValidIssuer = "identityserver", // }, // SignInAsAuthenticationType = "Cookies", // Notifications = new OpenIdConnectAuthenticationNotifications // { // AuthenticationFailed = async n => // { // await Task.FromResult(0); // }, // MessageReceived = async m => { // await Task.FromResult(0); // }, // AuthorizationCodeReceived = async n => // { // //// use the code to get the access and refresh token // //var tokenClient = new TokenClient( // // Constants.TokenEndpoint, // // "mvc.owin.hybrid", // // "secret"); // //var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync( // // n.Code, n.RedirectUri); // //if (tokenResponse.IsError) // //{ // // throw new Exception(tokenResponse.Error); // //} // //// use the access token to retrieve claims from userinfo // //var userInfoClient = new UserInfoClient( // //new Uri(Constants.UserInfoEndpoint), // //tokenResponse.AccessToken); // //var userInfoResponse = await userInfoClient.GetAsync(); // //// create new identity // //var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType); // //id.AddClaims(userInfoResponse.GetClaimsIdentity().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("refresh_token", tokenResponse.RefreshToken)); // //id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); // //id.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity.FindFirst("sid").Value)); // //n.AuthenticationTicket = new AuthenticationTicket( // // new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType, "name", "role"), // // n.AuthenticationTicket.Properties); // await Task.CompletedTask; // }, // 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; // } // } // if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication) // { // var otac = n.OwinContext.Get("otac"); // if (otac != null) // { // n.ProtocolMessage.AcrValues = otac; // } // n.ProtocolMessage.ClientSecret = "apisecret"; // n.ProtocolMessage.ClientId = "service.client"; // n.ProtocolMessage.GrantType = "client_credentials"; // n.ProtocolMessage.Scope ="api"; // } // return Task.FromResult(0); // } // } //}); } } public class IsAdminOrPMeRequirement : IAuthorizationRequirement { //public MinimumAgeRequirement(int age) //{ // MinimumAge = age; //} //protected int MinimumAge { get; set; } } public class IsAdminOrPMHandler : AuthorizationHandler { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IsAdminOrPMeRequirement requirement) { if (!context.User.HasClaim(c => c.Type == Constants.CLAIM_IS_ADMIN || c.Type == Constants.CLAIM_IS_PM)) { return Task.FromResult(0); } var isAdmin = context.User.Claims?.FirstOrDefault(x => Constants.CLAIM_IS_ADMIN.Equals(x.Type))?.Value; var isPM = context.User.Claims?.FirstOrDefault(x => Constants.CLAIM_IS_PM.Equals(x.Type))?.Value; if (true.ToString().Equals(isAdmin) || true.ToString().Equals(isPM)) { context.Succeed(requirement); } return Task.FromResult(0); } } }