写在前面
1、源码(.Net Core 2.2)
git地址:https://github.com/yizhaoxian/CoreIdentityServer4Demo.git
2、相关章节
2.1、《IdentityServer4 (1) 客户端授权模式(Client Credentials)》
2.2、《IdentityServer4 (2) 密码授权(Resource Owner Password)》
2.3、《IdentityServer4 (3) 授权码模式(Authorization Code)》
2.4、《IdentityServer4 (4) 静默刷新(Implicit)》
2.5、《IdentityServer4 (5) 混合模式(Hybrid)》
3、参考资料
IdentityServer4 中文文档 http://www.identityserver.com.cn/
IdentityServer4 英文文档 https://identityserver4.readthedocs.io/en/latest/
OpenID Connect 官网 https://openid.net/connect/
OpenID Connect 中文 https://www.cnblogs.com/linianhui/p/openid-connect-core.html
OpenID Connect和OAuth 2.0对比:https://www.jianshu.com/p/d453076e6433
Oauth 2.0 官网:https://oauth.net/2/
Oauth 2.0 授权框架:https://tools.ietf.org/html/rfc6749#section-4.2.1
4、流程图
1、客户端准备一个包含所需请求参数的身份验证请求。
2、客户端将请求发送到授权服务器(填写账号密码)。
3、授权服务器对最终用户进行身份验证(验证账号密码和客户端)。
4、授权服务器获得最终用户同意/授权。
5、授权服务器使用IdToken和AccessToken(如果要求)将最终用户发送回客户端。
一、服务端
1、添加客户端
new Client{ ClientId="mvc client implicit", //客户端Id ClientName="测试客户端 Implicit", //客户端名称 随便写 //Implicit 模式 因为token 是通过浏览器发送给客户端的,这里必须启用 AllowAccessTokensViaBrowser=true, AllowedGrantTypes=GrantTypes.Implicit,//验证模式 RedirectUris = { "http://localhost:5003/callback.html", // AccessToken 有效期比较短,刷新 AccessToken 的页面 "http://localhost:5003/silentref.html", }, //是否需要用户点击同意,这里需要设置为 false,不然客户端静默刷新不可用 RequireConsent=false, AllowedCorsOrigins={ "http://localhost:5003" }, //注销重定向的url PostLogoutRedirectUris = { "http://localhost:5003" }, AccessTokenLifetime=10, //客户端访问权限 AllowedScopes = { "api1", IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Email, IdentityServerConstants.StandardScopes.Address, IdentityServerConstants.StandardScopes.Phone, IdentityServerConstants.StandardScopes.Profile } },
二、客户端
1、下载 oidc-client 库
git地址:https://github.com/IdentityModel/oidc-client-js
2、添加测试页面
我直接使用的/home/index 在里面添加请求授权代码
class="row btn-box">
class="row">User:
"userinfo" class="col-md-12 box">class="row">@section Scripts{ }API:
"apiresult" class="col-md-12 box">
3、登陆回调页面
"utf-8" />Oidc-Client 登陆中...
4、自动刷新页面
"utf-8" />Oidc-Client Silent.html
5、页面结构目录
三、API资源
1、修改StartUp.cs
ConfigureServices()
services.AddCors(options => { options.AddPolicy("client1", policy => { //客户端地址 policy.WithOrigins("http://localhost:5003"); policy.AllowAnyHeader(); policy.AllowAnyMethod(); }); }); JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => { // IdentityServer 地址 options.Authority = "http://localhost:5002"; //不需要https options.RequireHttpsMetadata = false; //这里要和 IdentityServer 定义的 api1 保持一致 options.Audience = "api1"; //token 默认容忍5分钟过期时间偏移,这里设置为0, //这里就是为什么定义客户端设置了过期时间为5秒,过期后仍可以访问数据 options.TokenValidationParameters.ClockSkew = TimeSpan.Zero; options.Events = new JwtBearerEvents { //AccessToken 验证失败 OnChallenge = op => { //跳过所有默认操作 op.HandleResponse(); //下面是自定义返回消息 //op.Response.Headers.Add("token", "401"); op.Response.ContentType = "application/json"; op.Response.StatusCode = StatusCodes.Status401Unauthorized; op.Response.WriteAsync(JsonConvert.SerializeObject(new { status = StatusCodes.Status401Unauthorized, msg = "token无效", error = op.Error })); return Task.CompletedTask; } }; });
Configure()
app.UseStaticFiles(); //这里注意 一定要在 UseMvc前面,顺序不可改变 app.UseAuthentication(); app.UseCors("client1");
三、测试
可以看到右侧console 再自动刷新