ASP.NET Core IdentityServer4 role is uppercase - asp.net

I use the following sample as basis: GitHub QuickStart
I added to Config.cs UserClaims = new[] {ClaimTypes.Role} to get the role of the authenticated user. Everything works fine and I can see the role if I'm writing the claims out, like: role ADMIN.
What im struggeling with is, that the role name is uppercase. In the database is the following entry:
{
"_id" : ObjectId("59008a10cdaaf196d44bae8e"),
"Name" : "Admin",
"NormalizedName" : "ADMIN"
}
So is there a way to get the "real" name of the role?

Related

Bicep roleAssignments/write permission error when assigning a role to Keyvault

I am using GitHub Actions to deploy via Bicep:
- name: Login
uses: azure/login#v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Deploy Bicep file
uses: azure/arm-deploy#v1
with:
scope: subscription
subscriptionId: ${{ secrets.AZURE_CREDENTIALS_subscriptionId }}
region: ${{ env.DEPLOY_REGION }}
template: ${{ env.BICEP_ENTRY_FILE }}
parameters: parameters.${{ inputs.selectedEnvironment }}.json
I have used a contributor access for my AZURE_CREDENTIALS based on the output of the next command:
az ad sp create-for-rbac --n infra-bicep --role contributor --scopes /subscriptions/my-subscription-guid --sdk-auth
I am using Azure Keyvault with RBAC. This Bicep has worked fine until I tried to give an Azure Web App a keyvault read access to the Keyvault as such:
var kvSecretsUser = '4633458b-17de-408a-b874-0445c86b69e6'
var kvSecretsUserRole = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', kvSecretsUser)
resource kx_webapp_roleAssignments 'Microsoft.Authorization/roleAssignments#2022-04-01' = {
name: 'kv-webapp-roleAssignments'
scope: kv
properties: {
principalId: webappPrincipleId
principalType: 'ServicePrincipal'
roleDefinitionId: kvSecretsUserRole
}
}
Then I was hit with the following error:
'Authorization failed for template resource 'kv-webapp-roleAssignments'
of type 'Microsoft.Authorization/roleAssignments'.
The client 'guid-value' with object id 'guid-value' does not have permission to perform action
'Microsoft.Authorization/roleAssignments/write' at scope
'/subscriptions/***/resourceGroups/rg-x/providers/Microsoft.KeyVault/vaults/
kv-x/providers/Microsoft.Authorization/roleAssignments/kv-webapp-roleAssignments'.'
What are the total minimal needed permissions and what should my az ad sp create-for-rbac statement(s) be and are there any other steps I need to do to assign role permissions?
To assign RBAC roles, you need to have either User Access
Administrator or Owner role that includes below permission:
Microsoft.Authorization/roleAssignments/write
With Contributor role, you cannot assign RBAC roles to Azure resources. To confirm that, you can check this MS Doc.
I tried to reproduce the same in my environment and got below results:
I used the same command and created one service principal with Contributor role as below:
az ad sp create-for-rbac --n infra-bicep --role contributor --scopes /subscriptions/my-subscription-guid --sdk-auth
Response:
I generated one access token via Postman with below parameters:
POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
grant_type:client_credentials
client_id: <clientID from above response>
client_secret: <clientSecret from above response>
scope: https://management.azure.com/.default
Response:
When I used this token to assign Key Vault Secrets User role with below API call, I got same error as you like below:
PUT https://management.azure.com/subscriptions/d689e7fb-47d7-4fc3-b0db-xxxxxxxxxxx/providers/Microsoft.Authorization/roleAssignments/xxxxxxxxxxx?api-version=2022-04-01
{
"properties": {
"roleDefinitionId": "/subscriptions/d689e7fb-47d7-4fc3-b0db-xxxxxxxxxx/providers/Microsoft.Authorization/roleDefinitions/4633458b-17de-408a-b874-0445c86b69e6",
"principalId": "456c2d5f-12e7-4448-88ba-xxxxxxxxx",
"principalType": "ServicePrincipal"
}
}
Response:
To resolve the error, create a service principal with either User Access Administrator or Owner role.
In my case, I created a service principal with Owner role like below:
az ad sp create-for-rbac --n infra-bicep-owner --role owner --scopes /subscriptions/my-subscription-guid --sdk-auth
Response:
Now, I generated access token again via Postman by replacing clientId and clientSecret values like below:
POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
grant_type:client_credentials
client_id: <clientID from above response>
client_secret: <clientSecret from above response>
scope: https://management.azure.com/.default
Response:
When I used this token to assign Key Vault Secrets User role with below API call, I got response successfully like below:
PUT https://management.azure.com/subscriptions/d689e7fb-47d7-4fc3-b0db-xxxxxxxxxxx/providers/Microsoft.Authorization/roleAssignments/xxxxxxxxxxx?api-version=2022-04-01
{
"properties": {
"roleDefinitionId": "/subscriptions/d689e7fb-47d7-4fc3-b0db-xxxxxxxxxx/providers/Microsoft.Authorization/roleDefinitions/4633458b-17de-408a-b874-0445c86b69e6",
"principalId": "456c2d5f-12e7-4448-88ba-xxxxxxxxx",
"principalType": "ServicePrincipal"
}
}
Response:
UPDATE:
Considering least privileges principle, you need to create custom RBAC role instead of assigning Owner role.
To create custom RBAC role, follow below steps:
Go to Azure Portal -> Subscriptions -> Your Subscription -> Access control (IAM) -> Add -> Add custom role
Fill the details with name and description, make sure to select Contributor role after choosing Clone a role like below:
Now, remove below permission from NotAction Microsoft.Authorization/roleAssignments/write
Now, add Microsoft.Authorization/roleAssignments/write permission in Action:
Now, click on Create like below:
You can create service principal with above custom role using this command:
az ad sp create-for-rbac --n infra_bicep_custom_role --role 'Custom Contributor' --scopes /subscriptions/my-subscription-guid --sdk-auth
Response:

