ASP .NET Core Web Api + Angular

Identity Server 4

2018-10-24  本文已影响129人  xtddw

准备

  1. 建立Identity Provider项目

创建项目

   //注册Hsts
            services.AddHsts(options =>
            {
                options.Preload = true;
                options.IncludeSubDomains = true;
                options.MaxAge = TimeSpan.FromDays(60);
            });

            //配置HTTP重定向
            services.AddHttpsRedirection(options =>
            {
                options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
                options.HttpsPort = 6001;
            });

MVC 测试

  1. 身份认证请求


  1. Hybrid Flow


    Hybrid Flow

code demo

  1. 新建MVC
  2. 修改端口为7000,7001
  3. 修改Idp项目config.cs
 new Client
                {
                    ClientId = "mvcclient",
                    ClientName = "MVC客户端",

                    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
                    ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) },

                    RedirectUris = { "http://localhost:7001/signin-oidc" },
                    FrontChannelLogoutUri = "http://localhost:7001/signout-oidc",
                    PostLogoutRedirectUris = { "http://localhost:7001/signout-callback-oidc" },

                    AllowOfflineAccess = true, //offline_access(refresh token)
                    AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId }// { "openid", "profile", "api1" }
                },
  1. 修改mvc项目Startup
  public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });


            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);


            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

            services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            })
                .AddCookie("Cookies", options =>
                {
                    options.AccessDeniedPath = "/Authorization/AccessDenied";
                })
                .AddOpenIdConnect("oidc", options =>
                {
                    options.SignInScheme = "Cookies";
                    options.Authority = "https://localhost:6001";
                    options.RequireHttpsMetadata = true;
                    options.ClientId = "mvcclient";
                    options.ResponseType = "code id_token";
                    options.Scope.Clear();
                    options.Scope.Add("openid"); //与Idp中config对应
                    //options.Scope.Add("profile");
                    //options.Scope.Add("email");
                    //options.Scope.Add("restapi");

                    options.SaveTokens = true;
                    options.ClientSecret = "49C1A7E1-0C79-4A89-A3D6-A37998FB86B0";
                    options.GetClaimsFromUserInfoEndpoint = true;
                });
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseAuthentication();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
  1. HomeController 测试
 [Authorize]
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
  ......
跳转验证
  1. 添加更多获取资源
 public async Task<IActionResult> About()
        {
            var idToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.IdToken);

            ViewData["idToken"] = idToken;

            return View();
        }
  1. Config.cs添加
  public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new IdentityResource[]
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
                new IdentityResources.Email(),
            };
        }
 public static IEnumerable<ApiResource> GetApis()
        {
            return new ApiResource[]
            {
                new ApiResource("restapi", "My RESTful API")
            };
        }
   AllowOfflineAccess = true, //offline_access(开启refresh token)
   AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        IdentityServerConstants.StandardScopes.Email,
                        "restapi"
                    }// { "openid", "profile", "api1" }
  1. 修改html
@{
    ViewData["Title"] = "About";
}
<h2>@ViewData["Title"]</h2>
<h3>IdToken:@ViewData["idToken"]</h3>

<dl>
    @foreach (var claim in User.Claims)
    {
        <dt>@claim.Type</dt>
        <dd>@claim.Value</dd>
    }
</dl>

保护API资源

  1. 安装包 `IdentityServer4.AccessTokenValidation
  2. 注册
 // 注册IdentityServer
            services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = "https://localhost:6001";
                    options.ApiName = "restapi";
                });

  1. config
    app.UseAuthentication();
  2. api中加验证
    • 属性标签 [Authorize]
    • 全局filter
  //设置全局filter保护api需要认真用户才可访问
            services.Configure<MvcOptions>(options =>
            {
                var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            });
  1. NoAuth


    401 error
  2. MVC客户端
  public async Task<IActionResult> Contact()
        {
            var httpClient = new HttpClient
            {
                BaseAddress = new Uri("https://localhost:5001")
            };
            httpClient.DefaultRequestHeaders.Clear();
            httpClient.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/vnd.enfi.hateoas+json")
                );

            var accessToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.AccessToken);
            ViewData["accessToken"] = accessToken;
            httpClient.SetBearerToken(accessToken);

            var res = await httpClient.GetAsync("api/posts").ConfigureAwait(false);
            if (res.IsSuccessStatusCode)
            {
                var json = await res.Content.ReadAsStringAsync().ConfigureAwait(false);
                var objects = JsonConvert.DeserializeObject<dynamic>(json);
                ViewData["json"] = objects;
                return View();
            }
            if (res.StatusCode == HttpStatusCode.Unauthorized)
            {
                return RedirectToAction("AccessDenied", "Authorization");
            }
            throw new Exception($"Error Occurred:${res.ReasonPhrase}");
        }
 public class AuthorizationController : Controller
    {
        public IActionResult AccessDenied()
        {
            return View();
        }
    }
@{ViewData["Title"] = "AccessDenied";}
<div class="container">
    <h2>Access Denied</h2>
</div>
  1. https://jwt.io 网站解析token
上一篇 下一篇

猜你喜欢

热点阅读