Yii2 Rest API user authentication - yii

I am implementing Rest API in yii2. I want to authenticate the user using access token. I have referred various SO answers as follows
Rest api bearer authentication
Rest api bearer auth
Yii2 Rest api authentication
But I m not clear, which authentication method I should use and how I will get user identity.
I have created findIdentityByAccessToken() method in my user identity class as suggested in Yii2 Rest guide .
Below is the behaviour implemented in my controller
public function behaviors() {
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => HttpBasicAuth::className(),
'except' => ['login','forgot-password']
];
return $behaviors;
}
now, how I will get the user identity inside my controller action? As far as i know, access token will be set from the web service inside request header.
Note : I am using Yii2 advanced app
please help me.

Simple answer there's more than one possibility to implement this behavior.
Both HttpBearerAuth and HttpBasicAuth can use the findIdentityByAccessToken() methode when configured correctly. the behavior you should use depends on the way you want users to authenticate themselves.
if you read the documentation of HttpBasisAuth HttpBasicAuth you'll see
The default implementation of HttpBasicAuth uses the loginByAccessToken() method of the user application component and only passes the user name. This implementation is used for authenticating API clients.
loginByAccesToken will invoke the findIdentityByAccesToken methode
You can manipulate this behavior by defining a closure in the auth attribute see auth attribute.
HttpBeareAuth almost does the same. it also implements the loginByAccessToken
So what make the two different from each other? simple the location where the get the data from. where HttpBasicAuth expects that client has set the basic header example header('Authorization: Basic '. base64_encode("user:password")); (PHP has build in support for this see: http://php.net/manual/en/features.http-auth.php)
the HttpBearerAuth expects that the header is defined as the following header('Authorization: Bearer '. $token);
So the solution you should use depends on the way you want users/clients to authenticate themselves. you could also use the QueryParamAuth which gives the users the possibility to authenticate themselves whit a GET param see queryparamauth
And if you want to use a custom header let's say X-API-Token create your own custom class that implements the AuthMethod interface see AuthMethod
Hope this helps

Related

Get current authentication scheme in ASP.NET core 2

I am currently struggling with an Asp.net core 2 application which uses two openid providers for authentication, mapped to two different Authentication Schemes (with different names).
The problem I am facing is trying to logout of the specific scheme that is currently being used. For example, if I support both Google and Facebook authentication, I need to understand which scheme is currently being used, and call the SignOut method indicating the correct scheme. This allows me to clear the local cookies and also redirect the user to the external identity provider and logout.
The thing is that I am not able to find a GetCurrentScheme() sort of function so that I can use to then specify the scheme in the SignOut method. I am sure I am missing something basic...
There does not seem be any direct way to find current scheme. Here is a crude way:
private readonly IAuthenticationSchemeProvider authenticationSchemeProvider;
...
foreach(var scheme in authenticationSchemeProvider.GetRequestHandlerSchemesAsync()){
var authResult = await context.AuthenticateAsync(scheme.Name);
if(authResult.Succeeded)
// this is the scheme that was used for authentication
}
I had the same question, but I finally put the authentication scheme in the claims collection in my SignIn method :
claims.Add(new Claim(ClaimTypes.AuthenticationMethod, authenticationScheme));
So, in the SignOut method, I can retrieve the authentication scheme :
var authenticationScheme = HttpContext.User.FindFirstValue(ClaimTypes.AuthenticationMethod);
IAuthenticationHandler has also Task InitializeAsync(AuthenticationScheme scheme, HttpContext context). It is called before AuthenticateAsync scheme name is here in first parameter.

Look up the user with bearer token with Openiddict Core

I am currently using Openiddict, Identity and Entity Framework to manage my users and assign Bearer tokens to users to protect my API.
My infrastructure is currently using ASP.NET Core Web API in the back end and a separate React application in the front end. The React application makes HTTP calls to my API to retrieve it's data. There is no server side HTML rendering at all in the back end.
Everything works as I need it to for the most part. I can register users and retrieve tokens from the API. These tokens are included in my HTTP call in the Authorization header. My AuthorizationController uses this: https://github.com/openiddict/openiddict-samples/blob/dev/samples/PasswordFlow/AuthorizationServer/Controllers/AuthorizationController.cs with a few minor tweaks. My Startup.cs also uses almost exactly this https://github.com/openiddict/openiddict-samples/blob/dev/samples/PasswordFlow/AuthorizationServer/Startup.cs
In some instances, I need to make API calls to the endpoints that are specific to the user. For instance, if I need to know if a user has voted on a comment or not. Instead of passing along the users ID in a query string to get the user details, I would like to use the Bearer token I received that they use to make the API call for that endpoint. I am not sure how to do this though.
In some research I have done it looks like some samples use ASP.NET Core MVC as opposed to the API to retrieve the user with the User variable as seen here https://github.com/openiddict/openiddict-samples/blob/dev/samples/PasswordFlow/AuthorizationServer/Controllers/ResourceController.cs#L20-L31 however this seems not to apply to my infrastructure.
My question is how do I look up a user based on the Bearer token passed to the API to look up a users details from my database? I am assuming that all of the tokens passed out by the API are assigned to that specific user, right? If that's the case it should be easy to look them up based on the Bearer token.
The question is: How with Openiddict can you look up a user based on the token that was assigned to them for API calls? I need to get the user details before anything else can be done with the application first. Is there something baked internally or do I have to write my own support for this?
When you create an AuthenticationTicket in your authorization controller (which is later used by OpenIddict to generate an access token), you have to add a sub claim that corresponds to the subject/entity represented by the access token.
Assuming you use the user identifier as the sub claim, you can easily extract it from your API endpoints using User.FindFirst(OpenIdConnectConstants.Claims.Subject)?.Value and use it to make your DB lookup.

How to read custom header in IdentityServer4?

I would like to authenticate user not just based on username and password, but also based on tenant. I would like to pass tenant as custom header X-Company-Tenant. Can I read this custom header value in ResourceOwnerPasswordValidator in procedure ValidateAsync?
Is it possible to create a middleware on IdentityServer4 to read header from request and pass that value to ValidateAsync?
In ASP.NET you can inject the IHttpContextAccessor into anything that comes from DI (as a constructor dependency). This will give you access to the current HTTP context - including the request headers.
That said - you could also post the tenant as a body member and you would get easy access from the context object passed into your validator.

Get JSON Web Token payload data within controller action

I'm implementing JWT based authorization for my ASP.NET Web API application with Angular2 SPA. All is well and clear regarding authorization flow except for one detail. I am wondering how to get JWT payload information within the Web API controller action?
Looking through the web I can't find any solution that I would go for, for example, setting Thread.Principal or something like that.
What are the recommended ways to accomplish that?
The normal process to handle a JWT token as authentication in ASP.NET is:
Get the token from the request and ensure is valid.
Create a principal based on the information contained within the token and associate it with the request.
This implies that the payload information within the token is available through the request principal usually in the form of claims. For example, if your JWT contains information about the user roles it would get mapped to a role claim available in the principal.
You don't mention if you're using OWIN or not so I'll assume OWIN for the example, but it shouldn't really matter or be much different at the controller level.
Despite the fact you're concerned only with the data consumption part, if curious, you can read through this set of tutorials about ASP.NET Web API (OWIN) for a more in-depth look on the whole process:
Introduction
Authentication (HS256)
Authorization
The last one would be the one with most interest , you'll note the following code snippet on that one:
[HttpGet]
[Authorize]
[Route("claims")]
public object Claims()
{
var claimsIdentity = User.Identity as ClaimsIdentity;
return claimsIdentity.Claims.Select(c =>
new
{
Type = c.Type,
Value = c.Value
});
}
This relies on the User.Identity available within the controller to list all the claims of the currently authenticated identity. Unless you have an authentication pipeline configured rather different then what it's the norm, these claims are mapped from the JWT payload your API receives.

how to set header authentication in dropwizard

I've built a small api.
I Would like to implement header authentication for my api.
When user want to access my api he will send his apikey along with the api url. If the apikey was in my database then he will be given access, if not he can't access the api.
if you want to authenticate a single method
then you can look for the header directly in the method itself. something like
#GET
public Response processRequest(
#HeaderParam("X-APIKEY")
#DefaultValue("INVALID_OR_GUEST_KEY") String apikey , ...)
if you want to establish this for -all- (or most) of your methods, then you are better off with a filter. Take a look at http://www.dropwizard.io/0.9.2/docs/manual/core.html#jersey-filters and http://www.dropwizard.io/0.9.2/docs/manual/core.html#servlet-filters .
You can implement your key lookup logic in there
(PS you may want also to consider caching them, but that's another story).