zoukankan      html  css  js  c++  java
  • IdentityServer4学习(一)

    一、Client Credentials实例

    ①准备

    安装模板,请打开控制台窗口,然后键入以下命令:

    dotnet new -i IdentityServer4.Templates

    安装后,会出现这么几个identityserver模板

    查看模板

    dotnet new

     我们这里选择将信息放在内存里面的In-Memory Stores and Test Users模板

    ②创建In-Memory Stores and Test Users模板项目

     dotnet new is4inmem --name myService

    在config文件中会生成几个Client类别,本案例就试用

     然后我们将服务的启动项端口设为5000

    ③创建客户端

    编写一个请求访问令牌的客户端,创建一个控制台应用设置启动端口为5002

    添加IdentityModel包

    从元数据中读取实际的端点地址

    // discover endpoints from metadata
    var client = new HttpClient();
    var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
    if (disco.IsError)
    {
        Console.WriteLine(disco.Error);
        return;
    }

    接下来,您可以使用发现文档中的信息向IdentityServer请求令牌以访问api1

    // request token
    var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
    {
        Address = disco.TokenEndpoint,
    
        ClientId = "client",
        ClientSecret = "secret",
        Scope = "api1"
    });
    
    if (tokenResponse.IsError)
    {
        Console.WriteLine(tokenResponse.Error);
        return;
    }
    
    Console.WriteLine(tokenResponse.Json);

    将访问令牌发送到API,访问api

    // call api
    var apiClient = new HttpClient();
    apiClient.SetBearerToken(tokenResponse.AccessToken);
    
    var response = await apiClient.GetAsync("http://localhost:5001/identity");
    if (!response.IsSuccessStatusCode)
    {
        Console.WriteLine(response.StatusCode);
    }
    else
    {
        var content = await response.Content.ReadAsStringAsync();
        Console.WriteLine(JArray.Parse(content));
    }

    ④定义API资源

    创建一个api项目,设置启动端口为5001

    添加一个名为的新类IdentityController

    [Route("identity")]
    [Authorize]
    public class IdentityController : ControllerBase
    {
        [HttpGet]
        public IActionResult Get()
        {
            return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
        }
    }

    然后再控制器上面加上权限访问[Authorize]

    最后一步是将身份验证服务添加到DI(依赖注入),并将身份验证中间件添加到管道。这些将:

    • 验证传入令牌以确保它来自受信任的发行者
    • 验证令牌是否可以与此API一起使用(也称为受众群体)
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
    
            services.AddAuthentication("Bearer")
                .AddJwtBearer("Bearer", options =>
                {
                    options.Authority = "http://localhost:5000";
                    options.RequireHttpsMetadata = false;
    
                    options.Audience = "api1";
                });
        }
    
        public void Configure(IApplicationBuilder app)
        {
            app.UseRouting();
    
            app.UseAuthentication();
            app.UseAuthorization();
    
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
    • AddAuthentication将身份验证服务添加到DI并配置Bearer为默认方案。
    • UseAuthentication 将身份验证中间件添加到管道中,以便对主机的每次调用都将自动执行身份验证。
    • UseAuthorization 添加了授权中间件,以确保匿名客户端无法访问我们的API端点。

    http://localhost:5001/identity在浏览器上导航至控制器应返回401状态代码。这意味着您的API需要凭据,并且现在受IdentityServer保护。

    二、Authorization Code Flow保护MVC客户端实例

    ①创建mvc项目

    修改startup文件,注册身份认证中间件

    services.AddAuthentication(options =>
                {
                    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
                })
                    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
                    .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
                    {
                        options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                        //授权服务器地址
                        options.Authority = "http://localhost:5000";
                        //去掉https
                        options.RequireHttpsMetadata = false;
                        options.ClientId = "mvc client";
                        options.ClientSecret = "mvc secret";
                        options.SaveTokens = true;
                        options.ResponseType = "code";
    
                        options.Scope.Clear();
                        options.Scope.Add("api1");
                        options.Scope.Add(OidcConstants.StandardScopes.OpenId);
                        options.Scope.Add(OidcConstants.StandardScopes.Profile);
                        //options.Scope.Add(OidcConstants.StandardScopes.Email);
                        //options.Scope.Add(OidcConstants.StandardScopes.Phone);
                        //options.Scope.Add(OidcConstants.StandardScopes.Address);
                        options.Scope.Add(OidcConstants.StandardScopes.OfflineAccess);
                    });

    在Configure方法中调用

    app.UseAuthentication();

    放在mvc之前就行

    然后对控制中的资源进行保护

    在控制器前面加上验证[Authorize]

    ②在授权服务中添加Client

     // mvc client using code flow + pkce
                    new Client
                    {
                        ClientId = "mvc client",
                        ClientName = "MVC Client",
                        ClientSecrets = { new Secret("mvc secret".Sha256()) },
                        AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
                        //指定使用基于授权代码的授权类型的客户端是否必须发送校验密钥
                       // RequirePkce = true,
                        //RequireConsent = false, //禁用 确认授权那个consent 页面确认
                        //指定允许的URI以返回令牌或授权码
                        RedirectUris = { "http://localhost:5003/signin-oidc" },
                        //指定客户端的注销URI,以用于基于HTTP的前端通道注销
                        FrontChannelLogoutUri = "http://localhost:5003/signout-oidc",
                        //指定在注销后重定向到的允许URI
                        PostLogoutRedirectUris = { "http://localhost:5003/signout-callback-oidc" },
                        AllowOfflineAccess = true, // offline_access
                        AllowedScopes = {"api1", 
                            IdentityServerConstants.StandardScopes.OpenId,
                            IdentityServerConstants.StandardScopes.Profile,
                            //IdentityServerConstants.StandardScopes.Email,
                            //IdentityServerConstants.StandardScopes.Phone,
                            //IdentityServerConstants.StandardScopes.Address,
                            IdentityServerConstants.StandardScopes.OfflineAccess
                        }
    
                    },

    github代码地址:https://github.com/LGXQWER/identityServerDEMO

    参考文献:https://identityserver4.readthedocs.io/en/latest/quickstarts/1_client_credentials.html

  • 相关阅读:
    leetcode刷题笔记五十八 最后一个单词的长度
    leetcode刷题笔记五十六和五十七 合并区间与插入区间
    linux根据端口号,或进程名获取进程pid
    linux系统简单配置——centos7
    日常知识点记录
    实用代码-获取某一个对象中的信息
    java获取svn中的数据
    idea快捷键整理,以及eclipse快捷键对比,持续更新中
    ajax发送同步请求
    基于 pygame 设计贪吃蛇游戏
  • 原文地址:https://www.cnblogs.com/liguix/p/12727458.html
Copyright © 2011-2022 走看看