380 lines
17 KiB
C#
380 lines
17 KiB
C#
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<int>(0);
|
|
// },
|
|
|
|
// OnApplyChallenge = c1 =>
|
|
// {
|
|
// return Task.FromResult<object>(null);
|
|
// },
|
|
|
|
// OnValidateIdentity = context =>
|
|
// {
|
|
// context.Ticket.Identity.AddClaim(new System.Security.Claims.Claim("newCustomClaim", "newValue"));
|
|
// return Task.FromResult<object>(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<string, string>();
|
|
|
|
//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<string>("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<IsAdminOrPMeRequirement>
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
} |