[ New addition] Source code corresponding to this article ( Multipleflow, clients, callpython api): 

Currently in useasp.net core 2.0 ( Mainlyweb api) Make a project, Some functions need to be usedjs Client callpython Ofpandas,
So we need to build apython Of rest api, I chose it for the time beinghug, The official website is here.:http://www.hug.rest/

The current project usesidentity server 4, Some moreweb api andjs client.

Early background source code of the project: https://github.com/solenovex/asp.net-core-2.0-web-api-boilerplate

Start configuration belowidentity server 4, I usewindows.

Add toApiResource:

stay authorization server Add red section to profile in project, This part ispython hug Of 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", " Procurement and raw material warehouseAPI") { UserClaims = { JwtClaimTypes.Name,
JwtClaimTypes.PreferredUserName, JwtClaimTypes.Email } },new
ApiResource("hugapi", "Hug API") { UserClaims = { JwtClaimTypes.Name,
JwtClaimTypes.PreferredUserName, JwtClaimTypes.Email } } }; }
modifyjs Client Configuration:
// 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.Email, SalesApiSettings.ApiName,"hugapi"
} }
modifyjs Client sideoidc client configuration option:

Add to hugapi, Andauthorization server Configuration correspondence.
{ authority: 'http://localhost:5000', client_id: 'sales', redirect_uri:
'http://localhost:4200/login-callback', response_type: 'id_token token', scope:
'openid profile salesapihugapi 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 }) }
establishPython Hug api

( Optional) installvirtualenv:
pip install virtualenv
And then create a directory somewhere:
mkdir hugapi && cd hugapi
Build a virtual environment:
virtualenv venv
Activate virtual environment:
And then it's about like this:

pip install hug
Then, Referencehug Documents. Then build a simpleapi. create filemain.py:
import hug @hug.get('/home') def root(): return 'Welcome home!'
hug -f main.py
The result is easy to use.:

And then you need to install these:
pip install cryptography pyjwt hug_middleware_cors
amongpyjwt It's a yesencode anddecode JWT Library, If usedRS256 Algorithm, Installation is also requiredcryptography. 

andhug_middleware_cors yeshug A cross domain access middleware based on( becausejs Client and thisapi Not under the same domain name).

Add required references:
import hug import jwt import json import urllib.request from jwt.algorithms
import get_default_algorithms from hug_middleware_cors import CORSMiddleware
And the right thing to do is to go throughAuthorization Server Ofdiscovery endpoint To findjwks_uri,

identity server 4 Ofdiscovery endpoint The address is:

<http://localhost:5000/.well-known/openid-configuration>, It can find all kinds of nodes and information:


But I'll just write it downjwks_uri bar:
response = urllib.request.urlopen('
http://localhost:5000/.well-known/openid-configuration/jwks') still_json =
identity server 4 Ofjwks_uri, Inside ispublic key, It's structured like this:

And I usejwt library, The parameter of can only be passed to thejson, Or that iskeys[0].

So the last line of code above looks a little bit.......

If usedpython-jose This library will be simpler, But in mewindows Always fail to install on your computer, So it's a good ideapyjwt bar.

Then lethug api Usecors middleware:
api = hug.API(__name__) api.http.add_middleware(CORSMiddleware(api))
And thenhug Ofauthentication Part:
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 =
adoptrsa.from_jwk(json) Will getkey (certificate),
Then passjwt.decode Methodstoken Verify anddecode, Algorithm isRS256, This method requires that iftoken It containsaud,
Then the method needs to be specifiedaudience, that ishugapi.

Last modificationapi Method, Plus validation:
@hug.get('/home', requires=token_key_authentication) def root(): return '
Welcome home!'
Last run hug api:
hug -f main.py
Port should be8000.

Functionjs Client, Land, And call thishug api http://localhost:8000/home:

( Myjs Client isangular5 Of, This is not open source, Company property, But configurationoidc-client It's still very simple, Use)

Return200, Content is: 

To glance athug Oflog:

token Verified and parsed correctly. So you can enterroot Method.

Otherpython api frame, It's the same thing.

[ New addition]  Source code corresponding to this article ( Multipleflow, clients, callpython api): 

You can use this example to build your own


There's another officialnodejs api Example: https://github.com/lyphtec/idsvr4-node-jwks

Today's revised code: 
import json import hug import jwt import requests from jwt.algorithms import
get_default_algorithmsfrom hug_middleware_cors import CORSMiddleware api =
hug.API(__name__) api.http.add_middleware(CORSMiddleware(api)) def
token_verify(token): access_token= token.replace('Bearer ', '') token_header =
jwt.get_unverified_header(access_token) res= requests.get( '
http://localhost:5000/.well-known/openid-configuration') jwk_uri = res.json()['
jwks_uri'] res = requests.get(jwk_uri) jwk_keys = res.json() rsa =
get_default_algorithms()['RS256'] key = json.dumps(jwk_keys['keys'][0])
public_key= rsa.from_jwk(key) try: result = jwt.decode(access_token,
public_key, algorithms=[ token_header['alg']], audience='api1') return result
except jwt.DecodeError: return False token_key_authentication =
hug.authentication.token(token_verify) @hug.get('/identity', requires=
token_key_authentication)def root(user: hug.directives.user): print(user) return
  My blog will be moved to Tencent cloud soon+ Community, Invite everyone to settle in together:https://cloud.tencent.com/developer/support-plan