Application User Roles with Azure B2C
Summary
TLDR本视频教程介绍了如何在Azure B2C中使用API连接器来实现用户角色和权限管理。尽管Azure B2C本身不支持用户角色,但通过API连接器,我们可以在身份验证过程中添加自定义声明,实现不同用户访问不同应用部分的功能。视频详细演示了如何开发本地API连接器,设置反向代理以及在Azure B2C中配置API连接器。此外,还展示了如何在前端和后端应用中利用这些角色信息来控制用户访问权限。
Takeaways
- 😀 使用Azure B2C的API连接器可以实现用户角色的自定义,从而控制用户访问应用程序或后端API的不同部分。
- 🔒 Azure B2C本身不支持开箱即用的用户角色,但可以通过API连接器来实现角色控制。
- 🌐 API连接器允许Azure B2C在用户认证过程中调用外部API,以添加额外的声明(claims)到用户凭证中。
- 🔑 被调用的API必须是公开可访问的HTTPS端点,并且需要有证书支持。
- 🛠️ 开发者可以通过设置反向代理函数,使得本地开发环境能够模拟API连接器的行为,便于本地开发和测试。
- 🏠 在本地开发时,可以通过端口转发将本地Azure函数暴露到互联网上,并通过反向代理与Azure B2C通信。
- 📝 在Azure门户中设置API连接器时,需要指定Azure函数的URL和要调用的特定函数,如用户权限函数。
- 🔄 部署到生产环境时,需要重新配置Azure B2C,使其直接调用已发布的API函数,以添加自定义声明。
- 🔑 在Next.js应用中,可以通过检查ID令牌中的自定义声明来控制用户界面的显示,如仅对具有管理员角色的用户显示管理员链接。
- 🛡️ 在API层面,可以通过中间件检查访问令牌中的用户角色,以限制对特定Azure函数的访问,确保只有具有相应角色的用户才能调用。
Q & A
Azure B2C是否原生支持用户角色功能?
-Azure B2C原生并不支持用户角色功能,但可以通过API连接器来实现类似功能。
API连接器在Azure B2C中的作用是什么?
-API连接器允许Azure B2C在用户认证过程中调用外部API,该API可以添加额外的声明(claims),这些声明随后会被注入到用户的令牌中。
API连接器调用的API有哪些要求?
-API连接器调用的API必须是公共端点,并且是HTTPS端点,即需要有证书安装。
如何在本地开发环境中使用API连接器?
-可以通过设置反向代理功能,将本地开发机器暴露到互联网上,使得Azure B2C能够调用本地API连接器。
如何将本地Azure函数暴露到互联网上?
-可以通过路由器的端口转发功能,将本地Azure函数运行的内部IP地址和端口转发到外部端口。
创建Azure函数的反向代理时需要注意什么?
-需要配置反向代理函数以接受要代理到的函数名称作为URL的查询参数,并确保正确设置了代理API主机的环境变量。
如何在Azure门户中设置API连接器?
-需要在Azure门户中找到API连接器选项,添加新的API连接器,并配置其指向正确的Azure函数以及必要的安全凭证。
如何在用户流程中使用API连接器?
-在用户流程中,需要在API连接器部分选择之前设置的API连接器,并在应用声明中添加自定义声明,以便在用户登录过程中调用API连接器。
如何在Next.js应用中利用用户角色信息?
-可以在Next.js的用户存储中添加一个方法来检查用户是否具有特定的权限,然后在UI组件中根据用户角色显示或隐藏相应的链接。
如何在Azure函数API中实现基于角色的授权?
-可以在Azure函数的授权中间件中添加对用户角色的检查,确保调用者具有正确的角色和权限范围。
Outlines
🔒 使用Azure B2C实现用户角色和权限管理
本段介绍了如何使用Azure B2C的用户角色功能来管理不同用户的权限,以便他们可以访问应用程序或后端API的不同部分。尽管Azure B2C官方不支持开箱即用的用户角色,但可以通过API连接器实现。API连接器允许Azure B2C在用户认证过程中调用外部API,以添加额外的声明(claims)到用户的凭证中。视频还讨论了开发本地化时如何使用反向代理功能,以及如何将这些功能部署到生产环境。
🛠️ 构建本地开发环境的反向代理
这一段详细说明了如何设置本地开发环境中的反向代理,以便可以从互联网访问Azure函数。介绍了如何通过路由器设置端口转发,以及如何在Visual Studio Code中创建一个新的Azure函数来作为反向代理。这个代理将捕获对特定函数的调用,并将请求转发到本地开发机器上的对应API,然后再将响应返回给Azure B2C。
📝 创建API连接器以添加用户权限
本段讲述了如何创建一个名为'user permissions'的Azure函数,该函数通过接收POST请求来添加用户自定义权限。函数首先检查请求体是否正确反序列化,然后根据用户的身份验证信息添加相应的权限声明。此外,还介绍了如何在Azure门户中配置API连接器,以及如何将自定义属性添加到用户流中。
🔄 测试和部署API连接器
在这一段中,演示了如何测试和部署API连接器。通过在Azure门户中设置新的API连接器,并将其链接到之前创建的'user permissions' Azure函数。接着,介绍了如何在用户流中添加自定义声明,以及如何在应用程序中使用这些声明来控制对API的访问。
🏢 应用用户角色于前端和后端
本段讨论了如何在应用程序的前端和后端实现用户角色的应用。在前端,展示了如何根据用户的角色来显示或隐藏UI元素。在后端,介绍了如何修改API的授权中间件,以确保只有具有适当角色的用户才能访问特定的API端点。
👍 结束语和用户角色的保护
视频的最后一段是对如何使用Azure B2C实现用户角色和权限管理的总结。展示了如何测试前端和后端的用户角色保护,并鼓励观众如果发现视频有用,请点赞支持。最后,感谢观众的观看,并预告了下一个视频的内容。
Mindmap
Keywords
💡Azure B2C
💡用户角色
💡API连接器
💡HTTPs端点
💡自定义声明
💡反向代理
💡本地开发
💡访问令牌
💡JWT
💡权限验证
Highlights
使用Azure B2C API连接器实现用户角色和权限管理。
Azure B2C不支持开箱即用的用户角色,但可通过API连接器实现。
API连接器允许Azure B2C在身份验证过程中调用外部API,以添加额外的声明。
API必须为公共端点,并使用HTTPS协议。
介绍了如何在本地开发环境中使用反向代理功能来模拟API连接器。
通过反向代理,可以在本地开发时模拟Azure环境中的API连接器行为。
展示了如何在Visual Studio Code中设置和测试反向代理Azure函数。
解释了如何在Azure门户中配置反向代理的API主机环境变量。
演示了如何将本地开发的API连接器功能发布到Azure。
讨论了如何在Azure B2C中添加和配置API连接器。
介绍了如何在用户流程中添加自定义属性以使用API连接器返回的数据。
展示了如何在Azure函数中编写代码以根据用户角色添加自定义声明。
解释了如何在Next.js应用程序中使用用户角色数据来控制UI元素的显示。
演示了如何在API中使用用户角色数据来限制对特定端点的访问。
讨论了如何在生产环境中移除反向代理并直接调用添加了声明的API。
强调了用户角色和权限管理在保护Web应用和API安全中的重要性。
提供了如何在不同环境(开发、生产)中灵活配置API连接器的指导。
总结了使用Azure B2C API连接器实现用户角色和权限管理的整个流程。
Transcripts
if you want logged in users of your
website to have different permissions so
that they can access different parts of
your application or even your backend
API then you've come to the right place
because today we are going to be dealing
with user roles with azure b2c
[Music]
[Applause]
good morning good afternoon and good
evening whenever it is I find you and
welcome along to the channel so if you
Google for Azure b2c and user roles
you'll find generally a whole lot of
negativity around things that it says it
doesn't support user roles out of the
box
and while that's true there is a
mechanism in Azure b2c that we can
utilize for this purpose and that is API
connectors so what are API connectors so
the way that Azure b2c works is our
authenticating user goes across to or
gets redirected to azure b2c
Azure b2c can then call out to an API so
this API has got some constraints it
must be a public endpoint and it must
also be an HTTP s endpoint so it's got
to have a certificate installed
but this API function essentially adds
extra claims that it passes back to
Azure b2c so it can be any custom data
that your particular API wants to inject
into the user's credentials essentially
and they get injected into the token
that then gets sent back to your front
end
but there's a problem because it's all
great when it's up and running but how
do we develop this locally
so for the local situation we've got
Azure b2c still
and we've got our public endpoint so we
can use our API that we publish up to
Azure as part of our application
and we can actually put a reverse proxy
function into that API and that reverse
proxy function can then pull our local
development machine that we've exposed
out onto the internet
and that can do our custom claims at
that point pass it back through the
reverse proxy back to Azure b2c and into
the ID token and the access token this
means that we can develop locally and
work out what our claims should be and
get all that code working before we then
publish that up to our public API so
that what it looks like when we move to
production is that we remove that
reverse proxy function we reconfigure
Azure b2c to directly call our function
that just adds our claims that we've
been developing locally but now it
exists in our public API because we've
pushed that up and so this is what our
production architecture then looks like
we could choose to remove that reverse
proxy function at that point but
obviously you may want to develop again
locally to add enhancements to that
particular function so it might be
useful to to have that still inside your
API your decision
so let's go and dive in and see how we
can set all of this up so the first
thing that we're going to have to set up
is being able to access our Azure
function locally but from the internet
so I'm on my router here and you can see
that my
local Azure functions run on an internal
IP address on Port 7071 which is usually
the default for Azure functions in a
development environment
and you can see that I'm port forwarding
here from my external port on Port
quadruple 8. so any request that comes
into my internet IP address on Port
quadrupilate will forward across to my
Azure function API how you go about
setting this up is going to be a unique
situation for you there's all sorts of
weird and wonderful ways that people set
up their development environments these
days so I'm going to have to leave this
step to you but this is what works for
me so with that exposed we can jump over
into vs code and we can go to our API
Now API functions where we have all of
these and the first thing that we're
going to do is set up this reverse proxy
function that we're going to publish up
to our publicly exposed API so let's
create a new Azure function in here
which is our simple reverse proxy called
Simple reverse proxy it takes gets or
posts and what we need to do in here is
we're going to take the name of the
function that we want it to proxy across
to on the URL as a query argument
so that's why we're using this query
parameters dictionary here that I've got
in a utility function here in this query
parameters dictionary so this gets the
query parameter and teases those out
into a dictionary such that I can then
query for a given value so I'm looking
for a func query value on the URL so we
need somewhere where we can store our
response body as well then we'll have
some error handling so if bunk to call
doesn't actually
exist on the URL then we'll just return
an error a bad response or bad request
rather and then what we're going to do
is pull the configuration for where our
actual API is that we want to proxy
across to so in our case it's our our
Local Host one but it's going to be our
internet facing address
on that Port quadruple 8 for me that I'm
going to configure into this proxy API
host environment variable
so that's going to go into my local
settings Json file here so let's just go
and add that in while we're while we're
here and for now just to prove that the
simple reverse proxy Works locally it's
going to proxy across to localhost 7071
when we deploy to Azure we will set this
up in the Azure portal and that will
this will point to my public IP address
and quadruple 8 as the port we can save
that and close that and then let's carry
on with this function so we've got our
host environment variable but let's just
do some check-in to make sure that we
have configured that correctly and again
if we haven't then we'll send back an
error then we can start making our call
to our API so we need a new HTTP client
that's adding the right usings let's set
the Base address for our request to our
host and slash API which is where our
API lives we can then create a message
and we use the same
method the same HTTP verb that's been
sent in so if it's a post it will
forward as a post if it's a get it
before there's a get and we use our
function to call that we got out of our
query string up here as the function
that we want to call so then if it's a
post only because posts will contain a
request body then we do that so we get
the request body and we set that up as
the content of the message that we're
folding across we then make our call
and we get the response back into
an object here
and then
we can go ahead like we have done with
all our other Azure functions and create
a corresponding response from that and
put in that response body
so we send it back so that's essentially
just called an Azure function by calling
this Azure function so let's just run
that up and prove that that works so we
can see that we've got our new simple
reverse proxy function available to us
so I can come over to something like
thunderclion and put in a get request
give it a funk equals and the funk I
want to call is version so I can see
that I've got another API call called
version down here and if I send that in
I get back a 200 and the version
information has been returned correctly
so my reverse proxy is calling route
background to my own Azure API and
calling a separate function so that's
all working so that's good so we can
push this now up to Azure so that we get
our reverse proxy functionality
available in the cloud for us so I'm
going to go and do that and then we'll
come back and carry on while that's
deploying we can jump over to the Azure
portal and go to my static web app and
the configuration settings
and you need to add a new configuration
setting here I've already done it so
we're adding our proxy API host that we
had in our local settings and as I said
you want to configure this to your
public IP address and whatever Port
you're forwarding across to your
particular API so that's all now
deployed so I can go to my site that's
up on Azure and go to the API call
simple
RP and give it the funk that I want to
call and we'll call the version again
and on my local environment I've got my
Azure functions up and running and I've
got a breakpoint in the version function
so let's give that a go
and I can see down here
that Visual Studio is is flashing at me
saying that it's hit a break point so
let's go and we are inside of our
function
locally we've got our request coming in
so I'm just gonna let that run
jump back over here and I can see the
response has come back correctly from my
local Azure function so it's an internet
facing reverse proxy that's calling my
local development environment
which is nice
so that means I can now develop my API
connector function locally and set up
Azure b2c to call that reverse proxy but
we're going to get to all of that in a
bit so let's stop our API and let's go
and start on our API connector function
so we're going to have a function called
user permissions which takes a post and
I am going to cut some tutorial Corners
here like most people do we should
really have some authentication going on
in this particular function so out of
the box b2c for API connectors supports
basic author or certificate auth so you
should be validating that authentication
I'm going to skip over that just the
brevity of this tutorial because there's
enough here to show you how this all
works so given that you are
authenticated from Azure b2c to actually
call this API we can then get the
request body
as we normally do and we are going to
create this request connector class so
we're going to deserialize the request
body into a request connector object but
we'll create that in a minute we need to
do some usual error checking so if our
request connector isn't correctly
deserialized then we have to return
a set response
from our API connector to inform Azure
b2c to show a block page so it stops the
authentication at this point because our
API function has failed
and we return that as a bad response so
and if you want to see the information
on where I got this from so it's from
this page over here I'll put a link to
this in the description but it's about
adding an API connector to the sign up
user flow white sign up I'm signing in
and using it but anyway there we go and
there's this example responses section
down here so this is the example of a
good continuation response so this is
what you should return if you want the
login to continue along with your custom
attributes that you're adding in we'll
get to that in a minute so this is an
example of what I was just put in there
for the error so we share a block page
we put our error message in and version
so if we jump back over that's exactly
what mine looks like so that's our error
handling so at this point you could
perform any other validation that you
want against the payload things like
does the client ID match is the email
present Etc you you can do anything
inside your ISO function obviously so
add as much validation here as you want
to make sure that the consumer that's
calling this function is who they say
they are once you've passed all the
authentication and validation checks you
can then go and look up your custom
claims that you want to add in so I'm
hard coding this here but this might
typically be a database connection
lookup where you're going to find the
person who's actually logging in so you
get this claim coming in in the request
connector as we'll see in a minute and
at the moment I'm just checking if
that's admin then I go and add the admin
user role to the permissions so everyone
gets to be a user but only the admin
user gets to be admin is my simple case
here that I'm putting in but obviously
you can go and add in as many different
types of user permissions as you want
and I'm comma separating them here so
they all go into the same custom
property but comma delimited and then
finally the last thing that we need to
do inside this function is actually set
up that response with our custom claim
in it so we return a 200 response and we
return our
extra permission which is from our user
permissions comma delimited string
and we've called that user permissions
it has to have the extension prefix on
it that's a b2c convention so we have to
adhere to that and that's all we need to
do for our Azure function so let's go
and create a new file in here request
connector and let's just paste this in
so that we can see what this does so
here's our request connector class and
so we can see that we've just got some
properties in here basically and we are
renaming these so that they get
deserialized correctly so even though
we've called it client ID the Json that
will come in is client underscore ID so
we've renamed some of these locally
inside this object but essentially this
is what gets passed in the step the
client ID the UI locales the email
address which is the all-important one
because that's what we're using as our
ID to look up our permissions the object
ID which is the Azure object ID for this
particular user and some useful other
information like display name given name
Etc so we can now jump over to Azure b2c
in the Azure portal and we need to go to
this API connectors option here
and we add a new API connector we'll
give it a useful name and we'll give it
the name of our reverse proxy in here
and we can copy that from here and paste
that in there but we don't want the
version function we want user
permissions which is the Azure function
that we just created and we'll send in
some Basics so but we're not validating
it but we should be yeah so usual secure
credentials and we'll save that and then
we've got to go to user attributes to
add in our new
custom attribute so these are all the
default ones we're going to add in a new
one I'm going to call it user
permissions if you remember we had over
in our Azure function we called it use
permissions here
so that that has to match
and we'll make that a string give it
some useful description and create that
so now we have our user permissions down
here which is a custom type
and then we can go over to our
user flow that we used for sign in so
we've got our
sign in flow and we can go to
application claims and we can add in
and select that custom claim that we
just added and save that and then while
we're in the sign in user flow we go to
API connectors we can now see our user
permissions function in here that's
available to us so we can select that
and that's how we wire up b2c to call
that particular function
when it's creating the claims so as part
of the sign in process it will now call
out to this API that we've configured so
let's run all this up and give it a test
and we'll put a breakpoint in our user
permissions function just so that we can
see that it gets hit okay so our app is
up and running so we can this is our
local one so I'm running on localhost
I can sign in I get redirected to Azure
let's log in as the admin
in this particular case
and let's sign in and again I can see
I've hit a break point down in Visual
Studio code so let's go and jump in
there and here I am inside my user
permissions so let's just step over some
of this so we get our request body let's
go and have a look at that so we can see
exactly what that looks like and you can
see that the email address is the admin
has passed in so let's carry on so we
add in our user permissions but
essentially I've got a user an admin as
the user permissions that I'm sending
back so let's just run these through and
we'll probably find that my
authentication has failed because I've
taken too long so let's just now that
we've seen that up and running and
working let's take that out
take the break point out and let's try
that again
so that it runs through
as we would expect and that has signed
us in
and I've got some debug Trace in here so
we can go and look at the ID token
claims and we can see there's my
extension user permissions with user and
admin being passed back in the token
back to
the next application which is exactly
what we want the one on there
let's just go and get the access token
as well and if we come over to
jwt.ms and paste that in we have a look
at this here
we can see that we also get the
extension permissions passed into the
access token so that means that it's
available both to our client side next
application but also to our Azure
function API when we pass in the access
token so that's really handy that it
puts it into both tokens for us because
we can use that on both sides to make
sure that the user contains the right
roles to be able to do what they're
trying to do so that's all well and good
but we're obviously not taking any
advantage of that so how do we plug all
this now that we're getting these extra
user roles back into our next
application so let's get rid of the dev
tools let's come back over here and we
know our function API is now working so
we can now
close up the API side of this and start
looking at the next side of it and how
we can take advantage of some of this so
inside of our user store we've got our
auth user store
what we're going to do is add in a new
getter in here and we're going to ask if
the user has a particular permission so
it's going to query the token that it's
storing inside this store so we have to
pass in the required permission that we
want it to test for and that's going to
give us back a true or false result so
inside here we can have an if test that
says if we've got a current user and the
user
has the user permissions claim so what
we're going to do is we're going to look
in the user permissions string and we're
going to see if it contains the required
permission string that's been passed in
and if it does we return true so the
user has that permission and if it
doesn't we return false and if we don't
have a user or the user doesn't have any
user permissions claim in it then we are
just going to return false back out of
this method
so let's save that so then inside of
something like our header component and
we can now rather than always showing
this admin link let's change this so
that we only show the admin link if you
are in fact and a user that's got the
admin role so we need to import the auth
store in our script as we normally do
and then we can use the auth store to
get out the user has permission getter
and once we've done that that's then
available to us inside of our next
template up here
so we can put in a the if user has
permission and pass it the string of the
role that we want the user to possess in
order to show this particular next link
so let's save that so that's our app up
and running and as we can see we don't
see the admin menu here so let's go and
sign in let's
start by signing in as someone who's not
the admin so good old data just a
general user he can log in and welcome
Arthur Dent but he doesn't see the admin
menu but he does see restricted areas
because he is logged in and let's sign
him out let's sign back in as the admin
this time
the admin gets the admin user role and
so we see our admin link over here so
that's UI stuff inside of nux that you
can take advantage of the UI rolls quite
easily but what about our apis if we
want to restrict things in our API so
let's jump back over here
and we can get rid of these
so inside of our API we've got our
isolated function authorization
so we're gonna go and make some changes
to this to take account of the user role
that gets passed in
so let's jump into the authorization
middleware and right at the top where
we've got our Scopes we're also going to
add in our rolls claim type which is
extension user permissions as we know we
saw that in the access token
and then we can change the authorize
delegated permissions here so last time
I commented out about user roles and
said I'm not interested in those but I'm
now going to change this so that it does
take account of user roles but it looks
at my b2c extension
I'm going to look up the claim for the
user permissions and split that by the
delimiter so comma and a space and I'm
going to remove any empty entries so
this will get me a collection of the
user roles now I've got a collection
that I can use
I can query that collection to see if
the role that's been specified against
the Azure function exists for this user
so this user possesses the right role to
be able to call the Azure function that
they're calling and we'll go and change
the attribute that we put on the Azure
function to State what role they need to
possess in order to call it so that's
what this is doing here we just need to
change the last line as well so that as
well as checking the accepted scope so
exactly what we what it was doing
historically which is to check that the
user has the role and the scope we
changed this last time so I'm going to
put it back to how it was so now they
have to have the role and the scope in
order to call the function so let's save
that and then let's jump over to our
API
and we've got our b2c
protected function in here that at the
moment you have to have the email scope
in order to be able to call this so we
are going to change this so that as well
as email access we give it a user role
of some value
and let's say
admin so only admins can now call this
b2c protected function let's save that
and start this up okay so that's up and
running so let's jump over here
and we're not signed in so let's go and
sign in
and let's do the same test that we did
before so let's sign in as someone who
isn't admin I'm going to put on the
developer tools
so we can see there that my b2c
protected function gave me back a 403
Forbidden because he's not an admin role
so then let's sign out and sign in as
admin
thank you
this time we get a 200 for our b2c
protected function and we see our data
on the page so
that shows how you can protect your
Azure functions as well and make sure
that the people that are calling them
have the right roles in order to be able
to call them so that's front end and
back end secured with user roles using
Azure b2c so if you found this useful
please do hit the like button that helps
it find more people and with that I want
to thank you very much for watching and
I will see you in the next video
تصفح المزيد من مقاطع الفيديو ذات الصلة
最新技巧:一键申请任意大模型API,支持国内信用卡,彻底解决大模型API难题!
Obsidian-Excalidraw 1.8.12 - QoL Improvements: pens, pinned scripts, panning tool, and color picker
Unreal Engine 5 RPG Tutorial Series - #9: Combat
Easiest DIY Motion Controller for FPV using Betaflight
How to install ReShade Graphics in Genshin Impact Multiplayer [Tutorial Class] RayTracing Unity
Multiple JDBC Clients - How to configure multiple DataSources in Spring
5.0 / 5 (0 votes)