I've been playing with PowerShell this week creating a new Azure environment for our deployment, the final part of this calls for a WebJob written in C# to accept a message from a queue and create a new database and create the structure as required.
I was wondering if anyone here has done this before, I have found the azure management libraries for .NET which have examples of database creation but I'm stuck on the authorisation as this will be done from a back end process?
Is there anyway I can create a trust in my Azure environment to allow my WebJob to connect Azure (although the app is running in the same subscription) and create a new database?
At this time I don't really have any code more like ideas which is why I'm asking for help :)
I am assuming I would use something like this to authenticate?
var credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(
"clientid",
"clientsecret",
"tenantid",
AzureEnvironment.AzureGlobalCloud);
// Connect to Azure
var azure = Azure.Authenticate(credentials).WithDefaultSubscription();
I assume I may need to do something in Azure itself to trust the WebJob to have the access to create a new Azure database but this is the part I'm not sure about.
From PowerShell I've done the authentication by letting PS bring up the Microsoft Live Login Screen but this is not practical for a WebJob with no UI.
Hope this makes sense, and someone can shed some light on it for me?
You are on the right track.
You will have to create a service principal for the WebJob, which is essentially credentials for an app. You will get a client id and secret for it (which are the app's username and password), which it can use to authenticate against Azure Active Directory, and get an access token to call into APIs (such as Azure's management APIs).
You can see here how to create the app in Azure AD (which also creates the service principal): https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal#create-an-azure-active-directory-application
Then you can assign a role for the service principal on any resource/resource group/subscription. Since you need it to be able to create resources, it should be a Contributor on a resource group at least. If you also need to create a resource group for
So:
Create the app as in the documentation
Add a key (client secret) to the app as in the documentation
Copy the client id and secret + the tenant id as you will need them later when using the APIs
Assign a role/roles for the service principal via the Portal
You can now write the program which uses the credentials you got (this library is pretty nice: https://learn.microsoft.com/en-us/dotnet/azure/dotnet-sdk-azure-concepts?view=azure-dotnet)
Short note on storing secrets:
You should be careful with the client secret, it is essentially a password.
At minimum, you should store it in the App Settings of the Web App, not in code. An even better way is to use Azure Key Vault together with Azure AD Managed Service Identity: https://joonasw.net/view/azure-ad-managed-service-identity.
Related
I have an app service in Azure operating as an API for a system I'm designing. As the API is responsible for accessing the database directly, I obviously don't want to be storing connection strings containing credentials anywhere if possible, so am looking to use Managed Identities to grant the App Service access to the database (also hosted on Azure).
Within the Azure portal, I've enabled System-Assigned Identity within the Settings section of the App Service, then given the service the role of owner of the SQL Server via SQL Server -> Access Control -> Role Assignments-> Add.
As I understand it, Active Directory Users shouldn't even come into this as they are user-assigned identities rather than system-assigned identities, and take more setting up (or storing their credentials in the connection string).
As for the code, it's pretty much a carbon copy of this >> https://github.com/medhatelmasry/JwtAuthentication, the only differences being that I've added
services.BuildServiceProvider().GetService<ApplicationDbContext>().Database.Migrate();
to the end of the ConfigureServices method within Startup.cs, and added the below to the constructor of ApplicationDbContext as per Microsoft's instructions:
var conn = (System.Data.SqlClient.SqlConnection)Database.GetDbConnection();
conn.AccessToken = (new Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProvider()).GetAccessTokenAsync("https://database.windows.net/").Result;
When attempting to run this service in Azure, however, I get an exception when calling services.BuildServiceProvider().GetService<ApplicationDbContext>().Database.Migrate();:
Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'
I've tried StackOverflow, MSDN, Azure Help, Pluralsight and whatever random forums turn up from Google, and not managed to find an answer on any of them. I've only just got through a whole week of staying up until stupid o'clock every day trying to fix connection string configurations only to find Azure was changing the name of the connection string parameter that I was giving it and not saying a word about it (and nothing in any Microsoft documentation about it either).
Azure is becoming a serious pain in my ass, I haven't even started adding endpoints to the API yet, let alone creating an actual application to use it, this is ridiculous.
Eventually found the answer here >> https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/tutorial-windows-vm-access-sql#create-a-contained-user-in-the-database-that-represents-the-vms-system-assigned-identity
The App Service was indeed set as an owner of the server, but hadn't had a user provisioned on the database, so my problem was resolved by logging into the database via SSMS and running:
CREATE USER [My App Service Name] FROM EXTERNAL PROVIDER
then:
ALTER ROLE db_owner ADD MEMBER [My App Service Name]
However, I removed the ownership role of the App Service on the server's Access Control (IAM) page, and am still able to connect successfully, not sure why that is but this is probably just a lack of SQL user knowledge on my part. It actually suits me as at the moment my App Service has a provisioned SQL user with db_owner role assigned on the database itself, but not on the overall server.
From my understanding you have to go through the prerequisite process of creating, enabling and allowing Azure AD users and also setting SQL Admin to an Azure AD user.
There's a pretty comprehensive guide here including creating, accessing and using tokens for Managed Identities Tutorial: Secure Azure SQL Database connection from App Service using a managed identity
We have a client that currently use a ERP-system to store all their clients. This is a closed source ERP so they can not change the authentication flow. Right now they have an authentication API that various other APIs use but development is slow. They are now facing a challenge in that they need to bring more systems in and given the current structure this takes time since their APIs are tightly coupled with the rest of the systems. They absolutely wan't to avoid other departments from creating applications with their own authentication simply because they cannot keep their pace up.
They wan't to keep SSO for all their customer systems but have better control which users are allowed to do what.
I have been reading about Azure Active Directory B2C and it seems really great. We use Azure Active Directory (AAD) authentication for our internal applications and it works flawlessly most of the time.
Here comes the two part question:
Is it possible to use Azure AD B2C and still keep users in the ERP? For example if we can connect Azure AD B2C to send a request to a service that responds with user data if that user exists given that the credentials are correct.
Extension of question 1. The current ERP-systems gives the user an access token and refresh token. Is it still possible to use Azure Active Directory B2C in this case? Basically add our own Identity Provider that will refresh the access token when needed. Is this a feasible thing to do and are there any guides in creating this? Perhaps IdentityServer4 could be used or can it be simplified? http://openid.net/developers/certified/#OPLibs https://github.com/IdentityServer/IdentityServer4
Given these words on their website I think it should work:
Support all platforms and open standards
https://azure.microsoft.com/en-us/services/active-directory-b2c/
Yes, it is possible. As Miroslav mentions, you should use custom policies. This requires a ramp up on custom policies which can have a steep learning curve, but essentially you would take the starterpack (see getting started) and you would modify the userjourney to not write to the B2C directory (basically remove this step). Instead, you would do a call out to wherever the users are. This call out can either be an OIDC identity provider or a REST API, which are specified using technical profiles.
My company wants to develop something it calls a "Login Broker" for an on-premise desktop application also under development. The on-premise application will make significant use of Azure services (DocumentDb, Table Storage, Service Fabric, etc). Our goal is to be able to distribute the main application without it containing any knowledge of configuration values to reach Azure resources (endpoints, keys, etc). As a user logs in through the Login Broker, the desktop application then becomes aware of how to reach its resources, what permissions that user has within the application, and so on.
So far, my research has taken me in the direction of claims-based authentication (I'm very new to this area), which sounds correct in concept. Once a user logs in, the claims that we want to put into a token would be those specifics I mentioned above, plus we will undoubtedly have other claims that we don't know of yet that we want to assert.
My question is, does my company need to develop a custom login service / broker to authenticate users and deliver a configuration payload, or can Azure Active Directory serve this need in the way I described? Is this the kind of thing that AAD is suited for natively or would this wind up being a shoehorn that we'd rather avoid?
What you described looks like the federated identity, locally Microsoft has the Active Directory Federation Services, in cloud there are a few options:
1) Azure AD Access Control Services - https://azure.microsoft.com/en-us/documentation/articles/fundamentals-identity/#ac
2) Azure AD B2C - https://azure.microsoft.com/en-us/services/active-directory-b2c/
I would recommend to take a look at the Azure AD B2C.
I am using ADAL in order to log in to my app which is being made in Xamarin.Forms against Azure AD. That is all working fine, however I now want to be able to register a new user and to do this need an access token to pass to the constructor of one of my methods.
However, as the user hasn't yet been registered, I need to be able to get an access token from Azure AD without actually supplying any user credentials. I have been told that in a normal web app, I'd be able to send the client id and app key so that Azure AD would know who I was and then send me back an access token but I can't figure out how to implement this in a cross-platform Xamarin app.
If anyone has come across this before, your help would be greatly appreciated.
Thanks.
Use of an app key in a native application is not recommended, regardless sof the dev stack you use to implement it. The reason is that generally devices should not be trusted with secrets. Furthermore, secret distribution is complicated (you can't embed it in the app code).
As a result, ADAL for Xamarin (and all the other flavors of ADAL meant to be used in native apps) does not expose any method for acquiring tokens with an app key.
From a antive app you really need to bootstrap secure communication with a user identity. Once you have that, you can do all sorts of interesting things on the server side (e.g. you API can, given that is running on the server, obtain tokens as an app).
HTH
V.
I'm writing a set of Powershell Cmdlets that allow a user to run admin functions on their domain. Using gData I have been able to do provisioning calls to create new users, list groups and other things of that nature. When trying to list another user's documents (as admin) I hit a roadblock with the DocsList api, so I turned to the Google Drive api instead.
I've since been able to get the Drive API working and have a Cmdlet running based on their QuickStart for DotNet and File List Example. However, I can't seem to figure out how to make it list docs for another user. Everything I've found so far seems to point to the use of Service Accounts for delegation or using the old DocList api instead which is depreciated in favor of the Drive API anyways.
My problem is the Service Accounts seem to be an alternative to the Installed Application, not something I can use at the same time. Or, if I were able to get it working I would have to have each user create their own project and service account, if I'm understanding things.
How can I do this without inconveniencing the users? They've already authenticated themselves as admins, I don't understand why they have to create an API project and service account to achieve the same thing. Would I create a single service account for my API Project? If so, how do I handle the public key it generates and needs access to? That doesn't seem very safe if I'm throwing around the key file.
You can impersonate a user only with service accounts. Once you configure your service account for domain-wide authority, you can make requests with your administrator account as you mention. But, I'm not sure Google Apps allow multiple administrator accounts or not. If they do, all you need is setup a single project and a single service account.