Cosmos DB permissions on multiple resources - azure

I found the following document: CosmosDB grant permission to multiple resources?
The answer there states that after the resource token broker gets the Permissions feed of the user and sends it back to client:
FeedResponse<Permission> permFeed = await client.ReadPermissionFeedAsync(UriFactory.CreateUserUri("dbid", " userId"));
List<Permission> permList = permFeed.ToList();
The client app can then initialize an instance of the DocumentClient class and pass the list (provided that it will deserialize the Json to List<Permission>).
var jsonString = await response.Content.ReadAsStringAsync();
var permissions = JsonConvert.DeserializeObject<List<Permission>>(jsonString);
var client = new DocumentClient(new Uri(EndpointUri), permisions);
The problem that I have is that the Permission class has a Token property that has only a getter and no setter exists. The following source code is from Microsoft.Azure.Documents namespace.
namespace Microsoft.Azure.Documents
{
public class Permission : Resource
{
[JsonProperty(PropertyName = "resource")]
public string ResourceLink { get; set; }
[JsonProperty(PropertyName = "resourcePartitionKey")]
public PartitionKey ResourcePartitionKey { get; set; }
[JsonConverter(typeof (StringEnumConverter))]
[JsonProperty(PropertyName = "permissionMode")]
public PermissionMode PermissionMode { get; set; }
[JsonProperty(PropertyName = "_token")]
public string Token { get; } <------------------------------------- HERE
}
}
As such, trying to serialize the Token field, the value copied is null.
Anyone has any solution for that?

Related

User Flow - API connector cannot parse response

