您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)如何用Identity Server 4來保護(hù) Python web api,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
目前正在使用asp.net core 2.0 (主要是web api)做一個(gè)項(xiàng)目, 其中一部分功能需要使用js客戶端調(diào)用python的pandas, 所以需要建立一個(gè)python 的 rest api, 我暫時(shí)選用了hug, 官網(wǎng)在這: http://www.hug.rest/.
目前項(xiàng)目使用的是identity server 4, 還有一些web api和js client.
項(xiàng)目的早期后臺(tái)源碼: https://github.com/solenovex/asp.net-core-2.0-web-api-boilerplate
下面開始配置identity server 4, 我使用的是windows.
在 authorization server項(xiàng)目中的配置文件添加紅色部分, 這部分就是python hug 的 api:
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
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 }
}
};
}
// Sales JavaScript Client
new Client
{
ClientId = SalesApiSettings.ClientId,
ClientName = SalesApiSettings.ClientName,
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
AccessTokenLifetime = 60 * 10,
AllowOfflineAccess = true,
RedirectUris = { $"{Startup.Configuration["MLH:SalesApi:ClientBase"]}/login-callback", $"{Startup.Configuration["MLH:SalesApi:ClientBase"]}/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"
}
}
添加 hugapi, 與authorization server配置對(duì)應(yīng).
{
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 })
}
(可選) 安裝virtualenv:
pip install virtualenv
然后在某個(gè)地方建立一個(gè)目錄:
mkdir hugapi && cd hugapi
建立虛擬環(huán)境:
virtualenv venv
激活虛擬環(huán)境:
venv\Scripts\activate
然后大約這樣顯示:
安裝hug:
pip install hug
這時(shí), 參考一下hug的文檔. 然后建立一個(gè)簡單的api. 建立文件main.py:
import hug @hug.get('/home')def root(): return 'Welcome home!'
運(yùn)行:
hug -f main.py
結(jié)果好用:
然后還需要安裝這些:
pip install cryptography pyjwt hug_middleware_cors
其中pyjwt是一個(gè)可以encode和decode JWT的庫, 如果使用RS256算法的話, 還需要安裝cryptography.
而hug_middleware_cors是hug的一個(gè)跨域訪問中間件(因?yàn)閖s客戶端和這個(gè)api不是在同一個(gè)域名下).
添加需要的引用:
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來找到j(luò)wks_uri,
identity server 4 的discovery endpoint的地址是:
http://localhost:5000/.well-known/openid-configuration, 里面能找到各種節(jié)點(diǎn)和信息:
但我還是直接寫死這個(gè)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, 它的結(jié)構(gòu)是這樣的:
而我使用jwt庫, 的參數(shù)只能傳入一個(gè)證書的json, 也可就是keys[0].
所以上面的最后一行代碼顯得有點(diǎn).......
如果使用python-jose這個(gè)庫會(huì)更簡單一些, 但是在我windows電腦上總是安裝失敗, 所以還是湊合用pyjwt吧.
然后讓hug api使用cors中間件:
api = hug.API(__name__) api.http.add_middleware(CORSMiddleware(api))
然后是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
token_key_authentication = hug.authentication.token(token_verify)
通過rsa.from_jwk(json) 就會(huì)得到key (certificate), 然后通過jwt.decode方法可以把token進(jìn)行驗(yàn)證并decode, 算法是RS256, 這個(gè)方法要求如果token里面包含了aud, 那么方法就需要要指定audience, 也就是hugapi.
最后修改api 方法, 加上驗(yàn)證:
@hug.get('/home', requires=token_key_authentication)def root(): return 'Welcome home!'
最后運(yùn)行 hug api:
hug -f main.py
端口應(yīng)該是8000.
運(yùn)行js客戶端,登陸, 并調(diào)用這個(gè)hug api http://localhost:8000/home:
(我的js客戶端是angular5的, 這個(gè)沒法開源, 公司財(cái)產(chǎn), 不過配置oidc-client還是很簡單的, 使用)
返回200, 內(nèi)容是:
看一下hug的log:
token被正確驗(yàn)證并解析了. 所以可以進(jìn)入root方法了.
其他的python api框架, 都是同樣的道理.
可以使用這個(gè)例子自行搭建 https://github.com/IdentityServer/IdentityServer4.Samples/tree/release/Quickstarts/7_JavaScriptClient
關(guān)于如何用Identity Server 4來保護(hù) Python web api就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。