Microsoft CRM 2011 Impersonation - dynamics-crm-2011

I want to know in CRM 2011, if I initiated the organization service with user (A) and then I impersonated with user (B).
Which user permissions will be used by CRM when I try to execute a request (i.e create account, ...)?
For example:
I have
User (A) who don't have permissions to act on behalf another user.
User (B) who have system administrator permissions and act on behalf another user permission.
I create the organization service based on Windows Authentication and log-in with user (A) as following:
Uri organizationUri = new Uri("http://localhost:5555/RMS/XRMServices/2011/Organization.svc");
Uri homeRealmUri = null;
ClientCredentials credentials = new ClientCredentials();
credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
OrganizationServiceProxy orgProxy = new OrganizationServiceProxy(organizationUri, homeRealmUri, credentials, null);
Then I impersonate like that
orgProxy.CallerId = userBGuid;
When I am trying to execute WhoAmIRequest; I get the following error:
System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: User does not have the privilege to act on behalf another user. (Fault Detail is equal to Microsoft.Xrm.Sdk.OrganizationServiceFault).
When I give User (A) permissions to act on behalf of another user, this code pass successfully.

It looks it's expected behavior. If you set CallerId = userBGuid it means that even when you are logged as userA, all activities done on behalf of userB. UserA should have priviliges to do this.

Related

Insufficient privileges error when trying to fetch signed in user's group membership using Azure AD Graph API

I need to be able to get the signed in user's group membership so that I can verify whether he is part of a specific group. However I am getting "Insufficient privileges to complete the operation." exception using the Azure AD graph API client library.
I am a co-admin of a subscription and I have created a new Azure AD application to authenticate against the default directory and configured the "Permission to Other application" section as in the below screenshot.
Azure AD Application Configuration
I am able to fetch the signed in user details, but when I try to call MemberOf function, then I get the above exception. Please let me know what I am missing here. Thanks in advance!
string objectId = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value; // object id of the signed in user
ActiveDirectoryClient client = AuthenticationHelper.GetActiveDirectoryClient();
IUser user = await client.Users.GetByObjectId(objectId).ExecuteAsync();
var userFetcher = (IUserFetcher)user; // able to fetch the signed in user
IPagedCollection<IDirectoryObject> pagedCollection = await userFetcher.MemberOf.ExecuteAsync(); // getting error here - "Insufficient privileges to complete the operation."
The problem here was that I had selected the permissions outside the 'personal scope' (Access the directory as the signed in user, Read directory data).
Hence, it needed consent from the service administrator of the subscription associated to the directory. Once the admin logs into the app and approves the consent screen, the code should stop giving insufficient privileges exception.

Why Azure AD fails to login non-admins in multi-tenant scenario?

Environment:
Two Azure ADs: Company, Customers
Company publishes an ASP.NET5 web app called Portal, the app is setup to be multi-tenant.
Customers have 2 user: user (who is just a user) and admin (who is a Global Administrator in the directory).
Portal, is initially set up to ask for 1 Application Permission: Read Directory Data
-
Here comes the flow that I went through, and I believe Azure AD misbehaves at multiple steps. Please point out if I am missing something.
I open the web app, and first try to sign in as admin
I have to consent to the Read Directory data permission, so I do that
Application appears (I have no roles assigned yet, which is fine) -- so far everything works.
I re-open the web-app in a new incognito session, and try to sign in as the user
Now, I get [AADSTS90093: This operation can only be performed by an administrator. Sign out and sign in as an administrator or contact one of your organization's administrators.] -- the admin already consented, so why do I get this??
I go to Company AD and change the application permissions to include Read & Write Directory data
I go to Customer AD check the app Portal and the dashboard already shows the new permission listed. No one had to consent! The admin do not see any change even on next login. How is this not a security hole?
My understanding of https://msdn.microsoft.com/en-us/library/azure/dn132599.aspx is that Application Permissions are not deprecated.
UPDATE
My configuration in the WebApp:
app.UseOpenIdConnectAuthentication(options =>
{
options.ClientId = Configuration.Get("ActiveDirectory:ClientId");
options.Authority = String.Format(Configuration.Get("ActiveDirectory:AadInstance"), "common/"); //"AadInstance": "https://login.windows.net/{0}"
options.PostLogoutRedirectUri = Configuration.Get("ActiveDirectory:PostLogoutRedirectUri"); //"PostLogoutRedirectUri": "https://localhost:44300/"
options.TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
// The following commented-out line should work according to
// http://stackoverflow.com/questions/29317910/why-does-the-role-claim-have-incorrect-type
// But, it does not work in ASP.NET5 (currently), so see the "Hack." down below
// RoleClaimType = "roles",
ValidIssuers = new[] { "https://sts.windows.net/a1028d9b-bd77-4544-8127-d3d42b9baebb/", "https://sts.windows.net/47b68455-a2e6-4114-90d6-df89d8468abc/" }
};
options.Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = (context) =>
{
// This ensures that the address used for sign in and sign out is picked up dynamically from the request,
// which is neccessary if we want to deploy the app to different URLs (eg. localhost/immerciti-dev, immerciti.azurewebsites.net/www.immerciti.com)
string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
context.ProtocolMessage.RedirectUri = appBaseUrl;
context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
return Task.FromResult(0);
},
AuthorizationCodeReceived = async context =>
{
// Get Access Token for User's Directory
try
{
var identity = (ClaimsIdentity)context.AuthenticationTicket.Principal.Identity;
// Hack. TODO: keep an eye on developments around here
foreach (var claim in identity.FindAll("roles"))
{
// Readd each role with the proper claim type
identity.AddClaim(new Claim(identity.RoleClaimType, claim.Value, claim.ValueType, claim.Issuer, claim.OriginalIssuer));
}
}
catch (AdalException)
{
context.HandleResponse();
context.Response.Redirect("/Error/ShowError?errorMessage=Were having trouble signing you in&signIn=true");
}
}
};
};
Thanks for the information you've provided. I'm going to answer #7 first, because it looks pretty alarming. It does at first glance look like a security hole, but it's not. It's a bug in the Azure Management Portal that we are working to fix. In the "customers" tenant view, the UX is showing the permissions that the application (defined in the company tenant) is requesting. It should be showing the permissions actually granted in the "customers" tenant. In this case, if your app actually tries a call to write to the Graph API it'll get an access denied error. Anyways - not a security hole - but can sure understand why it looked that way to you - so sorry about this. We'll try to get this fixed as soon as we can.
On to some of your other questions about consent behavior... BTW this is something we are looking to improve in our documentation. Anyways, I'll try and answer this broadly in terms of the design behavior, because it looks like you've changed your app config multiple times.
If you pick any app permissions (not delegated permissions), the consent UX defaults to the "consent on behalf of the organization" experience. In this mode the consent page ALWAYS shows, whether the admin consented previously or not. You can also force this behavior if you make a request to the authorize endpoint with the QS parameter of prompt=admin_consent. So let's say you went down this path AND the only permission you have is app-only "Read Directory" and the admin consents. Now a user comes the user doesn't have any grant that allows them to sign in and get an id_token for the app (Read Directory app-only is not currently good for this), so the consent dialog tries to show the admin on behalf of org consent, but this is a non-admin so you get the error.
Now, if you add the delegated "sign me in and read my profile" permission for the app, and have your admin reconsent, you'll see that now the user will not be prompted for consent.
What I'll do is go back to our team and see whether ANY directory permission (app only or delegated) should allow any user to get a sign in token. One could argue that this should be the case.
HTHs,

