I have a web API that is authenticated by Azure's AD.
Within the API codes, what is the code to retrieve the username of the authenticated user?
Using System.Web.HttpContext.Current.User.Identity.Name will retrieve the email address that they have used to log in with.
As a side note, I am using this to control what the user has access to on the site. Because of how I am implementing it, it is more convenient for me to maintain a database of the usernames and their roles. However, if you are doing the same thing, it is also worth looking into [Authorize] and maintaining site access that way.
Related
I am wondering if it is possible to use Microsoft's Graph API in order to create a cookie in IE given the username and password, (preferably using C# or VB.net), so that when the user connects to sharepoint with IE, he/she won't have to log into sharepoint via the login screens.
I'm having difficulty searching for examples because most examples describe how to authenticate a user. I am not looking to authenticate a user though, I am looking to create and store a cookie to force a user login.
Thank you for any advice.
No, and this should never be done. First because cookies are simply not secure. Secondly because you should never be storing any encrypted password anywhere.
I'm really not sure how Graph API fits into the scenario you provided. Microsoft Graph is a REST based API. It doesn't authenticated users on its own, you pass in a valid access token with each call. How you retrieve that token depends on if you're using delegated or application permission scopes.
From the scenario you described, it sounds like you're looking for SharePoint Single Sign-On (SSO). There are a few ways to do this but generally it is done using ADFS and AADSync. There is a walkthrough for setting this up: Step-By-Step: Setting up AD FS and Enabling Single Sign-On to Office 365. Be forewarned however, this is not a trivial process.
I am building a reactjs website that will communicate with asp.net web api 2 to save and retreive data.
but I am not sure how to do this.
I know to accomplish this on a high level it would be something like
User comes to my site and hits signup/log
Chooses which provider then want to use(google, facebook and etc). I am only want to support external providers(ie I don't want to have to deal with usernames/pwds)
User it sent to authenticated part of site
User clicks "add course" that data send via ajax to webapi with some sort of token to prove they have access to these methods.
I am not sure how to implement this problems I see is
Reactjs I guess is handling the authentication part? then once they been authenticated it would have to be saved in my db via webapi so it knows about this new user?
Reactjs would have to block users from going to secure pages till they are authenticated
Web api would have to generate a token for the user for that session so they can access the web api(I want to stop people from consuming my api).
Is there some simple example out there how to achieve this?
Reactjs I guess is handling the authentication part? then once they been authenticated it would have to be saved in my db via webapi so it knows about this new user
Better use some third party auth library here like PassportJS that does the auth for you using strategies like Passport-Facebook. This will give you an Oauth access token from Facebook upon authentication. You can now save this token in your cookies (or localStorage), take a look at the security considerations.
Should you store it in a DB? Here are some arguments about it.
Reactjs would have to block users from going to secure pages till they are authenticated
This can be done by checking if they have a valid token.
Web api would have to generate a token for the user for that session so they can access the web api(I want to stop people from consuming my api).
This can be easily achieved by using JSON Web Tokens. Note that you will have to store the JWT in your client side locally, along side your FB-Google oauth tokens (or you can relegate that to a single API by storing them in DB?. Its a design choice, I would prefer to store them separately and save a lot of hassle).
We have an ASP.NET/MVC website that's using FormsAuthentication. As is usual, when the user tries to access a page, and doesn't have a valid FormsAuthentication cookie, IIS redirects him to the login view. When the user does a HttpPost to the login controller, our controller action makes a call to our WebApi webservice, which validates username, password, and customerid against a Sql Server database. If the authentication passes, the controller action sets a FormsAuthentication cookie, and redirects to the page the user had asked for.
Now sales is making noises about "Single Sign-On", though I'm not clear exactly what they mean by that. From what I've read, in the Microsoft World this usually means accessing MS's Active Directory Federation Services.
At this point I have almost no idea how this would work, but before I dig into this too deeply, would it be possible to put the authentication code within the WebApi webservice, where we could choose to validate against the Sql Server database, or against whichever ADFS server was appropriate for the specified customer?
Our problem is that we have I don't know how many thousands of users, working for some hundreds of customers. Many customers will not have ADFS running, and those who do will each have their own ADFS server.
Most of what I see with respect to Single Sign-On seems to involve doing browser redirection to the ADFS server, then redirection back, and looks to be avoiding login at all, if you're already logged in. I don't think we can do that, in our case. We can't know which ADFS server to redirect to, until we hit the database.
So, the question - is it possible to do ADFS authentication entirely from C# code in our WebAPI web service?
(One possible complication - the website itself has zero access to any database. The sole configuration setting in its web.config is the base URL of the webservice. Whatever authentication happens has to happen in the webservice, not in the website.)
First of all, "Single Sign-On" (SSO) is not limited to ADFS. It simply means that you type your credentials only once, and then all systems you access automatically "recognize" you; all subsequent authorizations request are transparent. For instance, if you have several web sites using Windows Authentication in your company Intranet (same AD domain), you have SSO: you authenticate once when you log in to your computer, and then your web browser authenticates automatically to these web sites using NTLM or Kerberos. No ADFS in this case.
What ADFS (and "Federation" more generally) allows, is SSO accross security boundaries. In Windows world, a security zone is typically created by an Active Directory forest; everything within this forest is accessible using SSO provided by Windows authentication. But as soon as you leave this zone (SaaS application, web site in another company network), you need another authentication protocol to perform SSO, and these protocols are implemented in ADFS.
Then about your particular problem:
What you could do is instead of using FormsAuth, you use AdfsAuth. When a unknown user accesses a page, he would be redirected to ADFS for authentication (using browser redirects as you correctly mention). To know which ADFS server should authenticate your user, you need a way to differentiate them indeed: a list of IP range per customer? a different URL per customer? If you don't have something like this, then the only way is to show them a list of choices such as: "I work for CompanyA", "I work for CompanyB", "I work for CompanyC", "I don't work for any of these companies and want to authenticate using FormsAuth."
In this case, what your WebApi web service has to do is: if I know which ADFS server to use, redirect the user there. Otherwise authenticate the user as usual using the database.
When you use AdfsAuth for a customer, your database is useless. You can delete all credentials related to this customer.
do ADFS authentication entirely from C# code in our WebAPI
Well it's possible to "re-implement" ADFS in your service, but you won't get SSO if you do that. When you use federation, your redirect the user to the ADFS server of his company. This ADFS server is in the same domain as his computer, so the user gets SSO here. Once again, your users can't get SSO if you authenticate them yourself, because your users are not in the same security zone as your site.
When authenticating to multiple identity providers, it is typical redirect to your own STS. So, in this case, you would have www.yourapp.com redirecting to sts.yourapp.com, which redirects to sts.somecustomer.com.
The specific tools to enable such a dataflow is the home realm parameter (whr), and the AD FS Powershell API (to allow IDP maintenance).
Your RP-STS acts as the trust-point for the app, and manages selection of the appropriate IDP. One RP-STS, many IP-STS's. Each of your Customer's IP-STS gets set up as a Claims Provider Trust in AD FS.
As always, Vittorio has already covered the subject better than I could.
I have a very simple implementation of the AspNet.Identity apiservice using Entity Framework that hands out tokens that cam be used to authorize requests through out all the services and web sites. Users have claims to identify what they are authorized to do within our system. Some of these users (internal users) will have also have AD accounts and rather than have them have to remember different passwords I would like to authenticate through AD for these users then use the AspNet.Identity.EntityFramework to add claims. Ideally if a user is already logged into the domain on there PC they would not even have to enter their password.
How can i get our AspNet.Identity implementation to validate with AD?
I have already seen this question Use ActiveDirectory authorization with ASP.NET Identity but I am not using the ThinkTecture Identity Server and it seems to be using something other than AspNet.Identity and I do not want to replace our current implementation.
Can anyone give me a course of action or point me towards a tutorial that accomplishes something similar?
It depends. VM, Cloud, Local Machine? If a machine on the network, could be different. Either way you will have to modify your web.config to gain access to your membership provider in order to achieve the seamless route presented in the link below.
This link,
https://www.iis.net/configreference/system.webserver/security/authentication/windowsauthentication, should help you get in the right direction as to setting up IIS*. Hope this helps.
In my Windows Store App (c#) I have own authorization mechanism:
User past their account name / password and sent it to server.
Server generate unique token and returns it to user.
For all next requests user used this token.
Now I'm in trying to make authorization with using only Windows Account.
MSDN provide UserInformation class and I can get name for the user account or domain name for the user. But I thing this is not enough for my authorization scheme.
Also method GetSessionInitiationProtocolUriAsync looks very interesting, but I don't know how correct use such Uri for authorization.
How I can use Windows Account for authorization in my application?
note: I'm interested in both situation: when user inside domain or not.
Thanks.
There is numerous was to implement this but if you want to keep it simple and own the process you could implement your own authentication method which on a successful authentication you could build a hash value from their password and secret salt which could be returned to the user as a cookie etc. which you use to validate on every request there after.
On regards to authorisation you can implement your own or use a role based provider linked to the local machine group or active directory by using the classes below or just using the plain old RoleProviders.
You could implement your own method of authentication using the method described below or using the Authentication and Authorisation provider for ASP.Net (if your server runs on .net). Basically the Asp.Net Membership and role Providers. However the method detailed below will allow you to access and modify roles and other information about the user too.
In .Net 3.5+ there is a new namespace called System.DirectoryServices.AccountManagement.
Snippet from MSDN
The System.DirectoryServices.AccountManagement namespace provides
uniform access and manipulation of user, computer, and group security
principals across the multiple principal stores: Active Directory
Domain Services (AD DS), Active Directory Lightweight Directory
Services (AD LDS), and Machine SAM (MSAM).
System.DirectoryServices.AccountManagement manages directory objects
independent of the System.DirectoryServices namespace. Managed
directory services applications can take advantage of the
AccountManagement API to simplify management of user, computer and
group principals. Solutions that previously required intricate
knowledge of the store or lengthy code, such as finding all groups to
which a user belongs, are accomplished in a few lines of code with the
AccountManagement API.
You can easily authenticate a user credential on AD using the code below:
bool valid = false;
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
valid = context.ValidateCredentials( username, password );
}
If you want to validate using a local machine account you can change the constructor too:
new PrincipalContext(ContextType.Machine)
You can check the documentation for other options and additionally this will let you get all sort of information from the store like membership etc.
The new namespace was Microsoft attempt to simplify DirectoryServices which I think was successful but if you want even more control you could use the DirectoryServices classes but that would increase the complexity of the solution.
I hope this helps if you require further information or you think it is not quite what you are looking for let me know I will endeavour to improve the answer.
First, I'm afraid you're confusing authentication and authorization.
Authentication - proving a user's identity (like me presenting an ID when going to the bank)
Authorization - deciding whether an identity is allowed to perform some action (like whether the client "Nitz" can drain account #44422).
A Microsoft account can only provide you with authentication - the client will use some scheme to prove to your server that it belongs to bla#microsoft.com, and it's up to you to decide if it is allowed to do stuff in your application (authorization).
With domain accounts, you can use domain group membership to help with your authorization (it's even common in windows server applications), which you usually get "for free" with the user's authentication token.
Assuming I understood you correctly and you're indeed looking for authentication, you have to provide two behaviors - one for using domain authentication and one for Microsoft account authentication. This is because libraries and communication protocols are very different between the two.
Providing authentication
Using this this tutorial from Microsoft Azure's guys, you can set up a sample application / website combination that utilizes Microsoft account authentication.
To use domain authentication (kerberos / NTLM), you can follow this post and simply enable "integrated windows authentication" in your web site/service (I'm assuming it's IIS). If you're new to enteprise authentication, I'll shortly say that when set up properly (no time differences, AD issues etc.), the authentication is seamless. If there are issues, fall back to a simple "hello world" website and test it from Internet Explorer.
For each scenario, you best create a "hello world" method returning the user's authentication information, to make sure you got it right.
Providing authorization
with each authentication method you end up with a unique ID (Microsoft account: UserId. Domain accounts: SID). Your logic should translate this info to a set of permissions - e.g. Maintaining a table that has the ID in one column, and isAdmin in another. Your application should consult this logic when deciding whether to allow or deny an action from a client.
Combining enterprise and public
Since the methods to authenticate public users are different from the ones used for enterprise users, you'll probably end up with different IDs for the same user when connected from different methods (e.g. DOMAIN\bla and bla.blason#outlook.com). If you intend to provide both authentication methods at the same time, you have to account for that (for example, by creating a "user" table that has one column for Microsoft account IDs, and one for Domain SIDs). It usually makes little sense to provide both authentication methods at the same time, but it's your app.
Hope I helped!
Once i had the similar situation, (A client app need to connect to server with few identity credentials. after the custom authentication , a token will be grant for the client with few claims, then each client request will be validated against the given token) , if you are in something like this, consider this link, it helped me to solve the issue.
http://bitoftech.net/2014/06/09/angularjs-token-authentication-using-asp-net-web-api-2-owin-asp-net-identity/
Note: you can implement custom authentication, and authorization by extending claimsAuthenticationManager and Claimsauthorizationmanager respectively