finalist / liferay-oidc-plugin

Plugin for Liferay, enabling OpenID Connect authentication
Apache License 2.0
21 stars 31 forks source link

provide ui_locales OIDC parameter #21

Open gvanderploeg opened 6 years ago

gvanderploeg commented 6 years ago

By @zipwiz in #18:

Is it possible to guess the current "content locale" on the Liferay side and forward it to OIDC OP using URL parameter ui_locales (as described in http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest ) ? If the request Locale is not set appropriately it is not that simple to guess it from the available request data like URI, URL, contextPath, servletPath and pathInfo because Liferay always treats the first path element as servletPath, regardless of its semantics...

gvanderploeg commented 6 years ago

Can't we just supply the result of LocaleUtil.getMostRelevantLocale()?

zipwiz commented 6 years ago

A proposal is made by https://github.com/finalist/liferay-oidc-plugin/pull/20/commits/6e988f48ba7c56c1f78ca24aff778a777519ee99 . The implementation is located in LibFilter and thus should work for both LR62 and DXP. However, if DXP works differently with locale prefixes in content URLs, than it might probably not work for DXP. I cannot verify that actually.

zipwiz commented 6 years ago

LocaleUtil.getMostRelevantLocale() sounds perfect. I did not know about that and will test it. However it must be implemented the same way the logging is implemented.

Commit will follow soon referring to this issue here -- if it works.

zipwiz commented 6 years ago

Generally looks promising:

    private Locale _getMostRelevantLocale() {
        Locale locale = LocaleThreadLocal.getThemeDisplayLocale();

        if (locale == null) {
            locale = _getDefault();
        }

        return locale;
    }
zipwiz commented 6 years ago

Does not work, sorry: On my portal, the default language is de. When I use LocaleUtil.getMostRelevantLocale(), en is used for everything, independent of actually selected portal content language. But I have to admit that this may be caused by non-typical use of locales in the actual content. However the mechanism should at least sometimes result in de.

gvanderploeg commented 6 years ago

Have you taken into account your browser's preferred language? And cookies in your browser? I'd say this should work regardless of whether (web) content has been written in a certain language (Content does not have a locale, but a (or more) languages, right? Only the user does have/select a locale)

zipwiz commented 6 years ago

I have removed all relevant cookies for the tests, and my browser's locale sequence is actually (de-de, de, en-us, en) which should result in preferring de at least.

My OP is actually Keycloak 3.2.1 (should be updated, right).

The portal has only de (default) and en language content. Most content pages have explicitly different URLs for en and for de, but default resources like /portal/login and /portal/logout use the Liferay 6.2 default mechanism. As far as I actually see, this results in /c/portal/login (de) and /en/c/portal/login (en), respectively. The Locale of the HttpRequest however is de_DE always, and the context of the HttpRequest is always empty.

After testing with LocaleUtils.getMostRelevantLocale() I conclude that the themeDisplayLocale is either empty or en always, or the defualtLocale is en at least..

zipwiz commented 6 years ago

My solution "works for me", but if there is any improvement towards a cleaner solution, I appreciate that :-)

zipwiz commented 6 years ago

The implementation update now takes the GUEST_LANGUAGE_ID cookie into account.

The request´s locale is useless as it seems, but this cookie is used by Liferay to store the last selected language ID (locale) in the user´s browser. This works at least for public pages.

Having this it is possible to send this locale to the OP so that it is able to select the same language for the login screen.

To be flexible with requested locale schemes, the full locale information is sent first, followed by shortened locales down to the pure language info. This way the OP should be able to display the best matching locale it has to offer.

The current implementation may be cleaned up a bit, however both the cookie and the URL prefix examination should be part of the final implementation I think.

zipwiz commented 6 years ago

Hint: After having authenticated, the user´s preferred language seems to be primarily controled by the user profile: After an authenticated user has explicitly chosen a display language, this language will automatically be used again after her next login, regardless of the language selected on public pages of the same site before. I am not a Liferay professional, so this is just what I have seen during some tests.