首页 新闻 会员 周边

用.Net Code 3.1做网站,同时提供API,怎么做身份验证?

0
悬赏园豆:10 [已解决问题] 解决于 2019-12-20 00:32

目标是做一个网站系统实现很多功能。
其中几个功能被要求使用时必须用桌面应用程序,不能用网站,所以会有好几个单独客户端。
但是所有的操作都需要身份验证,要有角色限制。
系统不是很复杂,所以不想把API和网站分开,感觉分开后会很麻烦,我也只会用.Net写网站

目前的结果是用IdentityServer4管理账户,但是那个网站只能单独作为客户端或者单独提供资源,这个根据文档都写没问题,但是同时作为客户端和资源的时候总是无法配置成功。应该怎么配置?
或者肯定有更简单的办法,不使用IdentityServer4,直接让.Net Core3.1的API用JWT身份验证,同时访问网站时也可以登录,但是相关示例找不到,官方文档也没有写(或者我不会英文找不到),创建VS2019 创建API的时候根本没有本地身份验证这个模板。
用户管理用得都是自带的 AspNetCore.Identity

.NetCode配置资源的代码是:

services.AddAuthentication(“Bearer”).AddJwtBearer("Bearer", options =>
    {
        options.Authority = "https://localhost:5000";
        options.RequireHttpsMetadata = false;
        options.Audience = "MainApi";
    });

配置客户端的代码是:

services.AddAuthentication(options =>
{
    options.DefaultChallengeScheme = "oidc";
    options.DefaultScheme = "Cookies";
}).AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
    options.SignInScheme = "Cookies";

    options.Authority = "http://localhost:5000";
    options.RequireHttpsMetadata = false;

    options.ClientId = "mvc";
    options.ClientSecret = "secret";
    options.ResponseType = "code id_token";

    options.SaveTokens = true;
    options.GetClaimsFromUserInfoEndpoint = true;
    options.Scope.Add("MainApi");
    options.Scope.Add("Roles");
    options.Scope.Add("offline_access");
    options.ClaimActions.MapJsonKey("website", "website");

    options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
    {
        NameClaimType = JwtClaimTypes.Name,
        RoleClaimType = JwtClaimTypes.Role
    };
});

但是吧他们一个一个写一通过API访问被保护资源就直接返回identitysrever登陆页面的源代码

如果这样合起来写的话

services.AddAuthentication(options =>
{
    options.DefaultChallengeScheme = "oidc";
    options.DefaultScheme = "Cookies";
    options.DefaultAuthenticateScheme = "Bearer";
}).AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
    options.SignInScheme = "Cookies";

    options.Authority = "http://localhost:5000";
    options.RequireHttpsMetadata = false;

    options.ClientId = "mvc";
    options.ClientSecret = "secret";
    options.ResponseType = "code id_token";

    options.SaveTokens = true;
    options.GetClaimsFromUserInfoEndpoint = true;
    options.Scope.Add("MainApi");
    options.Scope.Add("Roles");
    options.Scope.Add("offline_access");
    options.ClaimActions.MapJsonKey("website", "website");

    options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
    {
        NameClaimType = JwtClaimTypes.Name,
        RoleClaimType = JwtClaimTypes.Role
    };
}).AddJwtBearer("Bearer", options =>
{
    options.Authority = "https://localhost:5000";
    options.RequireHttpsMetadata = false;
    options.Audience = "MainApi";
}); 

会一直循环在identityServer登陆后选择资源的那个页面出不去,根据实验是options.DefaultAuthenticateScheme = "Bearer";这行导致的

随缘py的主页 随缘py | 初学一级 | 园豆:146
提问于:2019-12-13 15:33
< >
分享
最佳答案
1

https://github.com/linianhui/oidc.example 给你个示例,ids4做的认证+授权服务,wpf,uwp,js,console等类型的客户端应用。

收获园豆:10
Timetombs | 老鸟四级 |园豆:3954 | 2019-12-13 15:35

