zoukankan      html  css  js  c++  java
  • IdentityServer3:.NET开源OpenID和OAuth2架构

     简介

    大多数软件的相互沟通图:客户端与Web应用程序的访问、应用与Web api、api与api……相互沟通则需要授权、身份验证

     IdentityServer3的功能:Web认证、SSO单点登录、Web Api访问权限(常用的这三个)

    RP:依赖方

    OP:OpenID Provider

    IP:Id Provider

    STS:安全令牌服务

    Scope:范围标识(身份、资源)

    用户(User)访问客户端、客户端(Client: 如Web或APP)向IdentityServer请求token,OP返回身份token访问token,每一种资源都有一个标识范围(身份信息,授权资源信息都有一个对应的scope标识),OP会获取资源(RP)的Scope

    开始使用IdentityServer3

    1、新建一个控制台应用作为IdentityServer

    安装:install-package identityserver3

     新建Client.cs:在IdentityServer注册Client信息

    using IdentityServer3.Core.Models;
    using System.Collections.Generic;
    
    namespace IdSrv
    {
        static class Clients
        {
            public static List<Client> Get()
            {
                return new List<Client>
                {
                    // no human involved
                    new Client
                    {
                        ClientName = "Silicon-only Client",
                        ClientId = "silicon",
                        Enabled = true,
                        AccessTokenType = AccessTokenType.Reference,
    
                        Flow = Flows.ClientCredentials,
                        
                        ClientSecrets = new List<Secret>
                        {
                            new Secret("F621F470-9731-4A25-80EF-67A6F7C5F4B8".Sha256())
                        },
                        
                        AllowedScopes = new List<string>
                        {
                            "api1"
                        }
                    },
    
                    // human is involved
                    new Client
                    {
                        ClientName = "Silicon on behalf of Carbon Client",
                        ClientId = "carbon",
                        Enabled = true,
                        AccessTokenType = AccessTokenType.Reference,
    
                        Flow = Flows.ResourceOwner,
                        
                        ClientSecrets = new List<Secret>
                        {
                            new Secret("21B5F798-BE55-42BC-8AA8-0025B903DC3B".Sha256())
                        },
    
                        AllowedScopes = new List<string>
                        {
                            "api1"
                        }
                    }
                };
            }
        }
    }
    Client.cs

    Scopes.cs注册范围标识

    using System.Collections.Generic;
    using IdentityServer3.Core.Models;
    
    namespace IdSrv
    {
        static class Scopes
        {
            public static List<Scope> Get()
            {
                return new List<Scope>
                {
                    new Scope
                    {
                        Name = "api1"
                    }
                };
            }
        }
    }
    Scopes.cs

    Users.cs注册用户

    using IdentityServer3.Core.Services.InMemory;
    using System.Collections.Generic;
    
    namespace IdSrv
    {
        static class Users
        {
            public static List<InMemoryUser> Get()
            {
                return new List<InMemoryUser>
                {
                    new InMemoryUser
                    {
                        Username = "bob",
                        Password = "secret",
                        Subject = "1"
                    },
                    new InMemoryUser
                    {
                        Username = "alice",
                        Password = "secret",
                        Subject = "2"
                    }
                };
            }
        }
    }
    Users.cs

    配置Owin;这里把IdentityServer作为Owin的中间件配置一下

    using Owin;
    using IdentityServer3.Core.Configuration;
    
    namespace IdSrv
    {
        class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                var options = new IdentityServerOptions
                {
                    Factory = new IdentityServerServiceFactory()
                                .UseInMemoryClients(Clients.Get())
                                .UseInMemoryScopes(Scopes.Get())
                                .UseInMemoryUsers(Users.Get()),
    
                    RequireSsl = false
                };
    
                app.UseIdentityServer(options);
            }
        }
    }
    Startup.cs

     Program.cs

    using Microsoft.Owin.Hosting;
    using System;
    
    namespace IdSrv
    {
        class Program
        {
            static void Main(string[] args)
            {
    
    
                // hosting identityserver
                using (WebApp.Start<Startup>("http://localhost:5000"))
                {
                    Console.WriteLine("server running...");
                    Console.ReadLine();
                }
            }
        }
    }
    Program.cs

     2、新建控制台应用作为Client

    namespace Client
    {
        class Program
        {
            static void Main(string[] args)
            {
                var response = GetClientToken();//获取令牌
                CallApi(response);//实用令牌访问资源
    
                response = GetUserToken();
                CallApi(response);
            }
    
            static void CallApi(TokenResponse response)
            {
                var client = new HttpClient();
                client.SetBearerToken(response.AccessToken);
    
                Console.WriteLine(client.GetStringAsync("http://localhost:14869/test").Result);
            }
    
            static TokenResponse GetClientToken()
            {
                var client = new TokenClient(
                    "http://localhost:5000/connect/token",
                    "silicon",
                    "F621F470-9731-4A25-80EF-67A6F7C5F4B8");
    
                return client.RequestClientCredentialsAsync("api1").Result;
            }
    
            static TokenResponse GetUserToken()
            {
                var client = new TokenClient(
                    "http://localhost:5000/connect/token",
                    "carbon",
                    "21B5F798-BE55-42BC-8AA8-0025B903DC3B");
    
                return client.RequestResourceOwnerPasswordAsync("bob", "secret", "api1").Result;
            }
        }
    }
    Program.cs

    3、新建Web API作为资源(RP)

     Owin配置

    using Microsoft.Owin;
    using Owin;
    using System.Web.Http;
    using IdentityServer3.AccessTokenValidation;
    
    [assembly: OwinStartup(typeof(Apis.Startup))]
    
    namespace Apis
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // accept access tokens from identityserver and require a scope of 'api1'
                app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
                    {
                        Authority = "http://localhost:5000",
                        ValidationMode = ValidationMode.ValidationEndpoint,
    
                        RequiredScopes = new[] { "api1" }
                    });
    
                // configure web api
                var config = new HttpConfiguration();
                config.MapHttpAttributeRoutes();
                
                // require authentication for all controllers
                config.Filters.Add(new AuthorizeAttribute());
    
                app.UseWebApi(config);
            }
        }
    }
    Startup

    Controller

    using System.Security.Claims;
    using System.Web.Http;
    
    namespace Apis
    {
        [Route("test")]
        public class TestController : ApiController
        {
            public IHttpActionResult Get()
            {
                var caller = User as ClaimsPrincipal;
    
                var subjectClaim = caller.FindFirst("sub");
                if (subjectClaim != null)
                {
                    return Json(new
                    {
                        message = "OK user",
                        client = caller.FindFirst("client_id").Value,
                        subject = subjectClaim.Value
                    });
                }
                else
                {
                    return Json(new
                    {
                        message = "OK computer",
                        client = caller.FindFirst("client_id").Value
                    });
                }
            }
        }
    }
    Controller.cs

    资源:

    官网:https://identityserver.io/

    IdentityServer3文档:https://identityserver.github.io/Documentation/docsv2/

    示例与源码:https://identityserver.github.io/Documentation/

  • 相关阅读:
    Kibana: missing authentication credentials for REST request
    MySQL命令速记
    VIM常用命令简记
    Linux常用命令简记
    袁永福的C#编程书籍,电子工业出版社出版。
    发布DCWriter电子病历文本编辑器
    袁永福的博客系列文章链接集合
    ssh隧道 的命令行和 sshd 服务的配置(gatePort)
    PureMVC(AS3)剖析:设计模式(二)
    Python应用与实践
  • 原文地址:https://www.cnblogs.com/xmai/p/7359092.html
Copyright © 2011-2022 走看看