IdentityServer4实战:四种授权模式

前言

本篇所讲案例代码全部由上篇《IdentityServer4实战:快速入门》修改而来。

客户端模式

客户端模式只对客户端进行授权,不涉及到用户信息。如果你的api需要提供到第三方应用,第三方应用自己做用户授权,不需要用到你的用户资源,就可以用客户端模式,只对客户端进行授权访问api资源。 这是一种最简单的模式,只要client请求,我们就将AccessToken发送给它。这种模式是最方便但最不安全的模式。因此这就要求我们对client完全的信任,而client本身也是安全的

定义 Client

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

new Client

                    {

                        ClientId = "client1",

 

                        // 没有交互性用户,使用 clientid/secret 实现认证。

                        AllowedGrantTypes = GrantTypes.ClientCredentials,

 

                        // 用于认证的密码

                        ClientSecrets =

                        {

                            new Secret("secret".Sha256())

                        },

                        // 客户端有权访问的范围(Scopes)

                        AllowedScopes = { "api1" }

                    }

POSTMan 测试

用户名密码模式

需要客户端提供用户名和密码,密码模式相较于客户端凭证模式。通过User的用户名和密码向Identity Server申请访问令牌。  这种方式需要用户给出自己的用户名/密码,显然风险很大,因此只适用于其他授权方式都无法采用的情况,而且必须是用户高度信任的应用。

定义 Client

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

new Client

                    {

                        ClientId = "client2",

 

                        //  用户名 密码 模式

                        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,

 

                        // 用于认证的密码

                        ClientSecrets =

                        {

                            new Secret("secret".Sha256())

                        },

                        // 客户端有权访问的范围(Scopes)

                        AllowedScopes = { "api1" }

                    }

定义 用户资源

1

2

3

4

5

6

7

8

9

10

11

12

public static List<TestUser> GetTestUsers()

        {

            return new List<TestUser>

            {

                new TestUser

                {

                    SubjectId="1",

                    Username="admin",

                    Password="123456"

                }

            };

        }

注册 用户资源

1

2

3

4

5

6

7

8

9

public void ConfigureServices(IServiceCollection services)

        {

            services.AddIdentityServer()

                .AddDeveloperSigningCredential()

                .AddInMemoryClients(Startup.GetClients())

                .AddInMemoryApiScopes(Startup.GetApiScopes())

                .AddTestUsers(Startup.GetTestUsers())

                ;

        }

POSTMan 测试

隐藏式 (implicit)

有些 Web 应用是前后端分离的纯前端应用,没有后端。这时就必须将令牌储存在前端。 这种方式没有授权码这个中间步骤,所以称为(授权码)"隐藏式"(implicit)。

隐藏式的认证步骤为:

第一步,A 网站提供一个链接,要求用户跳转到 认证中心,授权用户数据给 A 网站使用。

第二步,用户跳转到 认证中心,登录后同意给予 A 网站授权。这时,认证中心就会跳回redirect_uri参数指定的跳转网址,并且把令牌作为 URL 参数,传给 A 网站。

 

注意,令牌的位置是 URL 锚点(fragment),而不是查询字符串(querystring),这是因为 OAuth 2.0 允许跳转网址是 HTTP 协议,因此存在"中间人攻击"的风险,而浏览器跳转时,锚点不会发到服务器,就减少了泄漏令牌的风险。

安装 登录界面

隐藏式 需要用户在 认证中心 登录并授权数据给 A 网站,所以需要一个登录界面。这里我们使用 官网提供的 Quickstart.UI,它提供了一个完善的登录和登出的UI。

进入到  MicroShell.IdentityServer4.Server 项目根目录,执行如下命令:

1

2

dotnet new -i identityserver4.templates

dotnet new is4ui

安装成功后,项目中多了 wwwroot、Quickstart、views 等文件夹。

注入 UI 的依赖服务 和 路由规则

ConfigureServices 方法中添加如下代码:

1

services.AddControllersWithViews();

Configure 方法中路由改为:

1

2

3

4

5

6

app.UseEndpoints(endpoints =>

            {

                endpoints.MapControllerRoute(

                      name: "default",

                      pattern: "{controller=Home}/{action=Index}/{id?}");

            });

 

定义 Client

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

new Client

                    {

                        ClientId = "client4",

 

                        //  授权码 模式

                        AllowedGrantTypes = GrantTypes.Implicit,

 

                        RedirectUris = { "http://localhost:5001/test/index"}, // 认证成功后允许的回调地址

                         

                        // 是否需要确认授权,这个配置我们会在后面介绍,这里设置为 false

                        RequireConsent = false,

 

                        // 用于认证的密码

                        ClientSecrets =

                        {

                            new Secret("secret".Sha256())

                        },

 

                        //AlwaysIncludeUserClaimsInIdToken=true,

 

                        //允许token通过浏览器 (必须 true)

                        AllowAccessTokensViaBrowser=true,     

 

                        // 客户端有权访问的范围(Scopes)

                        AllowedScopes = {

                            "api1",

                            IdentityServerConstants.StandardScopes.OpenId,

                        IdentityServerConstants.StandardScopes.Profile

                        }

                    }

修改注入的 用户资源

浏览器测试

浏览器输入:http://localhost:5000/connect/authorize?response_type=id_token token&client_id=client4&scope=openid profile api1&redirect_uri=http://localhost:5001/test/index&nonce=11111111111111111111111

授权码模式

授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。 这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。

定义 Client

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

new Client

                    {

                        ClientId = "client3",

 

                        //  授权码 模式

                        AllowedGrantTypes = GrantTypes.Code,

 

                        RedirectUris = { "http://localhost:5001/test/index"},

 

                        // 是否需要确认授权,这个配置我们会在后面介绍,这里设置为 false

                        RequireConsent = false,

 

                        // 这个参数必须设置 为 false

                        RequirePkce= false,

 

                        // 用于认证的密码

                        ClientSecrets =

                        {

                            new Secret("secret".Sha256())

                        },

                        // 客户端有权访问的范围(Scopes)

                        AllowedScopes = {

                            "api1",

                            IdentityServerConstants.StandardScopes.OpenId,

                        IdentityServerConstants.StandardScopes.Profile

                        }

                    }

浏览器测试

浏览器输入:http://localhost:5000/connect/authorize?response_type=code&client_id=client3&state=xyz&redirect_uri=http%3A%2F%2Flocalhost%3A5001%2FTest%2Findex&scope=openid profile api1

 

尾言

授权码模式中我们只拿到了 Code,并没有通过 Code 换取 Token,后面的操作笔友可以自己实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值