我找的是一个网站,既做资源有做客户端,这里也没找到这样的~~

随缘py | 园豆:146 (初学一级) | 2019-12-13 16:36

@随缘py:

资源是指资源服务器。

客户端指的是什么?认证的客户端,还是授权的客户端?

Timetombs | 园豆:3954 (老鸟四级) | 2019-12-13 18:55

@随缘py:

我梳理下我理解的你的问题:

你有一个网站。

  1. 网站要接入一个认证系统(ids4实现)。
  2. 网站上要增加一些受保护的api(由ids4颁发的access_token保护)给其他的桌面应用使用。
  3. 桌面应用使用ids4进行认证和授权。

如果是上述问题的话。

  1. 你需要部署一个ids4的服务(独立部署或者附加到你目前的网站上都行)。并配置一下认证方式。
  2. 在你的网站上增加一些API,然后配置一下授权方式。
  3. 桌面应用接入ids4的认证和授权即可,然后就可以拿着access_token访问你的网站的api了。

我给你的例子中,ids4本身的那个项目就类似你的网站。它既是认证中心,也是授权中心,同时自己也消费自己的认证,也具备受保护的api。

Timetombs | 园豆:3954 (老鸟四级) | 2019-12-13 19:05

抱歉,我给的例子上的ids4的一个api(IsLogin方法 https://github.com/linianhui/oidc.example/blob/master/1-src/web.oidc.server.ids4/Ids4/Account/AccountController.cs#L182)使用的是id_token的cookie的认证,并不是对access_token的认证。

不过理论上是可以,我找时间试试加上去一个示例。

Timetombs | 园豆:3954 (老鸟四级) | 2019-12-14 10:34

@blackheart: 谢谢了~ 现在感觉identityServer4太复杂,没有中文资料已经超过我的能力了~,就算这块完事了,后面还会碰到问题。
有没有单独一个.Net core WebApi使用内置的Identiy验证的例子,就像直接用VS创建ASP.NET Web API应用程序,选择内置的个人身份账户验证一样的,我在里面加上普通登录页面的验证应该就好了。

目前我试的最好情况是写单个Web API能用javascript获取到token了,但是获取之后postman不使用token就能直接访问需要验证的API~~ Winform一直在试还没成功

随缘py | 园豆:146 (初学一级) | 2019-12-17 09:38

@随缘py: 单纯用jwt确实是简化很多,很多逻辑可以自己自由控制,理解上更清晰一些。

不使用token就能访问那就是你服务的基于jwt token的认证还配置是有问题。这块的资料就比较多一些了。

Timetombs | 园豆:3954 (老鸟四级) | 2019-12-17 09:49

@blackheart: 最后还是最标准的IdentityServer+WebAPI+MVC网站+Winform程序了,这样结构最标准,不管有啥问题都有各种资料。
WebAPI+MVC网站作为一个项目的话,页面登录和jwt还是没办法同时实现~

随缘py | 园豆:146 (初学一级) | 2019-12-20 00:35

@随缘py: 是的,我也试了一下合并在一块,然后就注册了一个基于cookie : id_token的认证和一个基于 Authorization : Bearer access_token的认证组合。结果就是干扰了前者的认证,但是独立使用后者是可以的。理论上是可行的(任意多个认证方式都可以),应该是我没配置好,但是一般很少这么干,混在一块比较乱,出了问题不好排查。

Timetombs | 园豆:3954 (老鸟四级) | 2019-12-20 09:32

@blackheart: 同一个网站不同登录方式的问题最终解决了~
可以直接配置多个身份认证信息
[Authorize(AuthenticationSchemes = "JwtBearerLogin")]可以手动选择这个Controller身份验证的时候调用那种方式进行认证~~

这里有文档:https://docs.microsoft.com/zh-cn/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-3.1

随缘py | 园豆:146 (初学一级) | 2020-03-11 00:39
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册