require 'openid_connect' | |
require 'readline' | |
OpenIDConnect.debug! | |
def scopes_for(rs_alias) | |
['common', rs_alias].collect do |scope| | |
File.join 'https://sts4b2c.onmicrosoft.com/', rs_alias, scope | |
end | |
end | |
def inspect_jwt(jwt) | |
puts JSON.pretty_generate(jwt.header) | |
puts '.' | |
puts JSON.pretty_generate(jwt) | |
puts | |
end | |
# NOTE: "RS and Client" | |
client_id = '10a39a6d-c0e8-48b5-b2c2-dc1857749479' | |
client_secret = 'vEh14E[9[jBE0#$L' | |
redirect_uri = 'http://localhost:8000/callback' | |
# # NOTE: "Client" | |
# client_id = '896d6087-5609-4cc7-b762-0a9ccfa71582' | |
# client_secret = ';9N955bj*7H~d9l*' | |
# redirect_uri = 'http://localhost:8000/callback' | |
issuer = 'https://login.microsoftonline.com/11ca5489-95d3-40ba-9041-9e98c26047e2/v2.0' | |
policy_id = 'b2c_1_sign_in' | |
op_config = OpenIDConnect::Discovery::Provider::Config.discover!(issuer).tap do |config| | |
# NOTE: p=policy_id is REQUIRED, and MUST be in query, not body. | |
config.token_endpoint << "?p=#{policy_id}" | |
config.authorization_endpoint << "?p=#{policy_id}" | |
config.jwks_uri << "?p=#{policy_id}" | |
end | |
client = OpenIDConnect::Client.new( | |
identifier: client_id, | |
secret: client_secret, | |
authorization_endpoint: op_config.authorization_endpoint, | |
token_endpoint: op_config.token_endpoint, | |
userinfo_endpoint: op_config.userinfo_endpoint, | |
redirect_uri: redirect_uri | |
) | |
jwks = op_config.jwks | |
# NOTE: Azure AD B2C doesn't support access token with multiple audiences | |
# rs_aliases = ['rs1', 'rs2'] | |
# scopes = rs_aliases.collect { |rs_alias| scopes_for(rs_alias) }.flatten | |
# NOTE: 'rs1', 'rs2' or 'rs-and-client' | |
scopes = scopes_for('rs-and-client') | |
puts '# Requested Scopes' | |
puts scopes | |
puts | |
authorization_uri = client.authorization_uri( | |
scope: scopes, | |
nonce: SecureRandom.hex(8), | |
# response_type: [:token, :id_token] | |
) | |
puts '# Redirecting to...' | |
puts authorization_uri | |
`open "#{authorization_uri}"` | |
puts | |
print 'code: ' and STDOUT.flush | |
code = Readline.readline.strip # NOTE: `gets` can't receive 1024+ bytes input | |
puts | |
client.authorization_code = code | |
response = client.access_token! :body | |
access_token = JSON::JWT.decode response.access_token, jwks | |
id_token = JSON::JWT.decode response.id_token, jwks | |
puts '# Access Token' | |
inspect_jwt access_token | |
puts '# ID Token' | |
inspect_jwt id_token |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment