项目的早期后台源码: https://github.com/solenovex/asp.net-core-2.0-web-api-boilerplate
下面开始配置identity server 4, 我使用的是windows.
添加ApiResource:
在 authorization server项目中的配置文件添加红色部分, 这部分就是python hug 的 api:
public static IEnumerable GetApiResources()
{
return new List
{
new ApiResource(SalesApiSettings.ApiName, SalesApiSettings.ApiDisplayName) {
UserClaims = { JwtClaimTypes.Name, JwtClaimTypes.PreferredUserName, JwtClaimTypes.Email }
},
new ApiResource("purchaseapi", "采购和原料库API") {
UserClaims = { JwtClaimTypes.Name, JwtClaimTypes.PreferredUserName, JwtClaimTypes.Email }
},
new ApiResource("hugapi", "Hug API") {
UserClaims = { JwtClaimTypes.Name, JwtClaimTypes.PreferredUserName, JwtClaimTypes.Email }
}
};
}
修改js Client的配置:
// Sales JavaScript Client
new Client
{
ClientId = SalesApiSettings.ClientId,
ClientName = SalesApiSettings.ClientName,
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
AccessTokenLifetime = 60 * 10,
AllowOfflineAccess = true,
RedirectUris = { $"/login-callback", $"/silent-renew.html" },
PostLogoutRedirectUris = { Startup.Configuration["MLH:SalesApi:ClientBase"] },
AllowedCorsOrigins = { Startup.Configuration["MLH:SalesApi:ClientBase"] },
AlwaysIncludeUserClaimsInIdToken = true,
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
SalesApiSettings.ApiName,
"hugapi"
}
}
修改js客户端的oidc client配置选项:
添加 hugapi, 与authorization server配置对应.
{
authority: 'http://localhost:5000',
client_id: 'sales',
redirect_uri: 'http://localhost:4200/login-callback',
response_type: 'id_token token',
scope: 'openid profile salesapi hugapi email',
post_logout_redirect_uri: 'http://localhost:4200',
silent_redirect_uri: 'http://localhost:4200/silent-renew.html',
automaticSilentRenew: true,
accessTokenExpiringNotificationTime: 4,
// silentRequestTimeout:10000,
userStore: new WebStorageStateStore({ store: window.localStorage })
}
建立Python Hug api
(可选) 安装virtualenv:
pip install virtualenv
然后在某个地方建立一个目录:
mkdir hugapi && cd hugapi
建立虚拟环境:
virtualenv venv
激活虚拟环境:
venv\Scripts\activate
然后大约这样显示:
安装hug:
pip install hug
这时, 参考一下hug的文档. 然后建立一个简单的api. 建立文件main.py:
运行:
hug -f main.py
结果好用:
然后还需要安装这些:
pip install cryptography pyjwt hug_middleware_cors
其中pyjwt是一个可以encode和decode JWT的库, 如果使用RS256算法的话, 还需要安装cryptography.
而hug_middleware_cors是hug的一个跨域访问中间件(因为js客户端和这个api不是在同一个域名下).
添加需要的引用:
import hug
import jwt
import json
import urllib.request
from jwt.algorithms import get_default_algorithms
from hug_middleware_cors import CORSMiddleware
然后正确的做法是通过Authorization Server的discovery endpoint来找到jwks_uri,
identity server 4 的discovery endpoint的地址是:
http://localhost:5000/.well-known/openid-configuration, 里面能找到各种节点和信息:
但我还是直接写死这个jwks_uri吧:
response = urllib.request.urlopen('http://localhost:5000/.well-known/openid-configuration/jwks')still_json = json.dumps(json.loads(response.read())['keys'][0])
identity server 4的jwks_uri, 里面是public key, 它的结构是这样的:
而我使用jwt库, 的参数只能传入一个证书的json, 也可就是keys[0].
所以上面的最后一行代码显得有点.......
如果使用python-jose这个库会更简单一些, 但是在我windows电脑上总是安装失败, 所以还是凑合用pyjwt吧.
然后让hug api使用cors中间件:
然后是hug的authentication部分:
def token_verify(token):
token = token.replace('Bearer ', '')
rsa = get_default_algorithms()['RS256']
cert = rsa.from_jwk(still_json)
try:
result = jwt.decode(token, cert, algorithms=['RS256'], audience='hugapi')
print(result)
return result
except jwt.DecodeError:
return False
通过rsa.from_jwk(json) 就会得到key (certificate), 然后通过jwt.decode方法可以把token进行验证并decode, 算法是RS256, 这个方法要求如果token里面包含了aud, 那么方法就需要要指定audience, 也就是hugapi.
最后修改api 方法, 加上验证:
@hug.get('/home', requires=token_key_authentication)defroot():return'Welcome home!'
最后运行 hug api:
hug-fmain.py
端口应该是8000.
运行js客户端,登陆, 并调用这个hug api http://localhost:8000/home:
(我的js客户端是angular5的, 这个没法开源, 公司财产, 不过配置oidc-client还是很简单的, 使用)
返回200, 内容是:
看一下hug的log:
token被正确验证并解析了. 所以可以进入root方法了.
其他的python api框架, 都是同样的道理.
可以使用这个例子自行搭建 https://github.com/IdentityServer/IdentityServer4.Samples/tree/release/Quickstarts/7_JavaScriptClient
官方还有一个nodejs api的例子: https://github.com/lyphtec/idsvr4-node-jwks
本文来自企鹅号 - dotNET跨平台媒体
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文来自企鹅号 - dotNET跨平台媒体
如有侵权,请联系 cloudcommunity@tencent.com 删除。