[keycloak-dev] HTML5/JS applications
Bill Burke
bburke at redhat.com
Tue Oct 8 10:16:25 EDT 2013
Its up to the application how it wants to secure itself with the
browser. For JBoss applications, they can just use regular servlet
security. Adding a valve and a keycloak configuration file to their WAR
is all they have to do to secure their application. A session cookie is
set up and the token and role mappings are stored in the session.
Security is all handled in a standard Servlet way.
Our admin console is a little different in that it is one servlet app
managing multiple domains so it uses its own custom HttpOnly cookie.
That way it is not available in Javascript land, but will be sent on
REST invocations back to the server.
IMO, this is all we should support at the moment as there is a ton of
minor features we still need to implement and a lot of refactoring and
repolishing we need to do all over the place. Not to mention all the
testing that still needs to be done.
That being said....
I don't see why there would be a need for a keycloak.js with all the
methhods you suggest. These is not information that should be exposed
to clients. The Access Token should be opaque to client code. How the
application wants to represent a user is up to the application. IMO,
the client should have obtain the access token via a REST call to the
application's server. The response should be text/plain to protect
against XSS attacks. Embedding the access token in Javascript is a
security hole.
On 10/8/2013 9:38 AM, Stian Thorgersen wrote:
> I'm working on a HTML5 SDK + example for Keycloak and would like some feedback on how it should work.
>
> I've made the assumption that the application is a Keycloak resource, it uses fragments for navigation (i.e. no page reloads on navigation) and that the credentials for the application is not a secret.
>
> I'd like to hide as much as of the complexity as possible in keycloak.js and make it nice and simple to use. keycloak.js will provide the following functions:
>
> * init(config, async) - config is the configuration available from keycloak - async is optional (default is false)
> * onAuthenticated(handler) - registers a handler for successful authentication - should be used if async is set to true in init
> * onAuthenticationFailure(handler) - registers a handler if failed to authenticate - should be used if async is set to true in init
>
> * login() - redirects to the keycloak login form
> * register() - redirects to the keycloak registration form
>
> * isAuthenticated() - returns true if user is authenticated
> * getUsername() - returns the username (principal from token)
> * getProfile() - returns the authenticated users profile
> * getApplicationRoles() - returns the application roles
> * getRealmRoles() - returns the realm roles
> * getAccessToken() - returns the encoded access token
> * isError() - returns if there was an authentication error
> * getError() - returns the error query param
>
> If the 'code' query parameter is present keycloak.init will remove it from the URL (using window.history.replaceState) and request an access token from the server.
>
> We could store the access token in HTML5 storage, but that is risky due to XSS hacks (maybe it could be an optional feature to store in session or local storage). An alternative is to just keep it in memory. Storing it in memory means that a page refresh would loose the token so the user would have to click the login again. If cookies are permitted by the realm the user wouldn't have to actually login, the user would just be redirected back to the application.
>
> An optimization would be to add a feature to TokenService that returns an access code if the user is already logged in. This would also be useful for other types of applications to automatically login users that are logged in to the sso realm.
>
> We need to enable CORS support for the TokenService at least. We also need one more feature in the TokenService to retrieve the user profile for the current user (supporting 'Authorization bearer' or keycloak identity cookie), again this is something all applications will need.
>
> Config passed to init should contain one or more redirect uri's and keycloak.js should use the one that closest matches the current page for the redirect_uri param. Further we can support loading a specific fragment after the callback has been processed by keycloak.js. The specific fragment to load could be passed in to keycloak.login and encoded into the state param (for example keycloak.login('#/secretpage')).
>
> For application configuration we need to add one or more valid redirect uris and one or more web origins. As the credentials for a HTML5 application is public it's even more important that we validate that the redirect_uri param matches one of the pre-configured redirect uris. In the past I proposed the idea of allowing a redirect uri to be a pattern, but this is explicitly not recommended by the oauth2 spec, so we should require the redirect_uri value to be an exact match of one of the pre-configured redirects.
>
> We'd should probably also provide keycloak-angular.js that wraps keycloak.js up nicely for Angular apps.
> _______________________________________________
> keycloak-dev mailing list
> keycloak-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/keycloak-dev
>
--
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com
More information about the keycloak-dev
mailing list