接上一篇:IdentityServer4实现OAuth2.0四种模式之隐藏模式javascript
受权码模式隐藏码模式最大不一样是受权码模式不直接返回token,而是先返回一个受权码,而后再根据这个受权码去请求token。这比隐藏模式更为安全。从应用场景上来区分的话,隐藏模式适应于全前端的应用,受权码模式适用于有后端的应用,由于客户端根据受权码去请求token时是须要把客户端密码转进来的,为了不客户端密码被暴露,因此请求token这个过程须要放在后台。html
1,添加客户端前端
新建一个支持受权码模式的客户端,请求token时须要客户端密码,因此须要设置clientSecret。登陆成功后重定向地址依然用以前创建的HTML页面。java
new Client() { //客户端Id ClientId="apiClientCode", ClientName="ApiClient for Code", //客户端密码 ClientSecrets={new Secret("apiSecret".Sha256()) }, //客户端受权类型,Code:受权码模式 AllowedGrantTypes=GrantTypes.Code, //容许登陆后重定向的地址列表,能够有多个 RedirectUris = {"https://localhost:5002/auth.html"}, //容许访问的资源 AllowedScopes={ "secretapi" } }
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script type="text/javascript"> var content = ""; window.onload = function () { var url = window.location.href; var array = url.split("#"); if (array.length > 1) { content = array[1]; } var search = window.location.search; if (search) { search = search.substr(1); var paras = search.split("&"); paras.forEach(element => { content += element; content+=";" }); } document.getElementById("content").innerHTML = content; } </script> </head> <body> <div id="content"></div> </body> </html>
根据OAuth2.0协议,传递如下参数,传递地址仍是参数IdentityServer4的Discover说明中的authorization_endpoint节点值http://localhost:5000/connect/authorizejson
client_id:客户端Id redirect_uri=重定向Url,用户登陆成功后跳回此地址 response_type=code,固定值,表示获取受权码 scope=secretapi,此token须要访问的api
拼接url:http://localhost:5000/connect/authorize?client_id=apiClientCode&redirect_uri=https://localhost:5002/auth.html&response_type=code&scope=secretapi后端
在浏览器中访问此url,会跳转到用户登陆界面,用以前建立的用户apiUser和密码登陆后浏览器会自动跳转回设置的重定向Urlapi
能够看到已经取到了code。浏览器
public async Task<IActionResult> GetData(string type,string userName,string password,string code) { type = type ?? "client"; var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000"); if (disco.IsError) return new JsonResult(new { err=disco.Error}); TokenResponse token = null; switch (type) { case "client": token = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest() { //获取Token的地址 Address = disco.TokenEndpoint, //客户端Id ClientId = "apiClientCd", //客户端密码 ClientSecret = "apiSecret", //要访问的api资源 Scope = "secretapi" }); break; case "password": token = await client.RequestPasswordTokenAsync(new PasswordTokenRequest() { //获取Token的地址 Address = disco.TokenEndpoint, //客户端Id ClientId = "apiClientPassword", //客户端密码 ClientSecret = "apiSecret", //要访问的api资源 Scope = "secretapi", UserName =userName, Password = password }); break; case "code": token = await client.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest() { Address = disco.TokenEndpoint, ClientId = "apiClientCode", //客户端密码 ClientSecret = "apiSecret", Code = code, RedirectUri = "https://localhost:5002/auth.html" }); break; } if (token.IsError) return new JsonResult(new { err = token.Error }); client.SetBearerToken(token.AccessToken); string data = await client.GetStringAsync("https://localhost:5001/api/identity"); JArray json = JArray.Parse(data); return new JsonResult(json); }
直接访问:https://localhost:5002/home/getdata?type=code&code=93516f5af0c644c13228a66954d6c892816d358704536b6ca4e6623f6b00dee0安全
根据OAuth2.0协议,传如下参数,地址则是以前在客户端模式和密码模式获取token时用到的地址,能够在identityServer4的discover文档中找到。async
client_id:客户端Id client_secret:客户端密码 grant_type:authorization_code,固定值 redirect_uri=重定向Url,用户登陆成功后跳回此地址 code:获取到的受权码 scope=secretapi,此token须要访问的api
获取到token就能够访问api了。
四种模式讲完,IdentityServer.Config.GetIdentityResouce还没用上呢!由于这四种模式只涉及到IdentityServer4的OAuth2.0特性,OpenId部分尚未涉及,请看下一篇
。