Custom OIDC login page - host on identity server or client application server? - authentication

Most IDAM servers (Identity Server 4, Gluu, Cloud services) provide a way to host a login UI on the actually identity server. This login page can be customized so that it can be branded like your website. This works well for security flows so when you reach an authorization end-point you are redirected to your identityserver/login page.
But can you host the login page on the client application instead?
And if so:
Is this advisable?
Is this more/less secure than hosting the login UI on the Identity Server?
Would this break security flow standards like OIDC / Auth 2.0 authorization code flow?
Would this simply call an API to authenticate against? e.g. one that is hosted on the identity
server. Some appear to support this, but this seems a bit old / insecure compared to existing security flows.
Thanks.

Not really: the point of (federated) Single Sign On (SSO) is that one can use a single credential to login across different domains without divulging that credential to every domain/application.
Users use those credentials in one place against one server only to a trusted party aka. the Identity Provider. The Identity Provider then creates a derived token that is consumed by the 3rd-party application because the latter trusts the former to do so.
In case all applications belong to the same domain as the Identity Provider, the argument above no longer holds, but not using SSO would still mean that you'd have to login to each application separately, one by one.

Related

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.

Do users of a third party app accessing our API's have to log in with us even if they've already authenticated with their their system?

We have a third party company developing a mobile app and they want to call our API's. Our API is protected with Identity Server 4 which uses OpenID Connect and OAuth2. In order to access our API's would their app have to pop open a mobile browser so the user can log into our system? What if users already authenticated with the third party's identity provider? Seems like that would create a negative user experience to authenticate two different times while using the app.
My understanding is we would add their app as a client in Identity Server using the authorization code grant. Would we add their identity provider as an identity provider that our Identity Server can call?
Any help on this would be greatly appreciated. I've researched myself into a hole.
would their app have to pop open a mobile browser so the user can log into our system?
You are pretty much right on your assumptions that their app would have to somehow initiate oidc flow to allow the users of the mobile app to authenticate with the authority of your API (identity provider).
Seems like that would create a negative user experience to authenticate two different times while using the app.
It seems that this is what's holding you back. Firstly, that mobile app's identity provider is separate from your API's authority and it is important to understand that the "user" authenticated with the other identity provider means close to nothing to your API because the token has been issued by a different authority and it's not even a "user" from your user base.
My understanding is we would add their app as a client in Identity Server using the authorization code grant.
Yes, but check also Authorization Code grant with PKCE which adds extra security measures.
Would we add their identity provider as an identity provider that our Identity Server can call?
Yes, you will need to do that, but this is just a start of the things you would need to do to achieve what you are looking for. Because you already have Identity Server 4 in place, I assume your systems already have an established user base, therefore if you just redirect to the external identity provider, once a user authenticates there and the token is issued back - that kinda means nothing because you don't have any kind of mapping from the user of the third party system to the user of your system.
There is pretty much nothing out of the box in Identity Server 4 that will help you with this, but one way to tackle this is to implement some sort of account linking mechanism, where the users would first have to "link" their account in your system with the account in the third party system. With account linked, you would have means to issue claims related to your system.
Identity Server 4 absolutly has out of the box solutions for this. If they didn't, what would be the point calling themselve a OAuth 2.0 framework?
You do not need to initiated a oidc flow like stated. What does that even mean anyway? oidc is connection protocol, not a flow. Flows include hybrid, implicit, clientcredential, etc.
You could obtain an access token for your 3rd party app a number of ways all use the token endpoint built into identity server 4 specifically for creating access tokens The most common is using the ClientCredential flow, where you gain a bearer token by hitting the identity server 4 token endpoint passing the client_credentials grant type with the ClientId of the client they want to access, a shared secret supplied by you, and the api scope they are attempting to access.
Another option is you could create a user for this client on Identity Server 4, then gain an access token using the ResourceOwnerPassword flow by hitting the token endpoint passing the password grant type, clientId, username, and password, again along with the api scope they want to access.
For information on how to do all of the above check out his link. It will help you on your way.
http://docs.identityserver.io/en/latest/endpoints/token.html

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.

Implementing identity server behind web api owin authentication

I have two different client apps written in javascript connecting to two different web api. I am trying to implement identity server 3.
Is it possible to have identity server behind my web api owin
authentication api end point. In other words, is it possible to
route /token endpoint from owin in web api to call /authenticate
endpoint in identity server?
Is it possible to audit log to db in identity server including
failed request along with user's ip and browser agent. Also is it
possible to log user's ip even if i am calling from web api as my
web api is being called by a user using browser?
In my case should i keep two different user base for two different
projects or move all my users to identityserver. If i move all the
user info to identityserver, how am i going to handle all the joins
with other tables in different applications or should i keep a copy
of user with minimum info such as id, email and name?
It makes little sense to first call a web api and deal with authentication during that call.
Your client apps should first redirect the browser to IdentityServer where user would log in and be redirected back to your client app along with either access token (implicit flow) or authorization code (AuthorizationCode flow), depending on the client app having a back-end or not. Then, your client app would make requests to the webapi, passing the access token in the Authorization header.
As for different user bases, one approach might be to implement specific IUserService for each user base and either send a hint about which one to use in the acr_values or tie it to specific clients registered in IdentityService. Again, depending on the requirements.
Is it possible to have identity server behind my web api owin authentication api end point. In other words, is it possible to route /token endpoint from owin in web api to call /authenticate endpoint in identity server?
Yes and no - you cannot reroute those requests, but you can host identityserver in the same application as a web api. In Startup.cs, map a folder to identityserver.
It's not a good idea to do this, first of all, which api of the two will host idsrv? What if that api goes down and takes idsrv with, then the other api does not work anymore.
-> host idsrv separately, make both apis and both javascript apps clients in idsrv, login to idsrv from the javascript apps (=SSO) and use bearer tokens for the api
Is it possible to audit log to db in identity server including failed request along with user's ip and browser agent. Also is it possible to log user's ip even if i am calling from web api as my web api is being called by a user using browser?
Yes, this should be possible, check the logging implementation for idsrv, at the least you should be able to plug in a provider that writes to a database.
In my case should i keep two different user base for two different projects or move all my users to identityserver. If i move all the user info to identityserver, how am i going to handle all the joins with other tables in different applications or should i keep a copy of user with minimum info such as id, email and name?
Idsrv does not need to have all the user info, just an email-address is enough, you can use that as link to the user data in your api databases if you use that as unique identifier.

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