Allowing all users to impersonate any user in liferay

I have a requirement where I have to allow all of my regular users to impersonate a user of their choice.
I haven't been able to make this work. This is what I've done so far:
Added the following properties to portal-ext.properties:
portal.jaas.enable=false
portal.impersonation.enable=true
Created a role for the purposes of impersonation
Defined permissions for this new role: Portal > Users and organizations > View & Impersonate
Assigned this role to a non-administrator user (user A)
I don't need my users to see the list of users they can impersonate, I just want liferay to impersonate a user if ?doAsUserId=x is present in the url (which does work if you are an administrator).
When I try to impersonate user B using user A, nothing happens. I get this error in the tomcat log:
1ERROR [http-bio-8180-exec-85][PortalImpl:5990] User 80413 does not have the permission to impersonate 25105
(User 80413 is my User A, the one attempting to impersonate user B [25105])
Am I missing something else?
There is a condition in Lifeary, which checks the permission on the list of organizations for the impersonation. So, the user who is impersoneting the other user, must have a permission for "impersonation" in all the organisation of which, these users are part of.
if (doAsUser.isDefaultUser() ||
UserPermissionUtil.contains(
permissionChecker, doAsUserId, organizationIds,
ActionKeys.IMPERSONATE)) {
request.setAttribute(WebKeys.USER_ID, new Long(doAsUserId));
return doAsUserId;
}
So, those 2 users must be part of same organization and must be having impersonation permission for that organization.

How to use Login User credentials to call exchange web service in sharepoint for fetching user mail box?

I don't want to use default credentials because I need to fetch log in user Mail Box information therefore, to call Exchange Web Service I need Log in User credentials. So how can I get current Logged-in user credentials??
Constructor of calling exchangeweb service is as below:
ExchangeServiceBinding exchangeService = new ExchangeServiceBinding()
exchangeService.RequestServerVersionValue = new RequestServerVersion();
exchangeService.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2010;
exchangeService.Credentials = new NetworkCredential("user_LoginID", "LoggedIn_user_password");
you can't access the user password or the credentials from SharePoint directly. You're able to get something like SPContext.Current.Web.CurrentUser.LoginName, but you won't be able to hand over the user password, if UseDefaultCredentials doesn't work for the EWS.

How to get the user name using a Microsoft user id?

Am working on a windows store javascript application. I have used the microsoft login authentication from azure as follows.
client.login("microsoftaccount").done(function (results) {;
userId = results.userId;
refreshTodoItems();
var message = "You are now logged in as: " + userId;
var dialog = new Windows.UI.Popups.MessageDialog(message);
dialog.showAsync().done(complete);
}
Am able to retreive the userid such as "Microsoftaccount:c2892313bla...."
How am I supposed to retreive the associated UserName for that Microsoft account ID?
When you're logged on, on any scripts on the server side you can query for the identities of the user (via the user.getIdentities() function), which will give you an object with access tokens which you can use to talk to the authentication providers. The post at http://blogs.msdn.com/b/carlosfigueira/archive/2012/10/25/getting-user-information-on-azure-mobile-services.aspx has an example on how to get the user name for MS account (and other providers as well).

Resources