I have a main web-site that uses passive federation (ADFS 2.0)
This website has javascript that calls out to an MVC Web API site using jsonp.
I am trying to get this WebAPI to participate in Single Sign On (same machine, different port). However the passive redirects break the jsonp. (The STS returns its own script which the browser renders and i never get to redirect to the real url for my response script)
Is passive federation compatible with a jsonp webapi?
If not, how do I use Active Federation without username/password credentials?
i.e. The user will be authenticated via the main website before calling the webapi, so how do I leverage the fact they are already logged in, in the webapi?
The passive federation protocol won't work in this scenario as you are experiencing.
You have two options:
If your web api is being exclusively used by your website you can share the cookie that is generated by WIF when the user authenticates. To do that, if you are using different websites you should configure the <cookieHandler> section on WIF configuration to use the same domain and path and use a FQDN (instead of machine names), so that the browser identify both the website and the API as the same domain.
The second option is to configure the Web API to extract and validate SAML tokens (being generated during authentication). What you would have to do here is to save the token that was used for authentication (turn on the saveBootstrapToken on the <service> element of the WIF configuration), get it by using the claimsIdentity.GetBootrapToken() extension method and attach the token on the JavaScript call as an HTTP header like "Authorization: bearer ...the-token....". On the server side you have to get that and validate the token (programatically). Note that you might hit a quota in IIS because of the header length if the token is too big.
Related
I'm setting up OAuth2 in my app using the Authorization Grant flow. I am also using create-react-app, such that I'm developing on localhost:3000, which proxies to my app server backend on localhost:8080.
Everything mostly works, except for the fact that I cannot get the CSRF token working.
I realized it was because I was having the OAuth2 Redirect URL set to the backend, and as a result it was not sending the private encrypted csrf_state cookie along, because the request was originating from google instead of my app.
I don't think this will be a problem in production, because there won't be a proxy server. Instead, both the backend and frontend will be served from the same mydomain.com
So, should I just not have this work in development? Or should I have the OAuth2 redirect URL set to my frontend (localhost:3000), which then automatically redirects to the backend (localhost:8080), such that it can send the private encrypted CSRF token along?
Or is there a way to have the cookie originate from google, without having the multiple redirects? Or should I just not bother with CSRF, since SameSite has such large support amongst browsers now?
The OAuth2.0 Authorization Code grant includes CSRF protection using the state parameter. Use this instead of relying on cookies.
state
RECOMMENDED. An opaque value used by the client to maintain
state between the request and callback. The authorization
server includes this value when redirecting the user-agent back
to the client. The parameter SHOULD be used for preventing
cross-site request forgery as described in Section 10.12.
Source: https://www.rfc-editor.org/rfc/rfc6749#section-4.1
Ahmad is right - and here is some more context on standard usage for react apps and APIs:
If you're using React then you have an SPA that should redirect directly to Google during logins
So your redirect url should be localhost:3000
Your SPA should be entirely cookieless - and much simpler - which is one of the benefits of SPAs - also you can turn off CSRF checks in the API
Your SPA will then send an access token to your API and the API will need to validate the token rather than cookies
My tutorial and code sample may help you understand the moving parts:
https://authguidance.com/2017/09/24/basicspa-overview/
There is a sensitive page in my website, so I want to authenticate visitors before they opening a link like: www.examples.com/builder.
I know if I use cookie based authentication everything will be simple, as the browser will send the credential message in cookies automatically. But in my situation, I have to use token based authentication. Browser don't send token if there is no pre-load script.
So my question is how to achieve token based authentication when someone open a sensitive page directly.
As far as I can understand,
you're looking for a way to avoid double roundtrips to send authentication headers to your web-service.
If I am correct, then this would only be possible via service worker which is a not widely supported feature. https://developers.google.com/web/fundamentals/primers/service-workers/
If, depending on your requirements, you can't go for service workers, then, the only left option is to use cookies.
I normally have a secondary authentication flow which uses cookies allowing a web service to authenticate a user on its first get request (the one made by the browser).
There are also some spa framework which implement routing resolvers but this will require a double roundtrip (1. load javascript, 2. send the token).
I have some web application in my server which use ADFS for authentication let's say this is their URLs :
http://myServer/ManyWebApps/WebApp1
http://myServer/ManyWebApps/WebApp2
http://myServer/ManyWebApps/WebApp3
When the user access any URL under "ManyWebApps" hierarchy he can freely use the server function they provide through javascript and through the browser without further authentication:
http://myServer/ManyWebApps/Server/Function
Now, I need to detach one of my web apps to a new URL like so :
http://myServer/WebApp1
Will the user still be able to free access server functions under the "ManyWebApps" hierarchy :
access http://myServer/ManyWebApps/Server/Function from http://myServer/WebApp1
Note : both web applications are still on the same server and work with the same ADFS server, when the user enters http://myServer/WebApp1 he is authenticated, but will he be able to access functions on diffirent web apps on the server without further authentication?
P.S : I need to access a function without further authentication because making an AJAX request to the function while unauthenticated will cause the AJAX request to be redirected to the ADFS which it can't handle
CONFIRMED : The authentication is saved in http://myServer so no further authentication need to take place if both apps are on the same domain
When sending a request to the server, all of the user's cookies are sent including the authentication token. If the user's doesn't have the token in his cookies, the server will direct him to the ADFS. But since both web applications are under the same server, they share the same cookies which means once the user entered any address in MyServer hierarchy, he can free enter any in that hierarchy without further authentication
I have a site where user must login to access. I have some web services calls for getting datas stored in another server.
But to access to the server user must login again via a login popup. To avoid this I want to pass the user/password but not in the URL.
Is it possible to do this in Javascript adding user/password in header or something similar ?
Authorization of this type is typically done via request headers. For regular users interacting with a web page, the login credentials may be remembered using the cookies in the request. For API access, however, the standard way to do this is with bearer tokens included in the POST body of the request. See also: OAuth2.
For authenticating API access (but not the user), such authentication is typically done via API keys.
Important footnote: whenever doing any authentication, you should ensure that your requests are encrypted (and, when setting cookies, that cookies used for authentication are properly marked "secure").
Take a look at the W3C specifications for the XMLHttpRequest Object. The five-parameter version of the 'open' method allow you to specify the username and password.
EDITED
Keep in mind: this will make your password publicly accessible.
I am building a Windows 8 application where I would capture and store credentials using the Password Vault. I would like to then use them for all HTTPS requests to a specific domain. This is easy enough for single requests but I would like it to be seamless. I cannot use the enterprise authentication capability in the manifest because these machines are not joined to a domain. I have looked at the Web Authentication broker but this seems to be directed towards using OAuth.
My question is, is there a way to either:
1) Enable Enterprise Authentication and white-list the domain to use
these credentials for (even though these machines are not domain joined)?
2) Use Web Authentication to somehow use
my credentials (that I capture during initial launch) for all HTTPS
requests without OAuth?
3) If none of the above work, what is the
best way to use credentials that are in the Password Vault for all
HTTP requests to a specific domain, rather than pragmatically
submitting them with each request? (want this to be seamless so I
can write HTML without calling on this JavaScript function each
time. Thanks!
I don't think this is possible in Windows 8. You need to submit credentials with each request using
WinJS.xhr() or XMLHttpRequest.open(), or update your service to support OAuth or OpenID.