• IdentityServer4(五)


    本文实现控制台应用程序连接IdentityServer服务端进行客户端验证,并调用授权API

    1、新建控制台应用程序,nuget包安装 IdentityModel ,Program.cs代码如下:

    class Program
        {
            static async Task Main(string[] args)
            {
                var client = new HttpClient();
                var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5001");
                if (disco.IsError)
                {
                    Console.WriteLine(disco.Error);
                    return;
                }
    
                //ClientId = "consoleclient",
                //        ClientName = "Client Credentials Client",
    
                //        AllowedGrantTypes = GrantTypes.ClientCredentials,
                //        ClientSecrets = { new Secret("consolesecret".Sha256()) },
    
                //        AllowedScopes = { "scope1" }
    
                var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
                {
                    Address = disco.TokenEndpoint,
    
                    ClientId = "consoleclient",
                    ClientSecret = "consolesecret",
                    Scope = "scope2"
                });
    
                if (tokenResponse.IsError)
                {
                    Console.WriteLine(tokenResponse.Error);
                    return;
                }
    
                Console.WriteLine(tokenResponse.Json);
    
                var apiClient = new HttpClient();
                apiClient.SetBearerToken(tokenResponse.AccessToken);
    
                var response = await apiClient.GetAsync("http://localhost:6001/identity");
                if (!response.IsSuccessStatusCode)
                {
                    Console.WriteLine(response.StatusCode);
                }
                else
                {
                    var content = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(JArray.Parse(content));
                }
    
                Console.ReadKey();
            }
    
        }

    2、IdentityServer服务沿用前面文章所建的项目,并修改config文件。

     public static class Config
        {
            public static IEnumerable<IdentityResource> IdentityResources =>
                new IdentityResource[]
                {
                    new IdentityResources.OpenId(),
                    new IdentityResources.Profile(),
                };
    
            public static IEnumerable<ApiScope> ApiScopes =>
                new ApiScope[]
                {
                    new ApiScope("scope1"),
                    new ApiScope("scope2"),
                };
    
            public static IEnumerable<Client> Clients =>
                new Client[]
                {
                    // m2m client credentials flow client
                    new Client
                    {
                        ClientId = "consoleclient",
                        ClientName = "Client Credentials Client",
    
                        AllowedGrantTypes = GrantTypes.ClientCredentials,
                        ClientSecrets = { new Secret("consolesecret".Sha256()) },
    
                        AllowedScopes = { "scope1","scope2" }
                    },
    
                       new Client
                    {
                        ClientId = "wpfclient",
                        ClientName = "wpfclient Credentials",
    
                        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                        ClientSecrets = { new Secret("wpfsecret".Sha256()) },
    
                        AllowedScopes = { "scope1","scope2" }
                    },
    
                    // interactive client using code flow + pkce
                    new Client
                    {
                        ClientId = "interactive",
                        ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) },
    
                        AllowedGrantTypes = GrantTypes.Code,
    
                        RedirectUris = { "https://localhost:44300/signin-oidc" },
                        FrontChannelLogoutUri = "https://localhost:44300/signout-oidc",
                        PostLogoutRedirectUris = { "https://localhost:44300/signout-callback-oidc" },
    
                        AllowOfflineAccess = true,
                        AllowedScopes = { "openid", "profile", "scope2" }
                    },
    
                     new Client
                    {
                        ClientId = "mvc",
                        ClientSecrets = { new Secret("secret".Sha256()) },
                    
                        AllowedGrantTypes = GrantTypes.Code,
                    
                        // where to redirect to after login
                        RedirectUris = { "http://localhost:5002/signin-oidc" },
                    
                        // where to redirect to after logout
                        PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
                    
                        AllowedScopes = new List<string>
                        {
                            IdentityServerConstants.StandardScopes.OpenId,
                            IdentityServerConstants.StandardScopes.Profile
                        }
                    }
                };
        }

    3、新建Asp.net core API项目,nuget安装Microsoft.AspNetCore.Authentication.JwtBearer 包,修改Startup.cs文件。

    public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
    
                services.AddControllers();
    
                services.AddAuthentication("Bearer")
               .AddJwtBearer("Bearer", options =>
               {
                   options.Authority = "http://localhost:5001";
                   options.RequireHttpsMetadata = false;
                   options.TokenValidationParameters = new TokenValidationParameters
                   {
                       ValidateAudience = false
                   };
               });
                services.AddAuthorization(options =>
                {
                    options.AddPolicy("ApiScope", policy =>
                    {
                        policy.RequireAuthenticatedUser();
                        policy.RequireClaim("scope","scope2");
                    });
                });
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                app.UseRouting();
    
                app.UseAuthentication();
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                    //.RequireAuthorization("ApiScope");
                });
            }
        }

    4、Asp.net core API项目添加IdentityController.cs

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

    5、Asp.net core API项目添加NoScopeIdentityController.cs

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

    6.launchsettings.json

    {
      
      "profiles": {
        "IdsWebApi": {
          "commandName": "Project",
          "dotnetRunMessages": "true",
          "launchBrowser": true,
          "launchUrl": "weatherforecast",
          "applicationUrl": "http://localhost:6001",
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          }
        }
      }
    }

    7、添加wpf项目,Nuget安装 IdentitiModel 包

    <Window x:Class="WpfClient.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfClient"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="40"></RowDefinition>
                <RowDefinition Height="40"></RowDefinition>
                <RowDefinition Height="40"></RowDefinition>
                <RowDefinition Height="40"></RowDefinition>
                <RowDefinition Height="40"></RowDefinition>
                <RowDefinition Height="40"></RowDefinition>
            </Grid.RowDefinitions>
    
            <StackPanel Orientation="Horizontal">
                <Label Content="账号"/>
                <TextBox Name="txtaccount" Width="100" Height="30"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Grid.Row="1">
                <Label Content="账号"/>
                <TextBox Name="txtpassword" Width="100" Height="30"/>
            </StackPanel>
            <Button Grid.Row="2"
                    Height="30"
                    Width="100"
                    Content="登录"
                    Click="Button_Click"/>
            
        </Grid>
    </Window>
     public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                Login();
    
            }
    
            public async Task Login()
            {
                var client = new HttpClient();
                var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5001");
                if (disco.IsError)
                {
                    Console.WriteLine(disco.Error);
                    return;
                }
    
                var token = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
                {
                    Address = disco.TokenEndpoint,
                    UserName = txtaccount.Text,
                    Password = txtpassword.Text,
                    ClientId = "wpfclient",
                    ClientSecret = "wpfsecret",
                    Scope = "scope1"
                });
                if (token.IsError)
                {
                    return;
                }
                Console.WriteLine(token.Json);
    
                var apiClient = new HttpClient();
                apiClient.SetBearerToken(token.AccessToken);
    
                var response = await apiClient.GetAsync("http://localhost:6001/noscopeIdentity");
                if (!response.IsSuccessStatusCode)
                {
                    MessageBox.Show(response.StatusCode.ToString());
                }
                else
                {
                    var content = await response.Content.ReadAsStringAsync();
                    MessageBox.Show(content);
                }
    
            }
        }
  • 相关阅读:
    python 项目实例
    flash教程
    flask request
    systemd-unit
    kubernets HA集群手动部署
    zookeeper(1)-简单介绍
    apache与nginx原理
    技术文章整理
    CMS垃圾回收器
    Zookeeper
  • 原文地址:https://www.cnblogs.com/lhwpc/p/15076939.html
Copyright © 2020-2023  润新知