I'm building a WebAPI project using ASP.NET 5/CoreCLR. I have implemented Identity 3 and that works fine. I plan to allow users to use the WebAPI from either a browser or an app (mobile, or third-party like Kodi or foobar2000).
I want to allow "administrative" account tasks (changing password, deleting stuff, etc..) only from the browser and not from the third-parties. The apps should have access only to a restricted amount of controllers or actions. On top of that, I'd like to make it easier for users to authenticate themselves. I don't want them to put their login and password in an app (since these credentials allow to do administrative tasks on their account). Ideally I'd like to add a "third party app" authentication. Since the actions won't be sensitive, I was thinking of providing the ability to generate "API Keys" which would be short.
I'm thinking of a workflow where users would go to their Account page from the browser, click "Generate Third-Party Credentials", and get a 6 or 8 characters-long string to use from the third-party app. I might apply some HMAC later on.
What I'm wondering is what would be the 'proper' (conceptually) way to implement that on top of Identity 3. Is it possible, for instance, to create an identity Claim tied to a user?
Maybe you can use two separate account one for human-user and second for app-user ? Than you can use Claims-Based Authorization.
I'm thinking of a workflow where users would go to their Account page from the browser, click "Generate Third-Party Credentials"
Under this action you can create second account for app and link them with user-account using Claims.
For your app it will be two different account for Authentication/Authorisation but from user perspective it can be one account.
After that you have clear and simply to use solution using ASP.NET5 Authorization.
Related
I was wondering if it was possible to login to different salesforce environments (Sandboxes, scratch orgs, production env, etc) using either Apex/LWC/Aura (or anything that I can make a quick action to). For example, I have a list of credential records, with the username and password, and I would like to have a login button that creates a separate tab that can automatically redirect to that specific instance and log in.
Currently, if a user wants to login to a particular instance, they have to either go to test.salesforce.com or login.salesforce.com (depending on if it's a sandbox or production) manually, then copy the password and username in. The ideal situation is to have a login button that can do this automatically from the record page where the username and password is located.
I think previously this could have been accomplished through the URL, but salesforce has recently patched this out due to security concerns. Is there another good way to do this?
It sounds like you're trying to solve two specific challenges:
Your users need to be able to manage very high volume of credentials.
You need authentication to survive password resets.
The clear solution, in my mind, is to use the OAuth Web Server flow to execute initial authentication and then store the refresh token that results from this flow. This token survives password resets, and may be used more or less indefinitely to create new access tokens - which users can then use to log in via a frontdoor link.
There's an out-of-the-box tool that does this already: the Salesforce CLI. You can authenticate orgs to its toolchain, name them, and subsequently access them with a single command (sfdx force:org:open). Users that prefer a GUI can access the exact same functions in Visual Studio Code.
If you're hellbent on doing custom development to handle this use case, you can, but you need to be very careful of the security implications. As one example, you could implement an LWC + Apex solution that executed the relevant OAuth flows against orgs and stored the resulting data in an sObject, then allowing users to click a button to generate a new access token and do a one-click login.
But... if you do this, you're storing highly sensitive credentials in an sObject, which can be accessed by your system administrators and potentially other users who have relevant permissions. That data could be exfiltrated from your Salesforce instance by an attacker and misused. There's all kinds of risks involved in storing that kind of credential, especially if any of them unlock orgs that contain PII or customer data.
One of the two best answers for that (the other one being 'pure Apex' and relatively more complex) is using Flow.
"You can use a login flow to customize the login experience and integrate business processes with Salesforce authentication. Common use cases include collecting and updating user data at login, configuring multi-factor authentication, or integrating third-party strong authentication methods.enter image description here"
"You can use login flows to interact with external third-party authentication providers by using an API.
For example, Yubico offers strong authentication using a physical security key called a YubiKey. Yubico also provides an example Apex library and login flow on GitHub. The library supplies Apex classes for validating YubiKey one-time passwords (OTPs). The classes allow Salesforce users to use a YubiKey as a second authentication factor at login. For more information, see yubikey-salesforce-client.
You can also implement a third-party SMS or voice delivery service, like Twilio or TeleSign, to implement an SMS-based multi-factor authentication and identity verification flow. For more information, see Deploy Third-Party SMS-Based Multi-Factor Authentication."
learn more here: enter link description here
I got absolutely confused when trying to understand the differences between MicrosoftAccount, AzureAD and OpenIDConnect authentications.
I am trying to build a .Net Core MVC app that allows some users to authenticate with local accounts, but some with Microsoft accounts. I do need to have a local user in DB for both types of authentications as I have some custom authorization mechanisms built on that.
I started with creating the app from template and selected "local accounts" authentication. Then I added the MicrosoftAccount authentication according to this tutorial (https://learn.microsoft.com/en-us/aspnet/core/security/authentication/social/microsoft-logins?view=aspnetcore-3.1). This is using Microsoft.AspNetCore.Authentication.MicrosoftAccount and seems to be working fine.
However, when I create a new app from template and select "work or school account" authentication I can see it uses a different library - Microsoft.AspNetCore.Authentication.AzureAD.UI. It seems to do the same thing. I can see there are events I could hook into to connect the AAD user with my local DB.
Looking through the web I found some other tutorials that were using OpenIDConnect for the same purpose.
How are those methods different? Which one should I use and why?
In future I would like to be able to query the user's directory for a list of other users. Would that requirement be easier met with either of those three methods?
MicrosoftAccount: This is the login with a general Microsoft account, using OAuth2. This is also what Microsoft will refer to as “private account” and useful when you want to authenticate someone just using their Microsoft login as an external authentication provider. This is similar to how you would sign in to sites with your Google account.
AzureAD: This is the sign in to a specific Azure tenant. This is often understood as a “work or school account” because it doesn’t sign people in using a public account but rather some account bound to some organization. Usually, you would have an Azure tenant where you have direct users (or configure it to allow external users) but you want to control access through that Azure AD.
OpenIdConnect: This is the general OpenID Connect protocol which you can use to sign in with many different authentication providers because it is a protocol that many of them will support. You can use OIDC to sign in to either of the above (and many other services) but that will require you to do some more configuration as you will need to figure out specific addresses for example.
You can always use the OpenIdConnect or the OAuth authentication scheme to authenticate with most authentication providers but those are the “manual” schemes which will require you to configure additional things. All the other authentication schemes, including MicrosoftAccount and AzureAD but also the other ones like Google or Twitter build on top of those protocols and come preconfigured so that you do not need to set up much else. So those are mostly for convenience and for more specialized support.
So when you want to authentication through Microsoft or Azure, then you should choose MicrosoftAccount or AzureAD. Which of those depends on where you want to authenticate with. If you have an Azure AD, then you should use that.
I have scoured this and many other sites to find an answer but have come up short every single time. If this is a duplicate, I am very happy to accept direction to the original question with an answer:
I have built an MVC 4 site and I am using the Authorize tag where needed and this is working as expected.
My issue is that I require a mechanism by which to prompt the user (already logged in or some other valid user in the domain) to enter their windows credentials on one page in order to confirm/authorize that user. This is not what the authorize filter is doing. The authorize filter is actually authenticating the user. Thus changing the User.Identity information accordingly.
Is it possible to just authorize a user (not authenticate) without actually changing the User object?
Just returning the 401 response forces the windows prompt but that, in turn, does an authentication, not an authorize.
While a solution could be achieved with a custom action that accepts username/password input, my requirement specifically calls for the native browser windows prompt to be displayed.
The site is using IIS Express and is set up for windows authentication and every aspect of this does what I need. Except for the issue of "true" authorization mentioned above. The browser has to be IE9. Currently running on Windows 10.
No. You're currently using Windows Authentication, and this is how it works. There is no need to login because the user is already logged into Windows, that's the point.
To do what you want, you would need to use an individual auth library like Identity. Which will give you the login capability. However, that doesn't work with AD out of the box, but you can add that in yourself. In otherwords, instead of using the Identity functionality to look a user up by username and password to authenticate, you'd connect to AD over LDAP, and verify the credentials there. You'd also need to use the LDAP connection to add the user's groups in AD to the their roles in Identity. Then, you can utilize the Authorize attribute as normal.
Long and short, if you want to actually allow the user to login as any AD user, then you're pretty much on your own. There's no builtin functionality for that. It's relatively straight-forward, if not entirely easy, to set something up yourself for that that, but again, that's on you.
Everything I'm reading shows that in order for an application to use onedrive, it has to do the oauth2 thing to get credentials. But what if you're a batch process and don't have a web interface for your users.
Google's API has a special type of account called a service account where once you set it up, you can control access to everything from that one account, no need to interact with users. Does such a thing exist for onedrive?
App-only authentication doesn't require the user be prompted for credentials but it also isn't supported in 100% of scenarios. For example, the APIs need a user principle for creating special folders and resolving a user's personal site. Also, it is only supported for OneDrive for Business, not Consumer. Consumer always requires the user be prompted for initial authentication.
Another option would be to spin up a web service of some sort that handles initial user authentication, ie. a sign up page. With that, you can retrieve a refresh token for offline authentication and store it for the user. Every authentication from then on can be done using the refresh tokens, which doesn't require a user prompt.
I finally found this. It's the same basic idea as google's service account, but I think it's harder to use. But at least the concept is supported.
http://blogs.msdn.com/b/exchangedev/archive/2015/01/21/building-demon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow.aspx
When using Windows Identity Foundation (WIF) with multiple Security Token Services (STS), is it possible to provision users before they first access the application?
For example, let's say I have a web site called BufferOverrun where users can login and ask/answer questions and I want to support authentication with external Google accounts. When a user first accesses the page, they have to authenticate with their Google account, then they can access the web application. In this scenario, there are two STSes, Google (for identity authentication) and a custom one for my application (for authorization).
How can I assign claims to a user before that users accesses the system?
Since the identity is owned externally to my application, I cannot assign claims directly to that identity (and I wouldn't want to anyway, as they would be application specific). But since the user has not accessed the system, I do not have an internal identity to assign claims to. I see two possible solutions:
Wait for a user to access the system (creating some default application-specific claims), then use some internal provisioning tool to modify those claims as desired.
Have the provisioning tool allow users to manually map a default identity claim (email address, for example) before that identity authenticates by manually typing it in, so that on first access if the identity asserts that claim, a specific set of application claims are granted.
I see a few issues with both 1 and 2. For 1, all users have some implicit access to the system, even if the default application claims allow no functionality. This seems to work great for something like stackoverflow where the initial account has a certain permission set, and as the user uses the systems, new claims are granted. However, this is likely not desirable for all applications. 2 is error prone, as it requires an admin to manually specify a claim.
In both cases above, how do I provision the identity which has access to actually use the provisioning tool (i.e., an admin account)?
For this, I envision that during application installation time, I require a user to authenticate and set the applicaton claims for that identity to be such that they have "administrative" privileges. Is this a good implementation?
Historically (I am now referring to an existing application), the application specifically interfaced with Active Directory only. The way this was handled was that there was a built-in admin account (not affiliated with AD) that allowed the admin user to first login. After authenticating with the admin application, that user could search AD for users/groups and provision them individually. Any user/group not provisioned by the admin would not have access to the system at all. I don't see this paradigm being applicable to using an external STS like Google, etc, so I am trying to conceive an architecture that would enable external STS systems. Retaining the ability to search the STS is desired, though not required. In practice, the two STSes involved would likely both be Active Directory using federated services.
Note: This is similar to this question and this question.
When using Windows Identity Foundation (WIF) with multiple Security Token Services (STS), is it possible to provision users before they first access the application?
The answer is yes, if you have a way of identitfying those users (e.g. their e-mail)
In this scenario, there are two STSes, Google (for identity authentication) and a custom one for my application (for authorization).
This is frequently used, but not necessarilly always the case. If you rely just on Google, then you could simply have the authorization code in the app itself (e.g. "AuthorizationManager" classes, etc). The value of another STS is that it can be a broker for multiple identities (e.g. Google, LiveID, Yahoo!, whatever) and you can do some authorization related transformations.
Since the identity is owned externally to my application, I cannot assign claims directly to that identity (and I wouldn't want to anyway, as they would be application specific).
Why not? You can define a rule that says:
"Anyone authenticated with Google is a 'reader' in App BufferOverrun". You can even say:
"someone#gmail.com is a 'reader' on BufferOverrun", before someone accesses the app.
You can still use the original approach (an out of band admin account for setup). Or you can also "bootstrap" config during provisioning defining which is the claim that will identify admin users.
Take a look at sample "Federation with Multiple Partners and ACS" (sample 7) in http://claimsid.codeplex.com
We do exactly that.