I'm currently working on a fastify project, where I use fastify-jwt to create Bearer tokens to my users.
And in the routes I acces it with following:
fastify.get(
"/test",
{
preValidation: [fastify.authenticate],
},
Collection.functionX
);
So know I want some routes not accessible for "normal" users, only for "admin" users. Normally this information is within the token. I can grand access to only admins within the function, by I want to directly not give access to the route. So it directly calls "not allowed".
I found fastify Guard but it is not working.
you can use firebase authentication or any ,and put the user in a data base with a schema has property "role",then check this role in middleware,for example if role==0 its admin and so on .
I'm trying to set up a frontend React app service and a backend Node app service, which both require authentication, according to this tutorial.
I've followed the steps except that I needed to set "loginParameters": ["response_type=code id_token", "scope=openid api://<backend app id>/user_impersonation"] instead of additionalLoginParams since my app uses auth v2.
When my frontend app calls my backend api I get the following error
{"code":401,"message":"IDX10205: Issuer validation failed. Issuer: '[PII is hidden]'. Did not match: validationParameters.ValidIssuer: '[PII is hidden]' or validationParameters.ValidIssuers: '[PII is hidden]'."}
I don't know how to debug this as the useful information in the response is hidded and I can't find a way to show it when using Node. I have inspected the token and the issuer is https://sts.windows.net/<tenant id>/, but I don't know what's expected or how to set ValidIssuer.
What I do for authentication code-wise is calling /.auth/me from frontend after login to receive an access token and this token is passed to the backend api in the header as Authentication: Bearer <access_token>. I'm expecting Azure to handle everything else according to the settings made in the linked tutorial. Is this correct?
How can I debug this issue?
EDIT
This is how the Expose an API page of backend app registration looks.
This is the data of my access token.
Your question has been resolved, post it as the answer to the end of the question.
As I said in the comments, you need to obtain the 2.0 version of the token. So you need to change the accessTokenAcceptedVersion attribute of the application manifest to: "accessTokenAcceptedVersion": 2.
I am sure someone out there has already done this, but I have yet to find any documentation with regard to the Microsoft implementation of JWT. The official documentation from Microsoft for their JWT library is basically an empty page, see:
https://learn.microsoft.com/en-us/dotnet/framework/security/json-web-token-handler-api-reference
So, here is what I (and I am sure many others) would like to accomplish:
Definition: User ID = The username or email address used to log into a system.
AUTHENTICATION:
A user logs in. The user fills in web form and the system sends (via HTTPS POST) the users ID and password (hashed) to the server in order to authenticate / validate the user.
Server Authenticates user. The users ID and password are checked against the values saved in the database and if NOT valid, an invalid login response is returned to the caller.
Create a JWT Token - ???? No documentation available!
Return the JWT token to the caller - ???? - I assume in a header? via JSON, not sure -- again - no documentation.
Given the code below, can anyone provide a code example for steps 3 and 4?
[FunctionName( "authenticate" )]
public static async Task<HttpResponseMessage> Run( [HttpTrigger( AuthorizationLevel.Anonymous, "get", "post", Route = null )]HttpRequestMessage req, TraceWriter log )
{
// Step 1 - Get user ID and password from POST data
/*
* Step 2 - Verify user ID and password (compare against DB values)
* If user ID or password is not valid, return Invalid User response
*/
// Step 3 - Create JWT token - ????
// Step 4 - Return JWT token - ????
}
AUTHORIZATION:
Assuming the user was authenticated and now has a JWT token (I am assuming the JWT token is saved in the users session; if someone wants to provide more info, please do):
A POST request is made to an Azure Function to do something (like get a users birth date). The JWT token obtained above is loaded (from the POST data or a header - does it matter?) along with any other data required by the function.
The JWT token is validated - ???? No documentation available!
If the JWT token is NOT valid, a BadRequest response is returned by the function.
If the JWT token is valid, the function uses the data passed to it to process and issue a response.
Given the code below, can anyone provide a code example for steps 1 and 2?
[FunctionName( "do_something" )]
public static async Task<HttpResponseMessage> Run( [HttpTrigger( AuthorizationLevel.Anonymous, "get", "post", Route = null )]HttpRequestMessage req, TraceWriter log )
{
// Step 1 - Get JWT token (from POST data or headers?)
// Step 2 - Validate the JWT token - ???
// Step 3 - If JWT token is not valid, return BadRequest response
// Step 4 - Process the request and return data as JSON
}
Any and all information would really help those of us (me) understand how to use JWT with Azure (anonymous) functions in order to build a "secure" REST API.
Thanks in advance.
Any and all information would really help those of us (me) understand how to use JWT with Azure (anonymous) functions in order to build a "secure" REST API.
Per my understanding, you could use the related library in your azure function code to generate / validate the JWT token. Here are some tutorials, you could refer to them:
Create and Consume JWT Tokens in C#.
Jwt.Net, a JWT (JSON Web Token) implementation for .NET
JWT Authentication for Asp.Net Web Api
Moreover, you could leverage App Service Authentication / Authorization to configure the function app level Authentication / Authorization. You could go to your Function App Settings, click "NETWORKING > Authentication / Authorization" under the Platform features tab. Enable App Service Authentication and choose Allow Anonymous requests (no action) as follows:
You could create a HttpTrigger function with anonymous accessing for user logging and return the JWT token if the user exists. For the protected REST APIs, you could follow the code sample below:
if(System.Security.Claims.ClaimsPrincipal.Current.Identity.IsAuthenticated)
{
//TODO: retrieve the username claim
return req.CreateResponse(HttpStatusCode.OK,(System.Security.Claims.ClaimsPrincipal.Current.Identity as ClaimsIdentity).Claims.Select(c => new { key = c.Type, value = c.Value }),"application/json");
}
else
{
return req.CreateResponse(HttpStatusCode.Unauthorized,"Access Denied!");
}
For generating the JWT token used in App Service Authentication, you could follow How to: Use custom authentication for your application and the code under custom API controller CustomAuthController from adrian hall's book about Custom Authentication to create the JWT token.
UPDATE:
For the custom authentication approach under App Service Authentication, I just want op to leverage the authentication / Authorization provided by EasyAuth. I have did some test for this approach and found it could work on my side. Op could send the username and password to the HttpTrigger for authentication, then the HttpTrigger backend need to validate the user info, and use Microsoft.Azure.Mobile.Server.Login package for issuing App Service Authentication token to the client, then the client could retrieve the token from the AuthenticationToken property. The subsequent requests against the protected APIs could look like as follows:
https://<your-funapp-name>.azurewebsites.net/api/<httpTrigger-functionName>
Header: x-zumo-auth:<AuthenticationToken>
NOTE:
For this approach, the related HttpTrigger functions need to allow anonymous accessing and the App Service Authentication also needs to choose Allow Anonymous requests (no action). Otherwise, the App Service Authentication and function level authentication would both validate the request. For the protected APIs, op needs to manually add the System.Security.Claims.ClaimsPrincipal.Current.Identity.IsAuthenticated checking.
Try this: https://liftcodeplay.com/2017/11/25/validating-auth0-jwt-tokens-in-azure-functions-aka-how-to-use-auth0-with-azure-functions/
I successfully made it work using this guide. It took awhile due to nuget versions.
Follow that guide properly and use the following nuget versions
IdentityModel.Protocols (2.1.4)
IdentityModel.Protocols.OpenIdConenct (2.1.4)
IdentityModel.Tokens.Jwt (5.1.4)
Oh and, the guide tells you to write your AUDIENCE as your api link, don't. You'll get unauthorized error. Just write the name of your api, e.g. myapi
If you get error about System.http.formatting not being loaded when running the function, try to reinstall NET.Sdk.Functions and ignore the warning about AspNet.WebApi.Client being restored using .NETFramework. And restart visual studio.
What you're describing is something that you should be able to do yourself by doing a little bit of research. To address your specific questions:
Create a JWT Token - ???? No documentation available!
The link Bruce gave you gives a nice example for how to create a JWT: https://www.codeproject.com/Tips/1208535/Create-And-Consume-JWT-Tokens-in-csharp
Return the JWT token to the caller - ???? - I assume in a header? via JSON, not sure -- again - no documentation.
There's no documentation because you're basically inventing your own protocol. That means how you do it is entirely up to you and your application requirements. If it's a login action, it might make sense to return it as part of the HTTP response payload. Just make sure that you're using HTTPS so that the token stays protected over the wire.
A POST request is made to an Azure Function to do something (like get a users birth date). The JWT token obtained above is loaded (from the POST data or a header - does it matter?) along with any other data required by the function.
How you send the token is, again, entirely up to you. Most platforms use the HTTP Authorization request header, but you don't have to if you don't want to.
The JWT token is validated - ???? No documentation available!
Use the ValidateToken method of the JwtSecurityTokenHandler (see the previous link for how to get the JwtSecurityTokenHandler). Docs here: https://msdn.microsoft.com/en-us/library/dn451155(v=vs.114).aspx.
I created an Azure Functions input binding for JWT Token Validation. You can use this as an extra parameter with the [JwtBinding] attribute. See https://hexmaster.nl/posts/az-func-jwt-validator-binding/ for source and NuGet package information.
Basically Azure Functions built on top of ASP.NET Core. By making some dependency injection tricks you could add your own authentication and policy-based authorization. I created demo solution with JWT authentication just for fun, beware to use it on production.
I'm wondering how to create an endpoint (GET, POST, etc...) that can be accessed without any authentication. this is my code:
router.use(AuthenticationManager.ensureAuthenticated());
router.use('/', require('./index'));
router.use('/path-1', require('./path1'));
router.use('/path-2', require('./path2'));
All the endpoints will enjoy the Authentication Manager. How disable that authentication manager only in some endpoints inside ./path1 or ./path2 ?
The regular method of doing this is defining those endpoints before the AuthenticationManager middleware:
router.use('/path-1/unprotected', require('./path1'));
router.use('/path-2/unprotected', require('./path2'));
router.use(AuthenticationManager.ensureAuthenticated());
It depends on what exactly path1.js and path2.js are exporting if it works as-is, or if you need to do a bit of rewriting.
you can use authentication for specific endpoint by using this:
app.post('/profile', AuthenticationManager.ensureAuthenticated , userController.getUserProfile);
I'm playing with Azure AD authentication and authorization scenarios and not all clear for me.
Currently I'm looking at SinglePageApp-WebAPI-AngularJS-DotNet sample project.
And one thing that I can't understand. On the client side we get access token using implicit grant flow - that is clear. Then we send request to WEB API with Bearer and access token as value. On the server side we have TodoListController with Authorize attribute. So, in order to hit the controller request must be authorized.
What is not clear how authentication middleware validates my access token (what if random text sent instead of valid access token?). I cloned katana project and investigated WindowsAzureActiveDirectoryBearerAuthenticationExtensions and OAuthBearerAuthenticationHandler classes, but I still can't find concrete place where validation occur.
How my WEB API will know that this particular access token is valid and where is this concrete line of code, which is responsible for validation?
Thanks!
UPD:
Actually I find the place. All work is done inside OAuthBearerAuthenticationHandler in method AuthenticateCoreAsync:
tokenReceiveContext.DeserializeTicket(tokenReceiveContext.Token);
this call leads to running JwtFormat.Unprotect method, which performs actual validation.
Thanks #Aram for good notes.
In your service start up you register OWIN and when your controller is decorated with Authorize attribute then the authentication challenge will happen and OWIN will try to validate the token on each request..
The token validation happens because you have OWIN Dll references AND you have the startup.auth class in your service project...
You probably have something like this, that you include Auth challenge in the service side:
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Audience = ConfigurationManager.AppSettings["ida:Audience"],
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
});
When the validation is happening, the OWIN middleware will validate against the Audience and the Tenant that the token has been acquired from, and if they dont match the Authz will fail...
Depending on with Authentication handler you use the actual code that calls the ValidateToken function is in YOUR_AUTH_HANDLERAuthenticationHandler class.
Here is the location for OpenId AuthZ handler:
http://katanaproject.codeplex.com/sourcecontrol/latest#src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs
For instance if you have OpenIdConnect Authz handler then the token validation is in : Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationHandler class and the Overrride method :
protected override async Task<AuthenticationTicket> AuthenticateCoreAsync()
And the ValidateToekn code will look like (if your AuthZ handler is OpenId connect):
ClaimsPrincipal principal = Options.SecurityTokenHandlers.ValidateToken(openIdConnectMessage.IdToken, tvp, out validatedToken);