Is there some way to get path parameters in #SecureSocial.SecuredAction authorization implementation? - playframework-2.1

I'm new to playframework and trying to use securesocial for authentication & authorization in my web app.
I need to add custom authorization to my controller, that checks if current user is creator of entity, that he is trying to view or edit.
#SecureSocial.SecuredAction(authorization = OwnerCanEdit.class, params = {"id"})
routes:
GET /projects/edit/:id #controllers.ProjectsController.edit(id)
To make this I need to pass entity id from request path.
Is there some way to get/pass path parameter in class implementing Authorization interface?

There's currently no way to do it. This is a valid use case and should be covered. I'll keep this in mind to improve the API.

Related

How to pass custom argument to authorization policy

I need a custom attribute for my rest API in asp.net core MVC. I want to add this attribute optionally to some of my APIs. This attribute checks if the API is accessible to user or not based on some condition and throws a 403 if it's not accessible. I was using filters to achieve this and the issue with filter is that filter code gets executed whether the attribute is added or not to my API.
I would want that my filter code is executed only when this attribute is added to the API.
My colleague suggested that I should be using authorization policy instead of filters for this use case. Policies are executed only when it's added to the API. Also since I am throwing 403, authorization policy is a better candidate. I explored authorization policy but my issue is I am unable to pass custom attributes to Authorization policy.
For example, I was able to do this using filters and custom attributes.
[MyCustomFeature("param1", "param2")]
How can I do the same in authorization policy? I am using this example for authorization policy.
Custom Authorization attribute asp.net core
See here. Strongly recommend reading top to bottom.
The summary is that, regardless of how you tap in to the policy-basd auth system, a policy is always resolved via a single string. So, to get what you want, you need to:
Implement a custom attribute that subclasses AuthorizeAttribute and that takes the arguments you pass in and uses them to generate a policy name string. Read the "Custom Authorization attributes" example in the linked docs page closely, see how it actually stores the value of "Age" in the Policy string.
Implement and register a custom IAuthorizationPolicyProvider that can interpret the strings generated by your custom attribute and generate the appropriate policy on the fly.
There's not a ton of code involved and it's not super complex, but it's a little strange/awkward that it comes down to putting stuff into a string.

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.

Yii2 Rest API user authentication

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

Custom authorization approach for WebApi

I am going to implement Authorization for my Web API project. For that I have been reading various blogs, stack overflow answers about authorization in WebApi.
Two ways I saw recommended is either use Custom Authorization filter or use Web API Message Handler which gets executed before any filters.
I have very distinct requirement for my project.
1) I have third party authentication service implemented. Request will come to web API pipeline only when authenticated. I just need to perform authorization.
2) All actions in all my controllers are needs to authorize. (No anonymous access)
3) There are three levels of authorization I need to perform.
a) Module Level (to see if user has access to said module)
b) Record Level (if user has access to module see if he has access to particular resource accessing)
c) Action Level (if user has access on both see if user can perform the said action [View/edit/delete/create]
4) All my url follow some predefined pattern {api/module/resource/resourceid} & action GET, POST, PUT, DELETE
My requirement is, I don't want to register any attribute over any of action or controller & I want to infer the all incoming request and authorize user based on it. (using delegate handler)
I am trying to use below approach :
1) from the incoming request url extract module name, resource name , resource id & User Id from cookies and pass this info to a function which will return true or based on some business rules.
Examples:
GET API - api/modulename1/resource1/id -> This URL will check VIEW access to modulename1,resource1 & resource id
POST API - api/modulename1/resource1 -> This URL will check CREATE access to modulename1,resource1
Same thing for delete & edit also.
I want to ask experts here a question if this approach will work or if there are any limitations with this approach.