Get email address from SAML Response using Single Sign On and ADFS - authentication

I am in the process of setting up a single sign on (SSO) system using ADFS and SAML 2.0. I have to following scenario that I am stuck on:
1) User attempts to access web resource, is not logged in so is directed to ADFS SSO service.
2) User successfully authenticates against ADFS.
3) ADFS passes SAML Response back to web resource.
4) The web resource itself has a user database but the user does not exist here.
5) So, the web resource must create the user account silently. To do this I need the email address.
So, is it possible to configure ADFS to return the email address of the user in a successful SAML response message?

You can configure ADFS to return an Email claim, provided ADFS has some way of getting this (Active Directory or some other attribute store, maybe a database it can access?) and provided your application is set up to decrypt the returned token to read the claims inside.
Assuming this is ADFS 2.0:
Set up your web resource as a Relying Party Trust (sounds like you've done this)
Right-click the RP and choose Edit Claim Rules...
On the Issuance Transform Rules tab, add a new rule for Email address
If you can get the email from Active Directory because your users are authenticating through a domain, then you can choose the "Send LDAP Attributes as Claims" rule template.
Otherwise, you'll have to pick "Send Claims Using a Custom Rule" and set up a custom attribute store (to the database or whatever it is) and go through the motions of writing a claim rule to do it.
Once you have that set up, in your ASP.NET app you'll need to configure it to use ADFS as your token issuer. This is accomplished with the Windows Identity Framework Microsoft.IdentityModel.dll and associated configuration. If you've installed the WIF SDK, you should have some extra options in Visual Studio, namely if you right-click your web project there should be an "Add STS Reference" option. This will run FedUtil which is a wizard that will automatically set up your web.config appropriately. Google around for how to set things up.
Now that your site is using ADFS for claims, you'll need to make a few changes. Under the <microsoft.identityModel> section in your web.config, ensure that you have set it to save the bootstrap token (<service saveBootstrapTokens="true">). In your code, you can now access the email claim whenever you need it by doing:
string email = (User.Identity as IClaimsIdentity).Claims.Where(c => c.ClaimType == ClaimTypes.Email).FirstOrDefault().Value;
If you don't set it to save the bootstrap token, then the Claims collection there will be empty.
There's potentially a lot of other factors that can mess things up along the way, though. Hopefully this will get you on the right track.

Related

How do I build secure CRUD endpoints inside Dittofi?

I am working on building an app for a client inside the Dittofi Design Studio. I am on the basic package, so I cannot see by computer code.
I have built a collection of CRUD endpoints & actions & generated the code. Next & I want to make sure that some of my endpoints are only accessible by someone who correctly authenticates against them. Is there a setting for this inside the studio? How would this work for mobile apps authenticating against the endpoints?
Yes you can inside the studio.
If you look at the wrench in the bottom left, you should be able to create an "Authentication Profiles". You'd have to have users model/db table with username and password fields.
You would then have to have some sort of /sign-up, /login, and /logout endpoints (which would call the login web user and logout web user actions) for your authentication flow.
Finally, on the endpoint you want to lock down, if you look under its settings panel below the name, label and content type settings, you should be able to see how you can attach an authentication profile to the endpoint, i.e lock it down by making sure that only authenticated users can access the endpoint.
For mobile apps authentication agains the endpoints, I would generate a JSON web token (JWT) on the Dittofi end and have a secret key that's shared between the mobile apps and Dittofi to validate the token. That way the mobile app can send any requests to the Dittofi endpoints with that token. On the Dittofi end, I would have some token validation logic to validate that token.
This would require writing some custom Golang code to both generate the JWT and validate it using that secret key. That secret key can be stored in a Global variable (which can be though of as environment variables) accessible using that wrench in the bottom left corner of the Design studio.
Let me know if you'd like me to share the Go code that can generate the token and some example code that can validate your token using a secret key.

Can AD provide my Win desktop application with credentials for my web services?

I have a working c#/dotnet Windows desktop application that does its work by hitting various web services in my web application. When the desktop application starts up, it prompts the user for username / password and then hits my login web service, which returns a session token.
I have a large-org customer with many users. That customer wants to provide authentication / authorization for my combined desktop / web application directly from their domain controller. They want single signon, so my desktop app doesn't prompt their users for usernames and passwords.
How can my desktop application retrieve a usable authentication / authorization token from Windows (maybe from the user's Security Principal object)? How can my web application validate that token so it can trust the desktop application and send it a session token?
(My web application runs in my environment, not in the customer's domain.)
With pure-web-app customers I do this successfully with SAML2 and Active Directory / Federation Services. The SAML2 dance gets my user's browser to POST a request to the customer's AD/FS server, which then POSTs a signed response back to my web app.
But I can't figure out how to do it cleanly from a desktop application. Any wisdom?
You can check this samples in github (by jelledruyts): Modern claims-based identity scenarios for .NET developers
It has samples of authentication and authorization using Azure Active Directory and/or Windows Server Active Directory Federation Services.
I suggest read this article Digital Identity for .NET Applications. It's a little old but is a good overview/review.
Tokens come in many different formats. For today’s .NET applications,
however, three kinds of tokens are most important. They are the
following:
User name/password token—This very simple token contains only two
claims: the name of some subject and that subject’s password.
Kerberos ticket—More complex than a user name/password token, a
ticket includes a subject’s name, the name of the subject’s Windows
domain, and other information. Kerberos tickets that are issued by
Active Directory also include an extension that contains security
identifiers (SIDs) that identify the subject and the groups to which
this subject belongs.
SAML token—The Security Assertion Markup
Language (SAML) is an XML-based language that is owned by the OASIS
multivendor standards group. Unlike the other token types that are
described here, a SAML token doesn’t have a fixed set of claims
defined for it. Instead, this kind of token can contain any claims
that its creator chooses.
As soon as the claims are available, they can be used by Windows, the
application, or both. The most common uses of claims include the
following:
Authenticating the user(...)
Making an authorization decision(...)
Learning about this user(...)
Kind of Authentication:
Domain Based Authentication (eg Kerberos tickets):
A domain-based application accepts only a single token format with a
fixed set of claims. One common example is a Windows application that
accepts only Kerberos tickets. This kind of application is easy to
create, and it works well inside a single Windows domain. The problem
is that this simplistic approach to digital identity is no longer
sufficient for many applications
Claim Based Authentication (eg. SAML tokens):
Unlike a domain-based application, a claims-based application can
potentially accept multiple token formats with varying sets of claims.
The token formats and claim sets that this application accepts are
determined by the application itself.
Identity Technologies
Active Directory (AD) Domain Services (full-featured directory service, token source for Kerbero tickets, etc)
Active Directory Federation Services (ADFS) (support for claims-based applications, token source for SAML tokens
Windows CardSpace
Active Directory Lightweight Directory Services (subset of AD services)
Identity Life-Cycle Manager (ILM) (synchronization between different identity stores)
Windows Authorization Manager (tools for RBAC - role-based access control)
Active Directory Rights-Management Services (RMS)
Because AD Domain Services implements Kerberos, the default token in a
Windows environment is a Kerberos ticket. To use this default, an
ASP.NET application specifies Windows Integrated Authentication, while
a WCF application uses an appropriate binding, such as NetTcpBinding.
In either case, the following figure illustrates how a Windows
application with clients in the same domain might use a Kerberos
ticket and AD Domain Services
First versions of AD FS only support SAML with web clients.
ADFS 1.0, supports only browser clients—a restriction that’s scheduled
to change in the technology’s next release.
Hope it helps.
I should preface this with the fact that I've never done this, so I can't give you exact code, but I can point you in the right direction.
You should be able to do this with ADFS and Windows Integrated Authorization (WIA). In a "pure web app", the browser sends the credentials of the currently-logged-on user during the authorization step. In your case, your desktop app needs to do everything that the browser would normally do. Either way, the setup on the web service side should be exactly the same.
In C# with HttpClient, this is the important part:
var httpClient = new HttpClient(new HttpClientHandler()
{
UseDefaultCredentials = true
});
Then, whenever your httpClient sends a request that is challenged with a 401 response, it will automatically resend the request with the user's Windows credentials. This is exactly what a web browser would do. So use that when you get the token.
You may have to send a user agent string in the request, since ADFS seems to limit WIA to certain agents.
Once you have a token, then use the token in your requests to the web service.
The key is that you're replicating what a browser would do. So if you have trouble setting up what the HTTP requests should look like, then access a GET request in your API from a browser and use the browser's dev tools to inspect exactly what the traffic looks like, and use that information to replicate the same request in your code.

SAML between existing account and service provider

Background:
I have a basic user database with username(email) and password. The users are able to sign in to a website of mine with these credentials. From the website they get a link to different services they have access to, but with different username/passwords. So they click the link "Open My Service X" and they have to login with their service unique login credentials. I do have the users service login-username. So I can map local-user <=> service-user.
I want SSO between service X which has support for SAML and my website.
Question/Problem:
I want the users to login with their user/password in my database, then single sign on towards service X where service X has support for SAML. I don't want a user to be able to sign up for a new user account to my website using the SAML support in service X. The user must already have an account in my database.
So my question might be rather vague, but I'm having a hard time to grasp how this can be achieved?
I was thinking of letting my webapp become a SAML identity provider, so that the SSO request are transferred back to my webapp and verified for their service-user. Would that be correct approach?
You're on the right track with your SAML IdP. There are basically three parts involved. Your email database (the identities), your existing application front end and the remote services which support SAML. Usually it's SAML2 these days.
To get single sign-on (SSO) across your portfolio of apps (your own app and the remote services) you could install an IdP like the Shibboleth IdP and convert your app to use it instead of using email/password to login. That would take a fair amount of work as you'd have to convert your app into a SAML SP, just like the remote services.
An easier way might be to only use the IdP for SAML to the remote services and get the IdP to recognise that your users are already logged in with their email/password. Cookie? So the IdP should never display a login page as it would recognise your app's cookie and match that with a user in the database. It then releases SAML attributes to the remote service based on that user's information. That also covers your use case of not allowing account creation via SAML from a remote service.
That would mean you might end up with the following URLs:
https://yourapp.com/
https://yourapp.com/idp/
Your users login with the first URL as normal and the remote services use the second URL. That way your app cookie will be visible to the /idp endpoint but you'd need to write code to match that with a user in the database.

Office 365 rest api Authorization

I am currently using EWS in my application to access Exchange data. I want to add functionality for Office365 using rest api.
With EWS, Authorization was quite simple, just add Authorization tag in header with username and password base64 encoded, I bealive it is called basic Authorization.
But with office 365 the process gets 2 extra steps
On the image above you see that 2 steps are in between my application and office365.
Every office account that will use my application, must do
some configuration steps at Microsoft azure. to get secret key, client it and tenant id.
I would like to avoid that, ideally user needs only to enter his credentials thus I can access all of his data in office 365 programmatically.
Every office account that will use my application, must do some configuration steps at Microsoft azure. to get secret key, client it and tenant id.
If I understand your question correctly, you want to avoid all the steps to configure the client_id, secret key for your app user?
If your app is a browser-based web app, the "Application" block on your diagram actually consists of web server and user/browser. In this case, only the web server needs to pull the configurations from the Azure, client_id, secrect, etc... This being said, the user/web browser only needs to enter his credential, and with implicit consent, you app will have access the the user's data. Such workflow can be described below,
In this case, you app user/browser does not need to pull the configurations from Azure. Only the web server does.
If your app is a native app, when you make a request to the auth endpoint, you app needs to include the client_id and redirect URI in the request. This is shown on the first step below.
In this case, your app user can use the same client_id and redirect URI, you don't need to "force" them to create their own's, so that they only need to input their username and password.
You can find more info on Azure AD authentication from https://azure.microsoft.com/en-us/documentation/articles/active-directory-authentication-scenarios/

Claims aware security. Do I get it right?

I'm trying to investigate possibility of using claims aware security in the system I'm developing. The more I read about all this stuff the more confused i get.
So i decided to describe what I know already and I would ask that You correct my statements. I got lost with all those protocols and technologies used.
Below is a simple diagram of my system. There are two services - a REST service implemented using WCF and an ASP MVC web application.
I know I need to get an STS which will be a trusted identity issuer for both of my services. I'll be using roles to differentiate certain levels of access.
The STS functionality might be accomplished by using ADFS (or is there anything more needed in addition to it) or WSO2 Identity Server.
By saying STS I mean a service which will get credentials from a client wanting to authenticate and will return a set of claims (which will beside other information contain the role assigned to the user). This set of claims will be in the form of a token.
On the diagram I marked different client types with different colors. No I'll try to describe what protocols/formats i think will be used. I am pretty confused on what is a format and what is a protocol. But let me try:
Red scenario: rich WCF client authenticates agains REST service
Request to STS will be sent using WS-trust (is there any other possibility in ADFS or WSO2?). The credentials might be in one of several forms such as X.509 certificate, password digest, kerberos, windows authentication, SAML token (this is used in federation scenarios, right?), and few other.
The answer to the client will be in a form of SWT token sent over OAuth protocol since this is the way we do it when trying to authenticate against REST services.
Does ADFS support SWT and OAuth? I couldn't find the information.
The client then send the token received from STS to the REST service. Once again this is SWT token on OAuth.
I guess as for the client code all can be easily implemented using Windows Identity Framework.
Green scenario: rich android client authenticates against REST service
All protocols/formats are the same as in previous scenario. Is there any framework which can let me easily implement this?
Blue scenario: user of web browser authenticates against ASP MVC web application
User goes to the web app's main page. The webapp detects that he isn't authenticated yet so redirects him to the sign on page on STS (the sign on page is on STS, right?).
and 3. STS authenticates the user and sends HTTP response containing SAML token and redirection to webapp. So here is HTTP used, not WS-Trusts.
Another question. In this web browser scenario there will be a cookie written on a client's machine. So whenever client will try to authenticate once again, he'll just send the cookie to sts to obtain the token. There will be no need to send the credentials. STS will issue a token basing on the cookie without any real authentication logic involved. Is that statement correct?
ADFS / WIF out the box only supports SAML tokens - no OAuth support.
ADFS / WCF uses WS-Trust.
The sign-on page is part of ADFS.
The answer is "Yes" to your last question but (at some point) it will expire and the user will have to authenticate again.
Update:
Have a look at Claims Based Identity & Access Control Guide