Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Documentation] How to verify scope or app role in the same controller action #963

Closed
2 of 5 tasks
obryckim opened this issue Feb 12, 2021 · 1 comment · Fixed by #1011
Closed
2 of 5 tasks

[Documentation] How to verify scope or app role in the same controller action #963

obryckim opened this issue Feb 12, 2021 · 1 comment · Fixed by #1011
Labels
documentation Improvements or additions to documentation fixed
Milestone

Comments

@obryckim
Copy link

Documentation related to component

Web APIs

Please check all that apply

  • typo
  • documentation doesn't exist
  • documentation needs clarification
  • error(s) in the example
  • needs an example

Description of the issue

I have a web API that is called by BOTH daemon apps (client credential flow) as well as by other apps on behalf of the user.
In versions of Microsoft.Identity.Web prior to 1.6.0, you had to use the VerifyUserHasAnyAcceptedScope extension method on the HttpContext to check for user scopes and the ValidateAppRole extension method to check for app roles.

With this method, we could check scopes or roles based on the token:

// controller method
public async Task<ActionResult<IEnumerable<WidgetDto>>> GetAsync()
{
    this.ValidateUserScopesAndAppRoles(
        new[] { UserScopes.ReadWidgets, UserScopes.ReadWriteWidgets },
        new[] { AppRoles.ReadWidgets, AppRoles.ReadWriteWidgets });
    
    // ...
    return this.Ok(widgetDtos);
}

// method to validate based on user or daemon app
private protected void ValidateUserScopesAndAppRoles(string[] userScopes, string[] appRoles)
{
    // determine if the token is an app-only token or a user token
    var objectIdentifier = this.User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier")?.Value;
    var subject = this.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
    var isAppOnlyToken = objectIdentifier == subject;

    // if the token is an app-only token, validate the app roles
    // otherwise, verify the user scopes
    if (isAppOnlyToken)
    {
        this.HttpContext.ValidateAppRole(appRoles);
    }
    else
    {
        this.HttpContext.VerifyUserHasAnyAcceptedScope(userScopes);
    }
}

Now that the VerifyUserHasAnyAcceptedScope is obsolete and we should be using the RequiredScope attribute, how can I still allow an api controller method to be called by both users (with scopes) and applications (with app roles) and verify them based on the token type?

If an app calls the method with the RequiredScope attribute, it throws an UnauthorizedAccessException.

@obryckim obryckim added the documentation Improvements or additions to documentation label Feb 12, 2021
@jennyf19 jennyf19 added this to the 1.7.0 milestone Feb 23, 2021
@jennyf19 jennyf19 added the fixed label Feb 23, 2021
@jennyf19
Copy link
Collaborator

Included in 1.7.0 release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation fixed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants