webApi安全访问之 IdentityServer4使用总结

来源:互联网 发布:暗黑3猎魔人套装数据 编辑:程序博客网 时间:2024/06/10 23:34

     webapi项目通常需要考虑跨域,安全性等问题。今天总结一种最简单的方式,来保障webapi不被别人随便调用。这里总结下identityserver4的使用。

IdentityServer4 是最新也是比较容易上手的一个开源框架,你要是从IdentityServer3开始用,会很容易头大,搞不清楚所以然。就github上面的使用例

子看,IdentityServer4是比较容易理解上手的。这次我们使用了类似openId connect的方式。客户端访问apiServer的时候,先去IdentityServer上面请求

一个访问token。使用这个token,访问ApiServer的各个接口。


如上图: IdentityServer4 需要增加IdentityServer4 框架的引用,同时webapiserver,需要增加IdentityServer4 .AccessTokenValidation的引用,客户端可以通过多种方式,请求。可以参考git上面的sample。我这里使用的控制台程序测试用,Client 引入identityModel  的引用。

下面搭建框架:

1 首先是identityserver4 ,主要是从demo里改写配置即可。基本不需要增加代码。

在Startup.cs 中 配置IdentityServer4

        public void ConfigureServices(IServiceCollection services)        {            services.AddDeveloperIdentityServer()                .AddInMemoryScopes(Config.GetScopes())                .AddInMemoryClients(Config.GetClients());        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)        {            app.UseIdentityServer();        }
在Config中配置可用的client,注意AllowdGrantTypes 是ClientCredentials类型的。

        public static IEnumerable<Client> GetClients()        {            List<Client> lst = new List<Client>();            var client = new Client()            {                ClientId = setting.ClientID,                AllowedGrantTypes = GrantTypes.ClientCredentials,                ClientSecrets =                    {                        new Secret(setting.SercetKey.Sha256())                    },                AccessTokenLifetime = setting.TokenLiftTime * 3600, //AccessToken的过期时间, in seconds                 AllowedScopes = { setting.APPName }            };            lst.Add(client);            return lst;                   }

2 webapi 服务配置

由于新的identityserver4都是可以基于.net core平台的,发布在iis上使用useIISintegration属性代替useUrls。

        public static void Main(string[] args)        {            var host = new WebHostBuilder()                .UseKestrel()                .UseIISIntegration()  //.UseUrls("http://localhost:5001")                 .UseContentRoot(Directory.GetCurrentDirectory())                .UseIISIntegration()                .UseStartup<Startup>()                .Build();            host.Run();        }

然后在Startup.cs 中 配置需要绑定的授权服务器的ip。即修改 Authority属性,指定apiName,这些信息都是会被写到token的签名里,所以一个字符

都不能错。否则,n多的401错误。unauthroity

publicvoid Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {            loggerFactory.AddConsole(Configuration.GetSection("Logging"));            loggerFactory.AddDebug();              app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions            {                Authority = Configuration["Server"],                RequireHttpsMetadata = false,               // BackChannelTimeouts = t                ApiName = "TempSenGoApi"            });            app.UseCors("any");            app.UseMvc();        }

下面我们来定义API,添加一个Web API 控制器 ClientController  使用 【Authorize】注释来标记类。则token的验证全部由框架完成。如果token验证通过,则进入get action的代码中,进行业务逻辑的处理,如果验证非法。则不会进入get的代码里。

[Route("api/[controller]")]
    [Authorize]    public class ClientController : Controller    {        [HttpGet]        public IActionResult Get()        {            return new JsonResult(from c in User.Claims select new { c.Type, c.Value });        }    }
3.请求token

客户端代码如下:

publicstaticvoid Main(string[] args)
        {            //访问授权服务器获取token            var disco = DiscoveryClient.GetAsync("http://localhost:5000").Result;            var tokenClient = new TokenClient(disco.TokenEndpoint, "linezeroclient", "secret");            var tokenResponse = tokenClient.RequestClientCredentialsAsync("zeroapi").Result;                        //设置token 访问API tokenResponse.AccessToken 就是请求到的token,可以使用这个token访问webapi            var client = new HttpClient();            client.SetBearerToken(tokenResponse.AccessToken);            var response = client.GetAsync("http://localhost:5001/api/Identity").Result;            if (!response.IsSuccessStatusCode)            {                Console.WriteLine(response.StatusCode);            }            var content = response.Content.ReadAsStringAsync().Result;            Console.WriteLine(content);            Console.ReadKey();        }
4 使用postman测试该token。


总结: 我理解的处理流程是这样的。token存储在identityserver4服务器上而不是临时存储,比如内存中,就算服务器重新启动,token依旧有效。只依赖于token本身的内容,时候过期。当应用client请求到了token以后,在head中加入token。请求发送给webapi,webapi中的AccessTokenValidation 会将token实时发送给identityserver4,去验证。验证通过后,进入action的处理函数中。也就是说无论webapi重新启动,还是identityserver4重新启动,都不会使token过期。

做完才发现个不错的帖子。也可以参考。

原创粉丝点击