I have an Azure B2C user flow. It is associated with an API Connector pointing to an Azure Function. The function returns a ResponseContent with extension claims:
public class ResponseContent
{
public const string ApiVersion = "1.0.0";
public ResponseContent()
{
this.version = ResponseContent.ApiVersion;
this.action = "Continue";
}
public ResponseContent(string action, string userMessage)
{
this.version = ResponseContent.ApiVersion;
this.action = action;
this.userMessage = userMessage;
}
public ResponseContent(string userTypes, string accountIdentifiers, string pricebookAuthorized, string portalAuthorized)
{
this.version = ResponseContent.ApiVersion;
this.action = "Continue";
this.extension_UserTypes = userTypes;
this.extension_AccountIdentifiers = accountIdentifiers;
this.extension_PricebookAuthorized = pricebookAuthorized;
this.extension_PortalAuthorized = portalAuthorized;
}
public string version { get; }
public string action { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string userMessage { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string extension_UserTypes { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string extension_AccountIdentifiers { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string extension_PricebookAuthorized { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string extension_PortalAuthorized { get; set; }
}
Here are the claims of the user flow:
When I run this Azure function using Postman, the following is returned:
{
"version": "1.0.0",
"action": "Continue",
"extension_UserTypes": "",
"extension_AccountIdentifiers": "",
"extension_PricebookAuthorized": "",
"extension_PortalAuthorized": ""
}
But when I try to run the user flow on Azure, I get
Microsoft.Identity.Client.MsalServiceException:
AADB2C90261: The claims exchange 'PreSendClaimsRestful' specified in
step '2' returned HTTP error response that could not be parsed.
What might be wrong, and how this can be diagnosed?
Please check if below points can help:
Each key value pair in the JSON is treated as string, string
collection or Boolean.
AADB2C may not deserialise the claim in the JSON you send. One may
need to deserialise the string at the API, or will have to return a
nested JSON object without the escape characters.
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
Reference: dotnet-external-identities-api-connector-azure-function-validate
· GitHub
To troubleshoot the unexpected response, try sending Azure AD B2C
logs to Application Insights.
References:
Azure B2C - REST API call Error
Add extra claims to an Azure B2C user flow using API connectors and
ASP.NET Core | (damienbod.com)
how-to-parse-json-in-net-core

Getting SQL Azure database replication role in C#

I am trying to check the replication role of a SQL Azure database using the Azure SDK for .NET.
I used the SqlManagementClient to fetch databases from our subscription but there are no properties indicating the replication role.
I used the following code to fetch databases.
var client = GetSqlManagementClient();
var database = client.Databases
.List("<serverName>")
.First(x => x.Name == "<databaseName>");
Is there another way to get this information that I am missing?
If you means to read secondly location, I think Azure ARM management could help us to do this. I have tried it on my local and get the result as followings:
[Update]
Here is my test code:
public async Task<string> GetToken()
{
AuthenticationResult result = null;
string test;
AuthenticationContext authContext = new AuthenticationContext(adInfo.AuthUrl + adInfo.Telnant);
ClientCredential cc = new ClientCredential(adInfo.ClientId, adInfo.ClientSecret);
try
{
result = await authContext.AcquireTokenAsync(adInfo.Resource,cc);
test = result.AccessToken;
return test;
}
catch (AdalException ex)
{
return ex.Message;
}
}
public async Task GetSQLInfo()
{
string token = await GetToken();
var sqlclient = new SqlManagementClient(new TokenCloudCredentials(adApplication.Subscription, token));
var data = await sqlclient.Databases.GetAsync("jatestgroup", "jaserver", "jasql");
}
Here is my class about adInfo and adApplication:
public class AdInfo
{
[JsonProperty(PropertyName = "clientid")]
public string ClientId { get; set; }
[JsonProperty(PropertyName = "clientsecret")]
public string ClientSecret { get; set; }
[JsonProperty(PropertyName = "returnurl")]
public string ReturnUrl { get; set; }
[JsonProperty(PropertyName = "telnantid")]
public string Telnant { get; set; }
[JsonProperty(PropertyName = "authurl")]
public string AuthUrl { get; set; }
[JsonProperty(PropertyName = "resource")]
public string Resource { get; set; }
}
public class AdApplication
{
[JsonProperty(PropertyName = "ARMTemplate")]
public AdInfo Application { get; set; }
[JsonProperty(PropertyName = "subscription")]
public string Subscription { get; set; }
}
My Json Settings:
{
"ARMTemplate": {
"clientid": "****",
"clientsecret": "****",
"returnurl": "http://localhost:20190",
"telnantid": "****",
"authurl": "https://login.microsoftonline.com/",
"resource": "https://management.core.windows.net/"
},
"subscription": "***"
}
Since this issue is more related with Auth failed. I would suggest you create a new thread and give more info for us if my code does not give you help.

MVC 5 - Add a claim to a user

I am developing a MVC 5 internet application and am using Identity 2.1.
How can I add a claim to a user, after the user has logged in, where I knows the username?
Here is what I have:
public void AddClaimToUser(string userName, string type, string value )
{
var AuthenticationManager = HttpContext.Current.GetOwinContext().Authentication;
var Identity = new ClaimsIdentity(userName);
Identity.AddClaim(new Claim(type, value));
AuthenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(new ClaimsPrincipal(Identity), new AuthenticationProperties { IsPersistent = true });
}
However, after I call this method, and I check the claims for the user, the added claim is not listed.
Here is the code that I am using to get the claims in a controller:
var identity = (ClaimsIdentity)User.Identity;
IEnumerable<Claim> claims = identity.Claims;
Thanks in advance.
First Of all you have to create a method for add claim under IdentityModels.cs class.like this,in below code i have created a claim for CompanyId.
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool IsActive { get; set; }
public int? CompanyId { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
userIdentity.AddClaim(new Claim("CompanyId", (this.CompanyId + "" ?? "0")));
return userIdentity;
}}
After write above code,you need to write one more method in IdentityConfig.cs
public static class IdentityExtensions{
public static int CompanyId(this IIdentity identity)
{
return Convert.ToInt32(((ClaimsIdentity)identity).FindFirst("CompanyId").Value);
}}
After this you can get your created claim in any controller by just typing..
int companyId = User.Identity.CompanyId();
Giving AuthenticationResponseGrant is not enough to add claim to already logged in user. You need to get identity, add new claim ( you already do this), then sign user out and sign-in again. I pretty much do this in this answer

ServiceStack issue with object serialization between test method and service

Good day,
We are experiencing an issue with serialization where a request object set with a value for one property ends up being received by the service with the value assigned to a different property. Please see below for more information.
We are using the 3.9.71 version of ServiceStack NuGet packages. The solution is made up of the following projects:
Project.Host: Used for self-hosting ServiceStack and contains Service classes.
Project.DTO: All services DTOs and surrounding classes.
Project.Tests: Contains unit tests.
The problems has been identified to only one class/service, namely MinimalUser and MinimalUserService, which you can see code for both below:
MinimalUser.cs
namespace Project.DTO
{
[Route("/User/{Identity}", "GET")]
[Route("/User/{Username}", "GET")]
[Route("/User/{DisplayName}", "GET")]
public class MinimalUser : IReturn<MinimalUser>
{
#region Properties
public int? Identity { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string DisplayName { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Language { get; set; }
public string TimeZone { get; set; }
public string Culture { get; set; }
public List<string> Roles { get; set; }
public List<string> Permissions { get; set; }
public DiscUserDetails DiscUserDetails { get; set; }
#endregion
#region Constructors
public MinimalUser() { }
public MinimalUser(UserAuth auth)
{
if (auth != null)
{
this.Identity = auth.Id;
this.Username = auth.UserName;
this.DisplayName = auth.DisplayName;
this.Email = auth.Email;
this.FirstName = auth.FirstName;
this.LastName = auth.LastName;
this.Language = auth.Language;
this.TimeZone = auth.TimeZone;
this.Culture = auth.Culture;
this.Roles = auth.Roles;
this.Permissions = auth.Permissions;
this.DiscUserDetails = auth.Get<DiscUserDetails>();
}
}
#endregion
#region Methods
public static MinimalUser FromUserAuth(UserAuth auth)
{
return auth == null ? new MinimalUser() : new MinimalUser
{
Identity = auth.Id,
Username = auth.UserName,
DisplayName = auth.DisplayName,
Email = auth.Email,
FirstName = auth.FirstName,
LastName = auth.LastName,
Language = auth.Language,
TimeZone = auth.TimeZone,
Culture = auth.Culture,
Roles = auth.Roles,
Permissions = auth.Permissions,
DiscUserDetails = auth.Get<DiscUserDetails>()
};
}
#endregion
}
}
DiscUserDetails.cs
namespace Project.DTO
{
public class DiscUserDetails
{
public int? LocationId { get; set; }
public bool IsActive { get; set; }
public byte NumberOfFailedLoginAttempts { get; set; }
public bool MustChangePasswordAtNextLogon { get; set; }
public int? LastAcceptedPolicyId { get; set; }
}
}
MinimalUserService.cs
namespace Project.Services
{
[Authenticate]
[RequiredRole(new string[] { RoleNames.Admin })]
public class MinimalUserService : Service
{
IUserAuthRepository authRepo = AppHost.Resolve<IUserAuthRepository>() as OrmLiteAuthRepository;
/// <summary>
/// Return a minimalist structure of user insensitive information.
/// </summary>
/// <param name="request">The request containing the ID of the user.</param>
/// <returns>A minimalist structure of user insensitive information.</returns>
public object Get(MinimalUser request)
{
if (request.Identity != null)
return new MinimalUser(authRepo.GetUserAuth(request.Identity.ToString()));
else if (request.Username != null)
return new MinimalUser(authRepo.GetUserAuthByUserName(request.Username));
else
return null;
}
}
}
From my test project, I run the following test:
[TestMethod]
public void GetMinimalUserByUsername()
{
AuthResponse authResponse = client.Post<AuthResponse>("/auth", new Auth
{
UserName = "accountwithadminrole",
Password = "blablabla",
RememberMe = true,
provider = CredentialsAuthProvider.Name
});
MinimalUser request = new MinimalUser
{
DisplayName = BaseAccounts.System,
};
MinimalUser user = client.Get<MinimalUser>(request);
Assert.IsNotNull(user);
}
I clearly see, before issuing the client.Get method, that the request object have all its properties set to null except for the DisplayName which has the value "system". When this request is received by the MinimalUserService Get method, the value "system" is now assigned to the property UserName and DisplayName is null.
Also, I've tried to comment properties one by one in the MinimalUser class, suspecting one of its field could be causing serialization problem and I would end up having random 'Bad Request' when commenting a certain number of properties. Although, I could comment a properties randomly and one property that previously caused a 'Bad Request' would not do it depending on others properties commented out.
I'm really confused about how this can possibly happens. I feel the service and DTO are simple compared to others from this same project but I'm sure I'm doing something really stupid here.
Don't hesitate to ask for more details, it will be my pleasure to give all information you need.
Thank you.
The reason for Username to be populated instead of DisplayName is because of the routes you have defined for MinimalUser. In MinimalUser.cs you defined 2 identical routes:
[Route("/User/{Identity}", "GET")]
[Route("/User/{Username}", "GET")]
[Route("/User/{DisplayName}", "GET")]
Username and Displayname are both strings. This makes it impossible for ServiceStack to determine the appropriate route direct the request to as it cannot differentiate between the routes. You can fix this by either removing a route, or by adding additional text to one of the routes; eg /User/ByDisplayName/{Username}.

Json Deserialization BodyStyle Wrap issue using IPWorks nSoftware

I am using IPWorks nsoftware for creating service. In it, to call a service I am using
Rest rest = new Rest();
rest.Accept = "application/json";
rest.ContentType = "application/json";
rest.User = "UserName";
rest.Password = "Password";
rest.Get(#"http://Foo.com/roles.json");
string result = rest.TransferredData;
var listRoles = JsonSerializer.DeserializeFromString<List<role>>(result);
I am getting the Json response as a string
[{"role":{"name":"Administrator","created_at":"2012-02-11T09:53:54-02:00","updated_at":"2012-04-29T23:43:47-04:00","id":1"}},{"role":{"name":"NormalUser","created_at":"2013-02-11T08:53:54-02:00","updated_at":"2013-04-29T23:43:47-03:00","id":2"}}]
Here the json string contains my domain object “role” which gets appended to my response (i.e the body style of the message is wrapped) .
I am using ServiceStack.Text’s Deserializer to convert the response string to my object. But since it’s wrapped, the deserilization is incorrect.
Is there anything that I am missing here ? Is there any “BodyStyle” attribute which could be added to the Rest request?
The GitHubRestTests shows some of the different ways you can deserialize a 3rd party json API with ServiceStack's JSON Serializer.
If you want to deserialize it into typed POCOs then judging by your JSON payload the typed POCOs should look something like:
public class RolePermissionWrapper
{
public Role Role { get; set; }
public Permission Permission { get; set; }
}
public class Role
{
public long Id { get; set; }
public string Name { get; set; }
public DateTime? Created_At { get; set; }
public DateTime? Updated_At { get; set; }
}
var listRoles = JsonSerializer.DeserializeFromString<List<RolePermissionWrapper>>(result);

Resources