Request ADFS security token from the backend of single sign-on enabled ASP.NET website - wcf

I have a single sign-on enabled ASP.NET web site which uses ADFS for authentication. On logon users are redirected to the ADFS sign-in page, then my application gets FedAuth cookies back and doesn't store any user passwords.
What I need to do is to contact a third-party service (namely, SharePoint), which is configured to use the same ADFS server for authentication, from the web site backend. I've learned that I should be able to do so by getting another security token using some WIF (WCF in fact) calls described for example here http://blogs.technet.com/b/speschka/archive/2010/06/04/using-the-client-object-model-with-a-claims-based-auth-site-in-sharepoint-2010.aspx.
My problem is I don't know how to provide authentication for such calls using the information implicitly available in single sign-on cookies. I do not have explicit credentials nor Windows authentication.
The code I'm trying to use follows:
WSTrust13ContractClient trustClient = new WSTrust13ContractClient(binding, address);
trustClient.ClientCredentials.Windows.AllowNtlm = true;
trustClient.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
trustClient.ClientCredentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
System.ServiceModel.Channels.Message response =
trustClient.EndIssue(trustClient.BeginIssue(
System.ServiceModel.Channels.Message.CreateMessage(
MessageVersion.Default, WSTrust13Constants.Actions.Issue,
new RequestBodyWriter(trustSerializer, rst)), null, null));
It fails with "The HTTP request was forbidden with client authentication scheme 'Negotiate'" message.

Related

Securing an API with SAML SSO / OAuth2.0

Alright, so I'm having a hard time understanding a proper flow here for my setup.
Goal
I want to have a proper SSO flow for my SPA app that can authenticate users into an API.
Context
I have a React application that is intended to use an Okta porta that offers both SAML (preferred) and OIDC for SSO flows. I've wrapped my static sources in a web server that serves them, and that server has a middleware that checks for cookies, and if one doesn't exist, I redirect to the IDP (Okta) for login. This all works fine for now.
Currently, my API sits on that same server, which I intend on moving to a separate server to scale independently of the website. My API must also allow other machine clients (services) to call into it, so I implemented a service account flow that uses client ID and secret as the authentication measure.
In general, my intended flow looks like this:
User navigates to my website (unauthorized) -> Web Server -> Redirect to IDP -> Assertion Callback flow -> Generate JWT session cookie -> Web Application makes API call -> API Server auth middleware validates cookie / bearer token.
The problem.
The details of how the JWT access token is generated is where I'm stuck. Currently, my webserver receives the SAML assertion and generates a JWT, which is not the same JWT claims logic as the service accounts (bleh). I'm thinking of implementing an Auth service instead to centralize the token generation flows.
For the Auth Service, I've looked into OAuth2.0 and it seems like just the right approach for what I need. With that said, I can't find much information on patterns to follow for SAML assertion -> OAuth2.0. I saw an IETF draft for saml2-bearer grant-type, but it seems dead in the water. I'm also unsure about the general consensus on custom implemented OAuth2.0 grant types.
What does a proper flow look like? I have a couple of scenarios in mind:
SAML Service Provider within the same service as the Auth
Service. On lack of SSO session, my application redirects to my Auth service, which then redirects to my IDP. The IDP calls my SP (the auth server) with the assertion, the auth service generates a token, then my auth service redirects back to the webserver with a cookie placed in the response headers.
SAML SP as the webserver Since the webserver is the only system that needs to use the SSO, I could just keep the SAML flow within that process. Once my webserver receives the SAML assertion callback, my server makes a call to an endpoint service with the assertion claims, and then my auth service returns the access token in a JSON response.
Something else, like OAuth2.0 authorization code flow with PKCE for the web application. Or OIDC instead of SAML for SSO.
OIDC sounds like the right choice for you as APIs are involved. OAuth is designed to secure APIs' compared to SAML which is built for enterprise SSO.
You can integrate your SPA with Okta using OIDC. Okta provides SDK's for varies platforms to make it easier for you to do so. You can find SDKs' here:
https://developer.okta.com/code/angular/okta_angular_auth_js/
Once you get an ID token and Access token from Okta after OIDC flow, you can use the access token to access external API's. Your API resource server or the API gateway can validate the access token. Again Okta provides SDK's to verify access tokens: https://developer.okta.com/code/dotnet/jwt-validation/

Generating an OAuth2 token from user logged in via Windows Credentials (Kerberos)

We are running an application via Remote Desktop Services. The application authenticates to our web api middleware running in under WCF using Negotiate and Windows Auth.
We now have a scenario where the middleware needs to make calls to another service and pass a bearer token so that it can run as the user who made the initial request. It would also enable us to not have to use Negotiate on every request, which is fairly expensive.
We're looking for a way that we can make a OAUTH grant_type = client_credentials, but using the credentials of the user which is authenticated via Negotiate to our middleware. I haven't seen any examples of how that would be done. All of the examples I see pass the users credentials via client_id and client_secret, or in the HTTP Basic Auth header, but no examples of grant_type = client_credentials, where the credentials are via Negotiate.
Getting a token as the user without the user interactively logging in via OAuth is generally not supported since the password is unknown.
Aim for option 1 below:
Use client credentials, then pass the user id in addition via a different parameter, such as a path segment - simplest option is to get the downstream service to support this
Login via OAuth and federate to an Identity Provider that uses windows auth - this is likely to be a very big migration job - though it is the preferred way to use OAuth with Windows auth