.NET allow an "extra access" to a folder

(.NET Core 3.1 application)
Now, I may have cornered myself with this ... ,
Folder Structure
To access Account folders the user needs to be in the role administrator
options.Conventions.AuthorizeAreaFolder("Administration", "/Account", "RequireAdministrator");
options.AddPolicy("RequireAdministrator", policy => policy
.RequireRole("Administrator")
.RequireAuthenticatedUser());
What I want
I created a new role: DataConsulter which I want to give access to Account/Records, but I don't want it to be in administrator role. Also this new role shouldn't be needed for administrator users to access the Account/Records folder. Can I achieve this without changing the folders structure? Should I?
I guess I want something like this (after removing the previous access as suggested by #jb11):
options.AddPolicy("RequireAdministrator", policy => policy
.RequireRole("Administrator" || "DataConsulter")
.RequireAuthenticatedUser());
When you call AuthorizeAreaFolder, an AuthorizeAttribute is added to the PageApplicationModel's EndpointMetadata.
Therefore, to override the authorisation for a specific folder this attribute needs to be removed. This can be achieved by calling AddFolderApplicationModelConvention, identifying the attribute and removing it.
options.Conventions.AddFolderApplicationModelConvention("/Account/Records", action =>
{
var authorizeAttribute = action.EndpointMetadata.FirstOrDefault(r => r is AuthorizeAttribute {Policy: "RequireAdministrator"});
if (authorizeAttribute != null)
{
action.EndpointMetadata.Remove(authorizeAttribute);
}
});

Assign Role to User with WordPress REST API

I want to add user with the WordPress REST API. Each time I do, a default role of SUBSCRIBER is added to that user. No matter which role I include in my post request, it still assigns the SUBSCRIBER role.
Here is my JSON Post request:
{
"username" : "Paule",
"first_name" : "Paul",
"last_name" : "Ibukwe",
"email" : "david.george#dugenterprise.com",
"password" : "LoremIpsum123",
"roles" : ["Candidate"]
}

Can't create cloudsql role for Service Account via api

I have been trying to use the api to create service accounts in GCP.
To create a service account I send the following post request:
base_url = f"https://iam.googleapis.com/v1/projects/{project}/serviceAccounts"
auth = f"?access_token={access_token}"
data = {"accountId": name}
# Create a service Account
r = requests.post(base_url + auth, json=data)
this returns a 200 and creates a service account:
Then, this is the code that I use to create the specific roles:
sa = f"{name}#dotmudus-service.iam.gserviceaccount.com"
sa_url = base_url + f'/{sa}:setIamPolicy' + auth
data = {"policy":
{"bindings": [
{
"role": roles,
"members":
[
f"serviceAccount:{sa}"
]
}
]}
}
If roles is set to one of roles/viewer, roles/editor or roles/owner this approach does work.
However, if I want to use, specifically roles/cloudsql.viewer The api tells me that this option is not supported.
Here are the roles.
https://cloud.google.com/iam/docs/understanding-roles
I don't want to give this service account full viewer rights to my project, it's against the principle of least privilege.
How can I set specific roles from the api?
EDIT:
here is the response using the resource manager api: with roles/cloudsql.admin as the role
POST https://cloudresourcemanager.googleapis.com/v1/projects/{project}:setIamPolicy?key={YOUR_API_KEY}
{
"policy": {
"bindings": [
{
"members": [
"serviceAccount:sa#{project}.iam.gserviceaccount.com"
],
"role": "roles/cloudsql.viewer"
}
]
}
}
{
"error": {
"code": 400,
"message": "Request contains an invalid argument.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.cloudresourcemanager.projects.v1beta1.ProjectIamPolicyError",
"type": "SOLO_REQUIRE_TOS_ACCEPTOR",
"role": "roles/owner"
}
]
}
}
With the code provided it appears that you are appending to the first base_url which is not the correct context to modify project roles.
This will try to place the appended path to: https://iam.googleapis.com/v1/projects/{project}/serviceAccount
The POST path for adding roles needs to be: https://cloudresourcemanager.googleapis.com/v1/projects/{project]:setIamPolicy
If you remove /serviceAccounts from the base_url and it should work.
Edited response to add more information due to your edit
OK, I see the issue here, sorry but I had to set up a new project to test this.
cloudresourcemanager.projects.setIamPolicy needs to replace the entire policy. It appears that you can add constraints to what you change but that you have to submit a complete policy in json for the project.
Note that gcloud has a --log-http option that will help you dig through some of these issues. If you run
gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$NAME --role roles/cloudsql.viewer --log-http
It will show you how it pulls the existing existing policy, appends the new role and adds it.
I would recommend using the example code provided here to make these changes if you don't want to use gcloud or the console to add the role to the user as this could impact the entire project.
Hopefully they improve the API for this need.

