authorization icon indicating copy to clipboard operation
authorization copied to clipboard

Selectively allow anonymous access

Open dnndevelopernc opened this issue 6 years ago • 13 comments

Is it possible to white list one or more endpoints?

for example: I would like to require authentication for all mutation and queries except for Login.

Currently we authorize each mutation individually - we fear forgetting one will ship and endpoint with open access. The query mutation we AuthorizeWith at the root level therefore it catches all endpoints.

If this is not possible with the current implementation, I am happy to create a PR but how would this work? Instead of AuthorizeWith on an endpoint have DisableAuthorization() ? This could add metadata that is inspected during evaluation to bypass root level policies. What are the drawbacks to this approach?

Update Took the initial approach of removing operation level validation and the fields now inherit parent policies if they are not flagged a public.

Example image

dnndevelopernc avatar May 06 '19 17:05 dnndevelopernc

Currently u could also just do it like .AuthorizeWith(""); or some other non existing policy name. If the policy doesnt exists the user is also authorized.

Fireblade954 avatar May 08 '19 11:05 Fireblade954

@Fireblade954 that is no longer allowed with this issue fixed (PR merged) #15

Thank you for the suggestion

dnndevelopernc avatar May 08 '19 13:05 dnndevelopernc

Easiest way I found to-do with was:

(at whatever levels you need)

new FieldType
{
...
Metadata = dRules // This field lets us define properties anything in the resolver pipeline can use
...
}

Usage sample here: https://github.com/graphql-dotnet/authorization/issues/6

But this one of those - roll it like you need it cases.

OpenSpacesAndPlaces avatar Jul 16 '19 22:07 OpenSpacesAndPlaces

I think the issue of using the policies found in the GraphQL document is much broader and in some way relates to #6. Now I see the problem that it's not just enought to make auth check immediately when walking over AST. There should be some new component that accumulates all found policies to apply and then ... do something with them. In your case this component should filter policies to allow some priority model. In other cases it can modify/add policies, I don't know exactly. Such a view will allow not to mix different tasks in a bunch. One task - find all appliable checks with theirs context from input document. Another task - use somehow that information before performing checks. Ping @joemcbride @Shane32 .

sungam3r avatar Dec 11 '21 22:12 sungam3r

In other words, the need to fulfill the defined policies depends on the state of the entire AST.

sungam3r avatar Dec 11 '21 23:12 sungam3r

Or how do you like this solution - allow to remove validation errors from ValidationContext. Imagine AuthorizePublicRequirement that may check AST to see if it can safely put away validation error if INode from that error points to parent query/mutation/etc. Implement that "safely" may be a bit tricky though.

sungam3r avatar Dec 11 '21 23:12 sungam3r

the need to fulfill the defined policies depends on the state of the entire AST.

I think this is the main thing.

sungam3r avatar Dec 11 '21 23:12 sungam3r

I’m not sure I understand exactly what you suggested @sungam3r . I would comment on the original issue/suggestion, and say I agree, but I’m not exactly sure how. I think of ASP.Net where you can specify AllowAnonymous to make a specific action accessible regardless of the authentication attribute on the parent.

For GraphQL.NET it would be nice if all those conditions are precomputed when the schema is built to save on execution time at runtime.

Shane32 avatar Dec 12 '21 01:12 Shane32

Yesterday I reflected a lot about possible ways to implement. All decisions coming to the head, one way or another were associated with difficulties. Difficulties not only technical details, but also design. As a result, I came to the conclusion, which seems to me the easiest solution to the problem - no need to invent any sophisticated ways to override policies. The easiest, understandable and least erroneous way is to develop your schema in accordance with the required policies:

type Query {
  public: PublicApi!                no authorization here 
  authorized : AuthorizedApi!    authorized with some requirements
}

type PublicApi {
  login(input: LoginInput!): LoginResult!
  help(message: String!): FeedbackResult!
  otherPublicFields: ...
}

type AuthorizedApi {
  author(input: AuthorInputType!): String,
  otherFields: ... 
}

These are so called namespace-types or role-types. Another example:

query {
  viewer {
    getNews
    getAds
  }
  me {
    nickname
    photo
  }
  admin {
    shutdown
    exposePersonalData
  }
}

In this case, several qualities are achieved at once:

  1. Schema is well-decomposed
  2. Authorization requirements for fields are intuitively understandable.
  3. No changes in Authorization project at all. The implementation remains simple.

I could speculate some time about how to change the mechanism of policies checks, but I strongly doubt that this will lead to a decent solution.

sungam3r avatar Dec 12 '21 17:12 sungam3r

@dnndevelopernc I close this for now. Reopen if you have further questions.

sungam3r avatar Dec 12 '21 17:12 sungam3r

@sungam3r I don’t think we should close this issue. Redesigning the schema isn’t typically an acceptable solution for most users. The feature request isn’t unreasonable and is probably a good idea.

Shane32 avatar Dec 13 '21 00:12 Shane32

Any update on this?

Kowjako avatar Mar 02 '24 11:03 Kowjako

The authorization validation rule included with GraphQL.Server supports AllowAnonymous, effectively white listing a specific field within a graph type. There are other differences so be sure to read the documentation within the GraphQL.Server readme. I don’t believe this repo has been updated to support AllowAnonymous.

Shane32 avatar Mar 02 '24 17:03 Shane32