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.
Related
I am looking for support of resource attribute authorization in Keycloak.
I have a REST service which takes a datamodel (in JSON format) as body. Based on certain attribute of this Json, I want to deny or allow the request.
I know I can put my validation or kind of custom authorization logic as a layer, but I am looking if Keycloak provides any out of the box support for it like CBAC or Resource ABAC?
How can I define custom scopes on a per user basis using cognito?
For example I have scope resource1.read, resource1.write
I want user A to have resource1.read and resource1.write while user B has resource1.read only.
This is just a high level example. We have tons of different resources and wants to allow customers to manage what resource each user has access to.
I havent found a way to associate scopes with each individual users but only at a per pool level.
Is there a way to achieve this using only cognito or cognito + some AWS manged service or do I have to implement another API to manage the scopes myself?
we couldn't find a way to make scope work on per user basis so we ended up using the custom attributes instead.
if you have less than 25 scopes (cognito max limit) then you can use one attribute per scope. P.S. just be aware you can't rename/remove the attribute once its in place unless you delete the whole pool and start over again.
For example your attributes might look like:
custom:resource1.read : "true"
custom:resource1.write : "false"
custom:resource2.read : "true"
custom:resource2.write : "true"
the idea is simple. instead of having all the scopes defined inside the scopes array we define it in regular custom attributes. When the code checks for scopes just loop thru all fields and find the one with correct prefix.
You could implement your own authorization service and call it with the Pre token generation Lambda trigger:
https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html
This only applies to the ID token though, just like Steve's answer.
You can use this AWS Lambda trigger to customize an identity token before Amazon Cognito generates it. You can use this trigger to add new claims, update claims, or suppress claims in the identity token.
When using attribute routing, is it possible to remove routes based on certain runtime condition - such as licensing?
Something like this:
[LicensedRoute("/api/whatever")]
where '/api/whatever' is only added to the route table if the application is licensed.
Obviously I can explicitly do the check in the action method or use an action filter to validate the requests but ultimately I prefer the route not to be available if the software is not licensed.
Seems you need Attribute Routing: http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
Is it RESTful? How you store the licensing info: is it user logins? tokens? key?
You could do it RESTful and force the client to pass a token every time via token-based authentication, for example: define several "licence" levels/types (eg. Free/Trial/Basic/Pro) and then in a persistent storage (table) map tokens (guids) to a licence type.
Then using a custom attribute, mark each endpoint/controller/action with the minimum required licence type to be accessible (e.g. [MinimumLicence("Basic")]). And then create "routing tables" based on the licence required.
In this case you would deny access to routes rather than "remove" them.
I have a WCF service which uses claims based authorization.
What I want to do is to attribute an operation with a ClaimsPrincipalPermissionAttribute and only have the authorization check trigger once in my custom ClaimsAuthorizationManager. However I am finding that this authorization check is being triggered twice; once for the URL and then a second time on the operation itself.
I can't find much information on this subject, but what I have found indicates that this is by design. Is it possible for me to overwrite this behavior and not perform any authorization on the URL, and only authorization based on the operation?
I have no interest in authorizing based on URLs, and would really rather avoid adding claims for each and every URL as I am likely to have a lot of them and they may change in future.
I have read several articles, and seen videos from Dominick Baier on this subject, and while I have learnt a lot from these I still can't find an answer to this. Is this simply not possible and I just have to deal with having to authorize based on the URL as well?
You can't change this behavior - what I did is to write a custom claims permission attribute that does emit different claim types. This way I could distinguish between the per-request invocation and the explicit attribute.
https://github.com/thinktecture/Thinktecture.IdentityModel.45/tree/master/IdentityModel/Thinktecture.IdentityModel/Authorization
or the Thinktecture.IdentityModel nuget package.
I've tried researching about custom authentication modules and authentication post processing, but didn't find anything.
By programmatically I meant to set this value based on some user attributes. Actually I found a way, using a Custom Condition inside a Policy. The ConditionDecision class (wich is the getConditionDecision() ConditionĀ“s interface response) allows to set a specific Session TTL.
More about the Policy Evaluation API here: http://download.oracle.com/docs/cd/E19681-01/820-3748/6nf8sa0b1/index.html