/// <summary> /// Visits <see cref="OpenApiOAuthFlow"/> and child objects /// </summary> internal void Walk(OpenApiOAuthFlow oAuthFlow) { if (oAuthFlow == null) { return; } _visitor.Visit(oAuthFlow); Walk(oAuthFlow as IOpenApiExtensible); }
private void ConfigureSwaggerGen(IServiceCollection services) { var authCodeFlow = new OpenApiOAuthFlow { AuthorizationUrl = new Uri($"{ApiHelper.Authority}/connect/authorize"), TokenUrl = new Uri($"{ApiHelper.Authority}/connect/token"), Scopes = new Dictionary <string, string> { { ApiHelper.Audience, "Api access" } } }; services.AddSwaggerGen(options => { // integrate xml comments // options.IncludeXmlComments(XmlCommentsFilePath); // Set the comments path for the Swagger JSON and UI. // var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; // var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); // c.IncludeXmlComments(xmlPath); // Define the OAuth2.0 scheme that's in use (i.e. Implicit Flow) options.OperationFilter <AuthorizeCheckOperationFilter>(); options.AddSecurityDefinition( ApiInfo.SchemeOauth2, new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2, Flows = new OpenApiOAuthFlows { AuthorizationCode = authCodeFlow } }); options.AddSecurityRequirement( new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = ApiInfo.SchemeOauth2 } }, new[] { ApiHelper.Audience } } }); }); }
public static OpenApiOAuthFlow LoadOAuthFlow(ParseNode node) { var mapNode = node.CheckMapNode("OAuthFlow"); var oauthFlow = new OpenApiOAuthFlow(); foreach (var property in mapNode) { property.ParseField(oauthFlow, _oAuthFlowFixedFileds, _oAuthFlowPatternFields); } return(oauthFlow); }
internal OpenApiOAuthFlow ToOpenApi() { var item = new OpenApiOAuthFlow() { AuthorizationUrl = string.IsNullOrEmpty(this.AuthorizationUrl) ? null : new Uri(this.AuthorizationUrl), TokenUrl = string.IsNullOrEmpty(this.TokenUrl) ? null : new Uri(this.TokenUrl), RefreshUrl = string.IsNullOrEmpty(this.RefreshUrl) ? null : new Uri(this.RefreshUrl), Scopes = this.Scopes, Extensions = this.Extensions }; return(item); }
public void Configure(SwaggerGenOptions options) { if (!env.IsDevelopment()) { return; } var authority = $"{apiOptions.Authorization.Instance}/{apiOptions.Authorization.TenantId}"; var authorizationUrl = $"{authority}/oauth2/v2.0/authorize"; var tokenUrl = $"{authority}/oauth2/v2.0/token"; var authFlow = new OpenApiOAuthFlow { TokenUrl = new Uri(tokenUrl), AuthorizationUrl = new Uri(authorizationUrl), Scopes = new Dictionary <string, string> { { $"{apiOptions.Authorization.Audience}/.default", "Default" }, }, }; options.AddSecurityDefinition( SecuritySchemeType.OAuth2.ToString(), new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2, Flows = new OpenApiOAuthFlows { Implicit = authFlow, AuthorizationCode = authFlow, }, }); options.AddSecurityRequirement( new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = SecuritySchemeType.OAuth2.ToString(), }, }, Array.Empty <string>() }, }); }
public static OpenApiSecurityScheme LoadSecurityScheme(ParseNode node) { // Reset the local variables every time this method is called. // TODO: Change _flow to a tempStorage variable to make the deserializer thread-safe. _flowValue = null; _flow = new OpenApiOAuthFlow(); var mapNode = node.CheckMapNode("securityScheme"); var securityScheme = new OpenApiSecurityScheme(); foreach (var property in mapNode) { property.ParseField(securityScheme, _securitySchemeFixedFields, _securitySchemePatternFields); } // Put the Flow object in the right Flows property based on the string in "flow" if (_flowValue == OpenApiConstants.Implicit) { securityScheme.Flows = new OpenApiOAuthFlows { Implicit = _flow }; } else if (_flowValue == OpenApiConstants.Password) { securityScheme.Flows = new OpenApiOAuthFlows { Password = _flow }; } else if (_flowValue == OpenApiConstants.Application) { securityScheme.Flows = new OpenApiOAuthFlows { ClientCredentials = _flow }; } else if (_flowValue == OpenApiConstants.AccessCode) { securityScheme.Flows = new OpenApiOAuthFlows { AuthorizationCode = _flow }; } return(securityScheme); }
public ChangedOAuthFlowBO Diff(OpenApiOAuthFlow left, OpenApiOAuthFlow right) { var changedOAuthFlow = new ChangedOAuthFlowBO(left, right); if (left != null && right != null) { changedOAuthFlow.ChangedAuthorizationUrl = left.AuthorizationUrl != right.AuthorizationUrl; changedOAuthFlow.ChangedTokenUrl = left.TokenUrl != right.TokenUrl; changedOAuthFlow.ChangedRefreshUrl = left.RefreshUrl != right.RefreshUrl; } changedOAuthFlow.Extensions = _openApiDiff .ExtensionsDiff .Diff(left?.Extensions, right?.Extensions); return(ChangedUtils.IsChanged(changedOAuthFlow)); }
public static IServiceCollection ConfigureSwagger(this IServiceCollection services, string azureAdAuthority, string azureAdClientId, string apiName) { if (apiName == null) { throw new ArgumentNullException(nameof(apiName)); } services.AddVersionedApiExplorer(options => { options.GroupNameFormat = "VVV"; // Will remove the version tags from the ApiExplorer routes. This will generate cleaner routes in Swagger docs. options.SubstituteApiVersionInUrl = true; }); services.AddOpenApiDocument(document => { document.Title = apiName; document.Description = "TODO"; document.Version = "v1"; document.DocumentName = "v1"; document.ApiGroupNames = new[] { "1" }; var authFlow = new OpenApiOAuthFlow { AuthorizationUrl = $"{azureAdAuthority}/oauth2/authorize?resource={azureAdClientId}", TokenUrl = $"{azureAdAuthority}/oauth2/token", Scopes = { { "openid", "openid" } } }; document.AddSecurity("bearer", Enumerable.Empty <string>(), new OpenApiSecurityScheme { Type = OpenApiSecuritySchemeType.OAuth2, Description = "Azure AD bearer token", Flow = OpenApiOAuth2Flow.Implicit, In = OpenApiSecurityApiKeyLocation.Header, Flows = new OpenApiOAuthFlows() { ClientCredentials = authFlow, Implicit = authFlow } }); document.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("bearer")); }); return(services); }
private static OpenApiSecurityScheme ConfigureSecurityDefinitionScheme( ApiSecurityOptions apiSecurityOptions) { OpenApiOAuthFlow authCodeFlow = new OpenApiOAuthFlow { AuthorizationUrl = new Uri($"{apiSecurityOptions.Authority}/connect/authorize"), TokenUrl = new Uri($"{apiSecurityOptions.Authority}/connect/token"), Scopes = new Dictionary <string, string> { { apiSecurityOptions.Audience, "Api access" } } }; return(new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2, Flows = new OpenApiOAuthFlows { AuthorizationCode = authCodeFlow } }); }
public void ValidateFixedFieldsIsRequiredInResponse() { // Arrange string authorizationUrlError = String.Format(SRResource.Validation_FieldIsRequired, "authorizationUrl", "OAuth Flow"); string tokenUrlError = String.Format(SRResource.Validation_FieldIsRequired, "tokenUrl", "OAuth Flow"); IEnumerable <OpenApiError> errors; OpenApiOAuthFlow oAuthFlow = new OpenApiOAuthFlow(); // Act var validator = new OpenApiValidator(); var walker = new OpenApiWalker(validator); walker.Walk(oAuthFlow); errors = validator.Errors; bool result = !errors.Any(); // Assert Assert.False(result); Assert.NotNull(errors); Assert.Equal(2, errors.Count()); Assert.Equal(new[] { authorizationUrlError, tokenUrlError }, errors.Select(e => e.Message)); }
/// <summary> /// Visits <see cref="OpenApiOAuthFlow"/> /// </summary> public virtual void Visit(OpenApiOAuthFlow openApiOAuthFlow) { }
/// <summary> /// Visits <see cref="OpenApiOAuthFlow"/> and child objects /// </summary> /// <param name="oAuthFlow"></param> internal void Walk(OpenApiOAuthFlow oAuthFlow) { _visitor.Visit(oAuthFlow); Walk(oAuthFlow as IOpenApiExtensible); }
private static FlowEntity NewFlowEntity(string name, IList <string> scopeNames, OpenApiOAuthFlow openApiOAuthFlow) { var scopes = new List <SecurityScopeEntity>(); foreach (var scopeName in scopeNames) { var flowScope = openApiOAuthFlow.Scopes.SingleOrDefault(s => s.Key.Equals(scopeName)); if (flowScope.Value != null) { var scope = new SecurityScopeEntity { Name = scopeName, Description = flowScope.Value }; scopes.Add(scope); } } return(new FlowEntity { Name = name, AuthorizationUrl = openApiOAuthFlow.AuthorizationUrl?.ToString(), TokenUrl = openApiOAuthFlow.TokenUrl?.ToString(), Scopes = scopes }); }
private static OpenApiOAuthFlow ToOAuthFlow(this XElement element, string flowType, out IList <string> scopeNames) { var oAuthFlow = new OpenApiOAuthFlow(); scopeNames = new List <string>(); var authorizationUrl = element.Elements() .FirstOrDefault(p => p.Name == KnownXmlStrings.AuthorizationUrl)?.Value; var refreshUrl = element.Elements() .FirstOrDefault(p => p.Name == KnownXmlStrings.RefreshUrl)?.Value; var tokenUrl = element.Elements() .FirstOrDefault(p => p.Name == KnownXmlStrings.TokenUrl)?.Value; if (flowType == KnownXmlStrings.ImplicitFlow || flowType == KnownXmlStrings.AuthorizationCode) { if (authorizationUrl == null) { throw new InvalidSecurityTagException(string.Format( SpecificationGenerationMessages.UndocumentedAuthorizationUrl, flowType)); } oAuthFlow.AuthorizationUrl = new Uri(authorizationUrl); } if (flowType == KnownXmlStrings.Password || flowType == KnownXmlStrings.AuthorizationCode || flowType == KnownXmlStrings.ClientCredentials) { if (tokenUrl == null) { throw new InvalidSecurityTagException(string.Format( SpecificationGenerationMessages.UndocumentedTokenUrl, flowType)); } oAuthFlow.TokenUrl = new Uri(tokenUrl); } if (refreshUrl != null) { oAuthFlow.RefreshUrl = new Uri(refreshUrl); } var scopeElements = element.Elements() .Where(p => p.Name == KnownXmlStrings.Scope); if (!scopeElements.Any()) { throw new InvalidSecurityTagException(string.Format( SpecificationGenerationMessages.UndocumentedScopeForFlow, flowType)); } foreach (var scopeElement in scopeElements) { var name = scopeElement.Attribute(KnownXmlStrings.Name)?.Value; if (string.IsNullOrWhiteSpace(name)) { throw new InvalidSecurityTagException(string.Format( SpecificationGenerationMessages.UndocumentedName, KnownXmlStrings.Scope)); } var description = scopeElement.Elements().FirstOrDefault(p => p.Name == KnownXmlStrings.Description) ?.Value; if (string.IsNullOrWhiteSpace(description)) { throw new InvalidSecurityTagException(string.Format( SpecificationGenerationMessages.UndocumentedDescription, KnownXmlStrings.Scope)); } scopeNames.Add(name); oAuthFlow.Scopes.Add(name, description); } return(oAuthFlow); }
/// <summary> /// Execute validation rules against an <see cref="OpenApiOAuthFlow"/> /// </summary> /// <param name="item">The object to be validated</param> public override void Visit(OpenApiOAuthFlow item) => Validate(item);
public override void Visit(OpenApiOAuthFlow openApiOAuthFlow) { EncodeCall(); base.Visit(openApiOAuthFlow); }
public ChangedOAuthFlowBO(OpenApiOAuthFlow oldOAuthFlow, OpenApiOAuthFlow newOAuthFlow) { OldOAuthFlow = oldOAuthFlow; NewOAuthFlow = newOAuthFlow; }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddApplication(); services.AddInfrastructure(Configuration); services.AddHealthChecks() .AddDbContextCheck <ToDoDbContext>(); services.AddHttpContextAccessor(); // Customise default API behavour services.Configure <ApiBehaviorOptions>(options => { options.SuppressModelStateInvalidFilter = true; }); services.AddHttpContextAccessor(); services.AddScoped <ICurrentUserService, CurrentUserService>(); services .AddControllersWithViews() .AddNewtonsoftJson() .AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining <IToDoDbContext>()); services.AddRazorPages(); string authorizationUrl = "https://appdatadev.b2clogin.com/appdatadev.onmicrosoft.com/B2C_1_signupsignin/oauth2/v2.0/authorize"; string tokenUrl = "https://appdatadev.b2clogin.com/appdatadev.onmicrosoft.com/B2C_1_signupsignin/oauth2/v2.0/token"; var scopes = new Dictionary <string, string> { { "https://appdatadev.onmicrosoft.com/todo/ReadAll", "Read All" }, { "offline_access", "offline_access" }, { "email", "email" } }; var swaggerOAuthCodeFlow = new OpenApiOAuthFlow() { AuthorizationUrl = authorizationUrl, TokenUrl = tokenUrl, RefreshUrl = tokenUrl, Scopes = scopes }; var swaggerOAuthImplicitFlow = new OpenApiOAuthFlow() { AuthorizationUrl = authorizationUrl, RefreshUrl = tokenUrl, // TokenUrl = tokenUrl, Scopes = scopes }; var swaggerSecurityCode = new OpenApiSecurityScheme() { Flows = new OpenApiOAuthFlows() { AuthorizationCode = swaggerOAuthCodeFlow, // Implicit = swaggerOAuthFlow }, Type = OpenApiSecuritySchemeType.OAuth2, }; var swaggerSecurityImplicit = new OpenApiSecurityScheme() { Flows = new OpenApiOAuthFlows() { //AuthorizationCode = swaggerOAuthFlow, Implicit = swaggerOAuthImplicitFlow }, Type = OpenApiSecuritySchemeType.OAuth2, }; services.AddSwaggerDocument(o => { o.PostProcess = s => { s.Host = Configuration["SwaggerHost"]; s.BasePath = "/"; s.Schemes = new List <OpenApiSchema>() { OpenApiSchema.Https }; s.SecurityDefinitions.Add("oauth2code", swaggerSecurityCode); s.SecurityDefinitions.Add("oauth2implicit", swaggerSecurityImplicit); // s.SecurityDefinitions.Add("test",test); }; o.Title = "ToDo App"; o.Description = "Yes...Another Todo App"; o.SchemaType = SchemaType.Swagger2; o.OperationProcessors.Add(new OperationSecurityScopeProcessor("oauth2code")); o.OperationProcessors.Add(new OperationSecurityScopeProcessor("oauth2implicit")); // o.OperationProcessors.Add(new OperationSecurityScopeProcessor("test")); //o.DocumentProcessors.Add(new SecurityDefinitionAppender("oauth2",swaggerSecurity)); } ); //services.AddTransient<IPrincipal>( // provider => provider.GetService<IHttpContextAccessor>().HttpContext?.User); // configure strongly typed settings objects var appSettingsSection = Configuration.GetSection("AuthenticationOptions"); services.Configure <AuthenticationOptions>(appSettingsSection); // configure jwt authentication var authenticationOptions = appSettingsSection.Get <AuthenticationOptions>(); services.AddAuthentication(o => o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(o => { o.Authority = authenticationOptions.Authority; o.Audience = authenticationOptions.Audience; o.TokenValidationParameters.ValidateAudience = false; o.TokenValidationParameters.ValidateIssuer = false; }); services.AddAuthorization(o => { o.AddPolicy("ReadAll", new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build()); }); _services = services; }