C# 使用Swagger在ASP.NET内核中实现OAuth
我想在我的web应用程序中实现OAuth,为此,我在我的C# 使用Swagger在ASP.NET内核中实现OAuth,c#,.net-core,oauth-2.0,swagger,swashbuckle.aspnetcore,C#,.net Core,Oauth 2.0,Swagger,Swashbuckle.aspnetcore,我想在我的web应用程序中实现OAuth,为此,我在我的startup.cs public static IServiceCollection AddSwaggerDocumentation(this IServiceCollection services) { services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Open
startup.cs
public static IServiceCollection AddSwaggerDocumentation(this IServiceCollection services)
{
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "CombiTime API v1.0", Version = "v1" });
c.AddSecurityDefinition("OAuth2", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri("http://localhost:4200/login"),
TokenUrl = new Uri("http://localhost:4200/connect/token")
}
}
});
c.OperationFilter<AuthorizeOperationFilter>();
c.AddSecurityRequirement(new OpenApiSecurityRequirement{
{
new OpenApiSecurityScheme{
Reference = new OpenApiReference{
Id = "Bearer", //The name of the previously defined security scheme.
Type = ReferenceType.SecurityScheme
}
},new List<string>()
}
});
});
return services;
}
public static IApplicationBuilder UseSwaggerDocumentation(this IApplicationBuilder app)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Versioned API v1.0");
c.DocumentTitle = "Title Documentation";
c.DocExpansion(DocExpansion.None);
c.RoutePrefix = string.Empty;
c.OAuthClientId("combitimeapi_swagger");
c.OAuthAppName("Combitime API");
c.OAuthUsePkce();
});
return app;
}
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
通过使用这段代码,我在我的招摇过市用户界面上得到了一个“授权”按钮,当我点击该按钮时,我将重定向到我的登录页面(前端基于角度)。因此,我将我的授权URL
作为http://localhost:4200/login
当我被重定向到登录页面时,我使用有效的凭证登录,我使用jwt令牌登录,为此我在我的startup.cs中添加了以下代码
public static IServiceCollection AddSwaggerDocumentation(this IServiceCollection services)
{
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "CombiTime API v1.0", Version = "v1" });
c.AddSecurityDefinition("OAuth2", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri("http://localhost:4200/login"),
TokenUrl = new Uri("http://localhost:4200/connect/token")
}
}
});
c.OperationFilter<AuthorizeOperationFilter>();
c.AddSecurityRequirement(new OpenApiSecurityRequirement{
{
new OpenApiSecurityScheme{
Reference = new OpenApiReference{
Id = "Bearer", //The name of the previously defined security scheme.
Type = ReferenceType.SecurityScheme
}
},new List<string>()
}
});
});
return services;
}
public static IApplicationBuilder UseSwaggerDocumentation(this IApplicationBuilder app)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Versioned API v1.0");
c.DocumentTitle = "Title Documentation";
c.DocExpansion(DocExpansion.None);
c.RoutePrefix = string.Empty;
c.OAuthClientId("combitimeapi_swagger");
c.OAuthAppName("Combitime API");
c.OAuthUsePkce();
});
return app;
}
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
我想在使用有效凭据登录后重定向回swagger UI,但问题是,我在登录后被重定向到仪表板。请帮助我或让我知道我做错了什么
从swagger重定向到登录页面后形成的url为:
http://localhost:4200/login?response_type=code&client_id=combitimeapi_swagger&redirect_uri=http:%2F%2Flocalhost:61574%2Foauth2-redirect.html&state=V2VkIEZlYiAxNyAyMDIxIDIyOjU3OjQ2IEdNVCswNTMwIChJbmRpYSBTdGFuZGFyZCBUaW1lKQ%3D%3D&code_challenge=mT0amBTJgczCZmNSZAYVfjzzpaTiGb68XlyR3RNHuas&code_challenge_method=S256
我的前端在端口4200上运行。
我的大摇大摆在61574端口上运行。
但在输入有效凭证后,我不会被重定向到swagger UI
请帮助我。如果您查看OAuth网站,案例将根据请求进行描述
按请求定制
通常情况下,开发人员会认为他们需要能够使用
在每个授权请求上使用不同的重定向URL,并将尝试
更改每个请求的查询字符串参数。这不是问题所在
重定向URL的预期用途,并且
授权服务器。服务器应拒绝任何授权
请求的重定向URL与
注册网址
如果客户端希望在重定向URL中包含特定于请求的数据,那么它可以>而不是使用“state”参数来存储>用户重定向后将包含的数据。它可以在状态参数本身中对数据进行编码,也可以使用状态参数作为会话ID在服务器上存储状态
我希望这对你的探索有所帮助
来源:首先,让我为您的图片添加一些细节:
您有两个应用程序,一个使用API(基于ASP.NET核心),另一个使用前端UI(角度,但这并不重要),重要的是,还有授权/身份验证功能
您可以使用.NETCore 3.1
您为swagger配置授权,这意味着来自swagger UI页面的任何调用都将使用给定的授权参数
因此,对于API应用程序,我们必须添加一个类,该类具有配置我们的招摇过市的帮助器方法:
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddSwaggerDocumentation(this IServiceCollection services)
{
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "CombiTime API v1.0", Version = "v1" });
c.AddSecurityDefinition(
"oauth2",
new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri("https://lvh.me:4201/connect/authorize"),
TokenUrl = new Uri("https://lvh.me:4201/connect/token"),
Scopes = new Dictionary<string, string> {
{ "combitimeapi", "Demo API" }
}
}
}
});
c.OperationFilter<AuthorizeOperationFilter>();
c.AddSecurityRequirement(
new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme{
Reference = new OpenApiReference{
Id = "oauth2", //The name of the previously defined security scheme.
Type = ReferenceType.SecurityScheme
}
},
new List<string>()
}
});
});
return services;
}
public static IApplicationBuilder UseSwaggerDocumentation(this IApplicationBuilder app)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Versioned API v1.0");
c.DocumentTitle = "Title Documentation";
c.DocExpansion(DocExpansion.None);
c.RoutePrefix = string.Empty;
c.OAuthClientId("combitimeapi_swagger");
c.OAuthAppName("Combitime API");
c.OAuthScopeSeparator(",");
c.OAuthUsePkce();
});
return app;
}
}
请不要忘记向所有控制器添加属性[Authorize]
,因为authorizationOperationFilter
假定已完成此操作
让我们为前端和授权部件查找所需的更改。您应该配置某些特定内容,例如:
CORS政策
Awailable API客户端(一个是您的Angular UI,另一个是API应用程序)
可获得的API资源
认证和授权方法
类Startup.cs
应包含:
public void ConfigureServices(IServiceCollection services)
{
// ... some your code ...
services.AddSwaggerDocumentation();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication("Bearer", options =>
{
options.ApiName = "combitimeapi";
options.Authority = "https://lvh.me:4201";
});
// ... some your code ...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ... some your code ...
app.UseSwaggerDocumentation();
app.UseRouting();
app.UseAuthorization();
// ... some your code ...
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
public void ConfigureServices(IServiceCollection services)
{
// ... some your code ...
services.AddCors(policies => {
policies.AddDefaultPolicy(builder => {
builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin();
});
});
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
options.Clients.AddIdentityServerSPA("forntend", cfg => {});
options.Clients.AddNativeApp("combitimeapi_swagger", cfg => {
cfg
.WithRedirectUri("https://lvh.me:5001/oauth2-redirect.html")
.WithScopes("combitimeapi");
});
options.ApiResources.AddApiResource("combitimeapi", cfg => {
cfg.WithScopes("combitimeapi");
});
})
.AddApiResources();
services
.AddAuthentication(
x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddIdentityServerJwt();
// ... some your code ...
}
public void配置服务(IServiceCollection服务)
{
//…一些您的代码。。。
services.AddCors(策略=>{
policies.AddDefaultPolicy(生成器=>{
builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin();
});
});
services.AddIdentityServer()
.Addapi授权
输入您的密码,标记范围并按“授权”,在您进行身份验证后,您将获得:
如果您没有得到成功的结果,请检查前端应用程序的日志,通常它包含错误,可以帮助您找到问题
希望上面的文字能对您有所帮助。启动代码可能有多个问题,请参阅AddSwaggerGen
身份提供程序的配置:
独立于重定向,您是否能够获得访问令牌,或者是否遇到某种错误,例如在请求中或在身份提供程序本身中
请注意,您在Swagger中提供的客户端配置必须与Identity Provider中的配置匹配。您似乎在遵循;我们可以观察到,所有his都遵循Identity Server()中的信息
在对API的调用中设置令牌:
此外,即使您获得了令牌,我认为您也没有在从Swagger到API本身的后续调用中设置它
AddSecurityDefinition
和AddSecurityRequirement
或AuthorizeOperationFilter
通常至少提到一个具有相同标识符的方案,因为第一个方法定义了Swagger进行身份验证的方式,第二个/第三个方法定义了对API的调用进行身份验证的方式(因此,它们必须相互引用)。但是,您在所有三个方法中使用不同的ID—“OAuth2”、“Bearer”和“OAuth2”,因此它们都没有链接
我不完全了解您的应用程序,但我相信您实际上可能只使用了AddSecurityRequirement
或AuthorizeOperationFilter
中的一个,因为它们都指定了安全性要求。最重要的是引用安全性定义的ID(在您的示例中为“OAuth2”)
事实上,Scott的例子中使用了was-在他的例子中是“oauth2”,但任何名称/字符串都可以使用。有人请帮忙吗?我不知道答案,但我面临着同样的问题。我会在问题符合条件时立即提供悬赏。@Goodnight NerdPred请参阅此链接:(当您从microsoft emai id登录时,此课程是免费的。)“asp.net core和OAuth入门”课程已经定义了所有内容。它帮助了我,现在我可以重定向回。可能您和我一样缺少了一些内容。:@GoodNightnerdPred同样,重定向在HTT上不起作用