I'd like to make a Helpdesk user with permission to create new tickets (request fulfillment). I made a Service Desk group with the user and set the permissions for it to access the Request fulfillment process. After I logged in with this user all the tickets have seen, but cannot start a new one. Maybe this is a bug or for this role have to set up some other method or feature as well?
Related
I use Graph Explorer to test it.
API: GET /users/{userPrincipalName}/insights/shared, return 403.
API: GET /users/{userPrincipalName}/insights/used, return 200 and used documents.
Both API required same permission:
Sites.Read.All, Sites.ReadWrite.All
Anyone can help on it?
If you call GET /users/{id | userPrincipalName}/insights/shared, please make sure you have the Sites.Read.All or Sites.ReadWrite.All application permissions (don't forget to grant admin consent for this permission), because no users are logged in at the /users endpoint. Then you need to use the client credential flow to get the access token.
Update:
When you use Graph Explorer to test, because you need to log in as a user, you actually use the token obtained by the userName/Password flow. according to the document: Only the user can make requests using the user's id or principal name.
When you log in to a user, you can only use the id or principal name of the logged in user. You cannot use the id of other users, otherwise, a 403 error will be reported. But when you use other tools such as postman for testing, because you do not log in as a user, but use the application as the service principal to make a request, so, you can get a list of shared documents from other users.
Summarized in one sentence: As long as you are logged in as a user, you can only get the list of shared documents of the logged-in user. If you want to get the list of shared documents from other users, , don't log in users.
I am currently implementing an Identity Server solution and I needed some help with the IProfileService and how it works exactly.
It exposes a method called "GetProfileDataAsync". I understand that this is called when IS4 returns a token. So that means the person gets to the login screen, inputs his details, and then before IS4 returns an Identity token and an Access token, this method will get called to add additional claims.
I am currently trying to figure out the best way to implement roles and permissions based authorization. Currently I need to have access to both the permissions and roles that the user has assigned as that is what our existing code does and we are just switching our authentication model to IS4 but keeping the User Management to be as it currently is.
Questions then...
How best do I implement it? I currently have an ApplicationUser class which implements IIdentity. So should I add a list of roles in there and then a list of permissions, and then populate it when I go get it from the DB when the user does a LogIn?
E.G. In this method
ApplicationUser user = await _userRepo.FindByUsername(model.Username);
The alternative is to add each role and each permission as a claim in my UserProfileService, specifically in the method below
public virtual async Task GetProfileDataAsync(ProfileDataRequestContext context)
I read the following
Often IdentityServer requires identity information about users when creating tokens or when handling requests to the userinfo or introspection endpoints. By default, IdentityServer only has the claims in the authentication cookie to draw upon for this identity data. It is impractical to put all of the possible claims needed for users into the cookie, so IdentityServer defines an extensibility point for allowing claims to be dynamically loaded as needed for a user. This extensibility point is the IProfileService and it is common for a developer to implement this interface to access a custom database or API that contains the identity data for users.
With the above situation, as I have implement the IProfileService, does that mean that all claims that are loaded will be automatically returned and put into the Identity/Access token? Does that mean that for every request that is made to the API, my application will be sending in a token (in the cookie) which could get quite big with these claims that include roles and permissions? What is the alternative as the above statement from the IS4 website mentions it is impractical
How best do I implement it? I currently have an ApplicationUser class which implements IIdentity. So should I add a list of roles in there and then a list of permissions, and then populate it when I go get it from the DB when the user does a LogIn?
There is two kind of things here, Roles and Permissions. Roles are data and you can add them to the token and pass to clients and APIs. you can save the Roles in DB any how which fits your design.
To have the roles in the token you need to fetch them in ProfileService and add to token. Sth like this:
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
context.IssuedClaims.AddRange(context.Subject.Claims);
var user = await _userManager.GetUserAsync(context.Subject);
var roles = await _userManager.GetRolesAsync(user);
foreach (var role in roles)
{
context.IssuedClaims.Add(new Claim(JwtClaimTypes.Role, role));
}
}
After doing this your token should contains the roles. make sure to verify the token on https://jwt.ms/
But Permissions are more of real time calculation things.We need to decide about permissions on API based on the user info, user's role or any other data available.
For example a user may have the role as delete (means user can delete things). If this user call order API and tries to delete some one else's order it has to be declined. Means delete permission MUST be calculated based on user's ID + user's role + Order's owner ID.
With the above situation, as I have implement the IProfileService, does that mean that all claims that are loaded will be automatically returned and put into the Identity/Access token? Does that mean that for every request that is made to the API, my application will be sending in a token (in the cookie) which could get quite big with these claims that include roles and permissions? What is the alternative as the above statement from the IS4 website mentions it is impractical
Yes the profile service is called whenever IDS4 needs to return claims about a user to a client applications. If you request an identity and access token - it will get called twice (since you might be putting different claims into each token type).
What is the alternative as the above statement from the IS4 website mentions it is impractical
You should just fetch the data that you need - not extra. As I mentioned above permissions should be calculated on the fly and not be in the token.
Also you can use cache in the ProfileService. But if you use cache you are the one responsible to manage in your code.
I have a REST API which uses Azure ADD App registration to allow other apps to call it.
In the Azure Portal, I have registered it as an Enterprise Application and also registered the consumer applications and assigned them Roles appropriately.
The authentication and RBAC works fine.
But the use case that I am working on requires me to identify and log the incoming request calling application's name (The one seen in the portal as 'Display Name', when we view the list of users and groups for an enterprise Application).
As advised in the internet, I am using some Identity related API to read the claims from the request header.
var provider = claimsUser.FindFirst("http://schemas.microsoft.com/identity/claims/identityprovider").Value;
var sid = claimsUser.FindFirst(ClaimTypes.NameIdentifier).Value;
OR
var sid = claimsUser.FindFirst("stable_sid").Value;
But this gives me a GUID value which I couldn't map to any of the consumers of the Enterprise Application.
The clients are all registered in the Azure portal.
In the Portal, I can see the apps in the "Users and Groups" section for the Enterprise application, with their appropriate roles.
In terms of usage, before making the call, the clients generate a bearer token based on the certificate that they get from Azure. The make the call with the bearer token attached to the request header. This bearer token is validated against the Azure AD, in the filters set before every controller..
What I want is to get are the details about this client who has made the call.. As per some repliers, and, to which I agree, the Guid that I get as part of the previous call mentioned above is for the actual user and not the app itself which is making the call.
Can anyone throw some light into it.. some code snippet will be of real help..
I'm not sure what authentication flow you are using, but SID is generally for a user that's logged in, not an application. if your client applications are using client id and secret, the token it returns that you send to the api should include the app registration guid. https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#access-control-lists . So the appid and iss should give you the guid of the app registration. using this, you can make a call to graph api, to identify the display name of the app registration. https://learn.microsoft.com/en-us/graph/api/application-get?view=graph-rest-1.0&tabs=http
If your app is a user login app, and you don't want to make a call to graph, the other option you could do as a workaround would be to create app roles and assign users to them but name the app roles with some convention that includes the app's display name. then the name could come through under roles claim.. https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-add-app-roles-in-azure-ad-apps
those are some options.. but other than calling graph or kinda working around to inject the name into a different claim of the token I'm not sure of any other method to get the "app registration's display name"
I have set up identityserver 4 with an asp.net mvc web site using it for authentication (implicit grant type). I need have to have the claims on token updated when the user modifies the profile of the account but it is not.
Everything is working great in the happy path, client authenticates, then redirects back to website, claims comes through - all good.
My web site has a link that sends the user back to the IdentityServer in order to update the profile (name, email, phone, etc) but once this is completed and the user is sent back to the web site the claims are not being updated with the new information.
I can see that my user claims factory is being called from the profile service and that the new profile information is being set in the claims, however my website doesn't seem to pick up the new information. What might I be missing? Is this even the correct approach?
After the user logged in claim information is saved in a cookie. It will not be updated until the user logs out and logs in again. You may need to sign out user forcefully so that he must log in again after a profile update.
But if the user does frequent profile updates you may need to rethink having profile data in id-token and then in claims. There is a user info endpoint in identity server that you can query to retrieve profile data when needed.
http://docs.identityserver.io/en/latest/endpoints/userinfo.html
I'm trying to connect to exchange online and do certain operations with the emails using Microsoft Graph API 1.0 and this is all done in a demon program. I'm using Client Credential workflow for authentication, below is the small piece of code
AuthenticationContext authenticationContext = new AuthenticationContext(string.Format(CultureInfo.InvariantCulture, azureEndPoint, tenant));
ClientCredential clientCredential = new ClientCredential(clientId, clientSecret);
AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenAsync(resource, clientCredential);
But for this code to return the authentication token I have to get Application Permissions to the azure app id against microsoft graph api. The caveat here is if the permission is granted, the application id will have access to read emails of all users in the organisation and due to this reason tenant admin has strictly refused to grant the permission.
I tried my luck with consent framework but that requires user intervention to enter his/her id and password which is not possible in case of a demon program. I read few blogs like below but they all end up entering the user id password to get to the redirect url which defeats the whole demon thing https://blogs.msdn.microsoft.com/exchangedev/2015/01/21/building-daemon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow/
Is there any way I can give read/write access to azure application id for specific email ids in the tenant? Or alternatively any smart way to somehow get to the mailbox without user intervention?
Thanks in advance,
Vivek
You can only use app permissions with client credential grant flow.
To access only specific users' emails, you'd have to do a different approach.
This does require each user to consent individually.
Have the users login to your app, require consent for access to their email.
Upon returning to your app, acquire a refresh token and store it securely.
A refresh token is user-specific.
Then in your daemon service you acquire an access token for each user using their refresh token.
If the acquire fails because the refresh token has been invalidated,
the user will need to be notified to login again.
This is now resolved as microsoft has introduced a new concept of limiting application permissions to specific mailboxes or set of mailboxes using Group Policies. Check here https://learn.microsoft.com/en-us/auth-limit-mailbox-access