How do you delete user accounts in Meteor?

The only way I have found to delete user accounts in meteor (other than emptying the database with mrt reset), is by actually logging into that specific user account, and deleting the account from the console, using:
Meteor.users.remove('the user id');
But like I said, I need to be logged in as that specific user, and have not been able to find a solution which enables me to delete any user from the db. I'm sure it has something to do with permissions or roles, but I am not sure how to proceed / what is the best solution / how to set an administrative role for a particular user, so that I can delete different user accounts.
You could do
meteor mongo
or
meteor mongo myapp.meteor.com for a deployed app
Then
db.users.remove({_id:<user id>});
I wouldn't recommend it but if you want to delete any user without being logged in from meteor you would need to modify the allow rules. But deleting a user is a very unlikely event hence the above might be the best way to do it.
Anyway if you do want, modify the Meteor.users.allow({remove:function() { return true }); property. See http://docs.meteor.com/#allow. You could add in some custom logic there so it'll only let you do so if you're the admin
I was having trouble doing this on nitrous.io because I couldn't open both Meteor and Mongo. I put:
Meteor.users.remove(' the _id of the user ');
in the isServer section to remove the user.
If anyone is still looking for an answer to this question, I have outlined my solution below.
When I create a new user, I add a field called role in my user document. If I want a user to be able to remove other users from the Meteor.users collection, I give him a role of administrator. If not, I give him a role of member. So, my user document looks something like this -
{
"_id" : ...,
"createdAt" : ...,
"services" : {...},
"username" : "test",
"profile" : {
"name" : "Test Name",
"role" : "administrator"
}
}
On the client, I have a list of users (added using a #each template tag) with a remove button next to each user. A user has to login to see this list. I defined an event handler for the remove button -
'click #remove-user-btn': function () {
Meteor.users.remove({ _id: this._id }, function (error, result) {
if (error) {
console.log("Error removing user: ", error);
} else {
console.log("Number of users removed: " + result);
}
})
}
However, Meteor.users does not allow remove operations from the client by default. So, you have to edit the Meteor.users.allow callback in the server as shown below to allow the users to be removed from the client side. But we need to make sure that only a user with an administrator role is allowed this privilege.
Meteor.users.allow({
remove: function (userId, doc) {
var currentUser, userRole;
currentUser = Meteor.users.findOne({ _id: userId }, { fields: { 'profile.role': 1 } });
userRole = currentUser.profile && currentUser.profile.role;
if (userRole === "administrator" && userId !== doc._id) {
console.log("Access granted. You are an administrator and you are not trying to delete your own document.");
return true;
} else {
console.log("Access denied. You are not an administrator or you are trying to delete your own document.");
return false;
}
},
fetch: []
});
This is the general idea. You can build upon this to suit your needs.
Here are the steps to delete user from mongo through console:
step 1: open new console
step 2: change diretory to your app such as (cd myapp)
step 3 : enter command meteor mongo
step 4: make sure there exists a table called users, db.users.find({});
step 5: find the userid of the user you wish to delete and type :
db.users.remove({_id:"nRXJCC9wTx5x6wSP2"}); // id should be within quotes

Resources