What would be the actual solution to build a server with Grails and Spring Security that meets the following requirements :
Access to the server would be restfull, so only by third party clients (mobile,...)
The authentication would use the oauth2 facebook services and the client would use a facebook SDK to provide a token to the server
The authentication would be on per request basis so the token would be passed on the request as GET parameter (not POST as the Rest API uses it)
No need to access Facebook user's information, only authentication
I tried Spring Security Facebook but the Json filter only returns user details so no per request or per session authentication.
I noticed Spring Security Oauth2 Provider but to me it's a provider and not a consumer that could plug into another provider like Facebook so no clue on how to use it.
Spring Social doesn't seem to meet my requirements.
As a result of this search for information, I intend to write a plugin to create a Restfull server connected to facebook.
Thanks in advance
You could implement a security filter on the top of all your requests, and then if the request contains an auth header for the API you respond with as a restful API, otherwise you redirect your users to the login page, handled by the oauth authentication service, where you let the users login with the oath method (facebook, mozilla persona or whatever you like)
Related
Consider that we have:
An SPA or a statically generated JAMStack website.
A REST API.
The website is being served with nignx that also reverse proxies to our API.
--
It is required that a user should be able to register/authenticate with an identity provider (say, Google) through the OpenID Connect protocol. For the sake of simplicity, let us assume that the user has already registered with our API.
Talking about authentication using OIDC, from what I have read on the subject, the steps you take are the following:
Register the application with the IdP and receive a client id and a secret.
When the user initiates a login (with Google) request on the API ('/api/loginWithGoogle') the API sets a state variable on the request session (to prevent CSRF) and redirects the user-agent to the IdP's login page.
At this page, the user enters their credentials and if they are correct, the IdP redirects the user to the callback URL on the API callback (/api/callback).
The request received on the callback has the state parameter (which we should verify with the one we set on the session previously) and a code parameter. We exchange the code for the identity token with the authorization server/IdP (we also receive access/refresh tokens from the auth server, which we discard for now because we do not want to access any APIs on the behalf of the user).
The identity token is parsed to verify user identity against our database (maybe an email).
Assume that the identity is verified.
-- The next part is what's giving me trouble --
The documentation that I have read advises that from here we redirect the user to a URL (e.g. the profile page)and start a login session between the user agent and the API. This is fine for this specific architecture (with both the SPA/static-site being hosted on the same domain).
But how does it scale?
Say I want to move from a session based flow to a JWT based flow (for authenticating to my API).
What if a mobile application comes into the picture? How can it leverage a similar SSO functionality from my API?
NOTE: I have read a little on the PKCE mechanism for SPAs (I assume it works for JAMStack as well) and native mobile apps, but from what I gather, it is an authorization mechanism that assumes that there is no back-end in place. I can not reconcile PKCE in an authentication context when an API is involved.
Usually this is done via the following components. By separating these concerns you can ensure that flows work well for all of your apps and APIs.
BACKEND FOR FRONTEND
This is a utility API to keep tokens for the SPA out of the browser and to supply the client secret to the token service.
WEB HOST
This serves unsecured static content for the SPA. It is possible to use the BFF to do this, though a separated component allows you to serve content via a content delivery network, which some companies prefer.
TOKEN SERVICE
This does the issuing of tokens for your apps and APIs. You could use Google initially, though a more complete solution is to use your own Authorization Server (AS). This is because you will not be able to control the contents of Google access tokens when authorizating in your own APIs.
SPA CLIENT
This interacts with the Backend for Frontend during OAuth and API calls. Cookies are sent from the browser and the backend forwards tokens to APIs.
MOBILE CLIENT
This interacts with the token service and uses tokens to call APIs directly, without using a Backend for Frontend.
BUSINESS APIs
These only ever receive JWT access tokens and do not deal with any cookie concerns. APIs can be hosted in any domain.
SCALING
In order for cookies to work properly, a separate instance of the Backend for Frontend must be deployed for each SPA, where each instance runs on the same parent domain as the SPA's web origin.
UPDATE - AS REQUESTED
The backend for frontend can be either a traditional web backend or an API. In the latter case CORS is used.
See this code example for an API driven approach. Any Authorization Server can be used as the token service. Following the tutorial may help you to see how the components fit together. SPA security is a difficult topic though.
We have a Web App using REST API. The REST API is based on Loopback and uses it's built-in token-based authentication. For the Web App we use forms based authentication over HTTPS, so the user has to enter his username and password which we then use to get access token from the REST API via POST /users/login endpoint.
One of our customers asked us to support single sign-on (SSO) authentication through SAML 2.0 and AD FS.
We configured our Web App as a service provider (Relying Party in AD FS) and managed to support SSO for it. The changeling part is the authentication between Web App and the REST API. The idea right now is to configure both Web App and the REST API as the same Relying Party and add new POST /users/saml-login endpoint to the REST API, so the Web App can send a SAML response to that end point and get an access token based on the claims specified in the SAML response. Everything else should work as it used to work before. Here is the flow I imagine:
Web App generates SAML request and redirects a user to the IdP login page
After a successful login the user is redirected back to the Web App with the SAML Response
Web App acts as a proxy and redirects the SAML Response to the REST API endpoint (POST /users/saml-login) where it is validated
If the SAML response is valid the API returns an access token based on the claims
Web App uses access token for further communication with the REST API same as before
Here is the question: Is it OK to implement SAML-based SSO this way? Do you see any issues or security considerations with this approach? Are there any alternatives?
I have read a lot of articles on the web and questions here on StackOverflow about how to use SAML & REST API together:
Propagate SAML Assertion Response/Security Context to downstream Services/Apps
REST API authentication with SAML
SAML and back-end REST service authentication
Attacking SSO: Common SAML Vulnerabilities and Ways to Find Them
None of them really helped me to confirm or reject the idea described above.
That sounds like a reasonable approach. I can't think of any security issues.
You're simply re-posting the SAML response internally within your application for processing. As long as you then perform the various security checks on the SAML response and assertion within your REST API, there shouldn't be any issues.
I have a web site written in Angular that uses a REST api in order to provide functionality.
I would like to know the proper workflow for authentication to the website.
Let's go back to 1999 - I write a website and all the logic is in the web code. There is no REST API. If someone wants to log in to the website they enter their email and password and I store a cookie on their machine and they now have a 'logged-in' session on my website. By having this cookie they are authorized to do certain things such as write a comment.
All good.
Fast-forward to my new website. This website is written in Angular and all content is provided via a REST API. Some of the REST calls just display data like a bunch of comments. Any anonymous user can make these calls just by browsing the page. However, there the user can log in to the website using their email and password. Again, I store a cookie on the user's machine and they are logged in to the website. Now, because they are logged in to the website they can post comments. These posts are done via a REST API call. However, Google and the Interweb have told me that my REST API should be stateless and i should be using oauth2 for this request.
My question is, what is the workflow for this very common auth pattern?
I thought maybe something like:
User logs in with username and password
One request is sent to my web auth server and a session cookie is created
A second request is sent to my api auth server which issues a valid token for further requests
The two systems are quite separate and do not depend on each other.
If i was to add social login to the mix then (2) above would just be authentication to the required social auth server and (3) would be unchanged.
Yes, your REST API should be stateless.
This is a typical workflow for authentication for a REST API.
User logs in with username and password.
A JSON web token is issued upon login from the backend and sent to the browser.
The JWT(JSON web token) can be stored in a cookie in the Web Storage(local/Session Storage) on the browser.
Subsequent requests to the REST API will have the token embedded in the header or query string for authorization. With that form of authorization, your REST API understands who is making the request and what kind of resource to return based on the level of authorization
A practical example of this can be found in this blog post. Angular 2 was used for the sample app implementation.
I hope this helps!
I am creating an 'API as a service' by developing a separate REST API server and a web-app server which simply serves up a website that consumes the REST API. The web-app acts as a client of the API. The web-app is a simple dashboard that allows a user to login and see their API usage and view their API secret and keys so that they can access the API securely.
I am planning on using AWS-like shared secret to enable clients of the API to access protected resources.
But one thing im confused about is when the user logs in to the dashboard website, should this be handled by the REST API, or by the web-app server.
If it is to be handled by a REST API endpoint, how does the API server maintain session state between requests. How does the API know if the user is logged in or not? Is it ok to store session state on the API server, even though it is supposed to be stateless. How do other rest-like API's like twitter do this?
ReSTful security is handled server-side; basically:
the server returns a 401 status code when a client ask for a resource without been authenticated
every client call have to provide authentication through a WWW-Authenticate header
this header can be store client-side in a cookie after a successful login
You will find great help on the matter in the book: ReSTful WebServices Cookbook. Look for explaination on basic / digest authentication.
Here is a good introduction with a live working sample.
I am in the process of building a RESTful web service using ASP.NET Web API, and I am considering using OAuth 1.0 as an authentication mechanism to secure the service. Our API would also be maintaining the credentials store and would therefore be the OAuth provider. Client applications using our API would be used by end users who would have to authenticate using a username and password, so I assume the client app is considered to be an OAuth consumer. The client application would make an API call to retrieve an unauthorized request token, then send along the user's credentials with the token to get an access token.
Ultimately, I could see other 3rd party applications wanting to access our application through my API, and they would use OAuth with the redirection with our application being the credentials provider.
Is this a viable way to use OAuth? Will something like DotNetOpenAuth support this scenario?
We have decided to implement OAuth 2.0, which supports various workflows, one of which includes a Resource Owner Credentials flow that allows the client to pass user credentials to the authorization server in exchange for an access token. This will serve our purposes.