Outsourcing Grafana's authentication process to my application server

Background:
I have an application server that has an endpoint of /api/token. What this API does is it performs authentication against the supplied username and password using the standard basic authentication protocol.
When the process is successful, it returns an access token and HTTP code of 200 (OK). When fails, HTTP code 401 (unauthorised) is returned.
Question: Is there any way I can make Grafana's login page to pass on the login credential to my application server for authentication?
No, unless you want to hack source code.
But you can use Grafana in auth proxy mode, where authentication will be made by some "auth" proxy. For example, auth will be made by reverse proxy (e.g. Apache+mod_authnz_external) which will be in front of Grafana. All auth logic will be there and Grafana will just receive the request with request header X-WEBAUTH-USER value when user authentication is successful.
Another option is to start OIDC Identity Provider (for example Keycloak), which will use your app auth endpoint for authentication. Grafana has native OIDC/OAuth support, so it will be just configured against your OIDC Identity Provider.

How to Login API to Identity Provider

Our system architecture has this setup. We have an API that is used by a WebApp Client. We allow users to authenticate using an Identity Provider (IDP) that returns SAML.
The problem is how would you setup authentication? Which of the flow below would be more suitable?
WebApp Client controls the flow
When a user needing authentication visits WebApp Client, redirect user to IDP.
User authenticates with IDP
IDP redirect user back to webapp client with SAML response
WebApp client passes the SAML to the API.
The API will decrypt and read the attributes.
API then gives access token to the WebApp client it can use for subsequent requests.
API controls the flow
When a user needing authentication visits WebApp Client, redirect user to a special endpoint of API.
API redirects user to IDP
User authenticates with IDP
IDP redirect user back to API with SAML response
API decrypt and read the attributes
API redirects user to the WebApp client passing an access token to the WebApp client it can use for subsequent requests.
I'm currently asking myself the same questions with google idp. I thought about passing the returning code from idp to my API and then authenticating the user from my API.
If you have some return on your experience let me know :)

How to get a JWT?

When reading about securing an app with JWTs, it is often said that the client initially gets a token from the server and then sends this token along with every request to the API.
This approach works great, once you have a token. As far as I can see, the default way of transferring a token is using an HTTP header, namely Authentication with Bearer as the prefix of the token as value.
But - is there also a default way of how to get the token initially? In samples you often see that this is just a simple request to and HTTP endpoint, that then returns JSON. But I was wondering whether there is something more of a standard workflow that e.g. describes what should be the name of this endpoint, as in OAuth2?
Any hints?
JWT is a token format which is used in security protocols like OAuth2 and OpenID Connect.
How to get the token from the authorization server depends on the grant flow you are using.
There are 4 grant flows defined in OAuth 2.0 that are intended for different clients and uses.
Authorization code grant
This grant is intended for web applications. The user's browser is redirected (HTTP 302) to the authorization server. The authorization server takes care of authenticating the user (via username/password, smartcard, 2-factor auth whatever).
The authorization server then redirect the browser back to a preregistered endpoint in the web application with a code. The web application then uses it's own credentials (client id and client secret) and the authorization code to request an access token from the authorization server.
The authorization server returns an access token and a refresh token to the web application. Note that the browser (untrusted) never sees the access token. Only the web application (trusted) has access to the access token and refresh token.
This grant is difficult to use from other clients than web applications as it's based on HTTP redirection.
Implicit grant
This grant is used for untrusted clients like JavaScript applications or 3rd party mobile clients (the ones you download from the app-store).
It also redirects a browser (or browser control) to the authorization server, but instead of returning a code to the browser after successful authentication, it returns an access token directly. Because the client is not trusted, the grant does not return a refresh token. The access token needs to be stored somewhere and is vulnerable to XSS attacks.
Even though you do not get a refresh token, some implementations do provide a way to get a new access token by communicating to the authorization server in a hidden IFRAME and using cookies to authenticate with the authorization server itself.
Resource Owner Password Credentials grant
This grant is for trusted clients, for example a desktop application or a first party mobile app with secure storage capabilities. The client application asks the user (the resource owner) for their username/password and then sends this to the authorization server to acquire an access token and refresh token.
Once the client has the access token, it can discard the password as it can use the refresh tokens to get new access tokens. This makes it more secure than basic authentication.
This grant does not depend on browser redirects and can be easily used from any application that can execute HTTP requests.
Client Credentials grant
This grant is meant to authenticate the client (application) instead of the user of the client.
In this case, the client submits its client id and secret directly to the authorization server to acquire an access and refresh token.
So basically the first two grants depend on browser-like capabilities (HTTP redirects, HTML login pages), where the other two grants only need an HTTP stack to communicate with the authorization server.
Every OAuth2 server has its own endpoints. The client can discover the name of relevant endpoints using discovery protocols like http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata.