I'm trying to develop a custom login form using Worklight customSecurityTest, based on SingleStepAuthAdapter application sample.
Basically, I've noticed that the login function used in the SingleStepAuthAdapater is always called after that user try to access to a secured function (after that, on login action, secured data are sent to the user), but if i try to call the submitAuthentication function directly, before any attempt to access to a secured function (i have inverted the "login page" with the "get secured data" page), i got the following error/lo on firebug:
The two POST calls are the same function raised two times by Worklight on login action (submitAuthentication function inside the SingleStepAuthAdapter called by singleStepAuthRealmChallengeHandler.submitAdapterAuthentication(invocationData, {})) and the error is related to the fact that authentication is requested twice: probably when the authentication request is performed, this function is issued twice after that the submitSuccess() function is called inside the handleChallenge (in fact, the issue doesn't occurs when i delete the submitSuccess invokation, but WL framework is not notified and, for example the isUserAuthenticated function return false, until the access to a secured resource is performed).
How can fix this behavior? What are the best practices to develop a simple login-form using worklight that allow authentication before any access to a proteced resource? I have found some workarounds (such as perform a fake data request before perform the submitAuthentication, but i hope that you can suggest me a better solution).
I've consulted the infocenter and the getting started modules, but probably due to my fault I'm not able to found any useful information
A common practice is to have an initial blank page or view for your app.
In WLCommonInit, either access a protected resource (that is what getsecretdata is all about), or call WL.Client.login(). Another option (suggested by #tk27) is to secure the app in the application descriptor and set connect on login to true. This will trigger authentication when the app starts.
Your challenge handler should display a login prompt dialog, and when the authentication successfully completes, transition to the first real page of your app.
This way, authentication is still done in response to a challenge from the WL Server (as it must be) but you don't see anything but a blank page to a login prompt until the login is successful.
Related
I have implemented a login form manually in Twig and I am using the default authentication provided by Symfony 3.4 (based on username and password). Users are stored in a database, therefore I have an Entity which extends AdvancedUserInterface. I am using neither FOSUserBundle nor form builder. Just a simple form. It actually works.
The problem is that I want to integrate Google reCAPTCHA in the login process. I know how to check if the captcha is valid and implemented a custom AuthenticationListener (let's call it MyAuthenticationListener).
I know that Symfony uses UsernamePasswordFormAuthenticationListener as its default listener. The problem is that I could not find a way to change the used listener to that I have implemented.
It seems that in Symfony2 it was as easy as adding the following line in the config.yml:
parameters:
security.authentication.listener.form.class:
MyBundle\EventListener\MyAuthenticationListener
However, I cannot find a way for Symfony3. Any suggestions?
I also tried to find a specific bundle for Symfony3, but I actually could not find anything that is correctly integrated with Symfony Security, allowing me to use the recaptcha in a login form.
Thank you
Your question may be answered here:
https://stackoverflow.com/a/50800993/7408561
The solution is based on a custom-listener triggered by SecurityEvents::INTERACTIVE_LOGIN. That event is fired after verification of credentials but before redirecting to default_target_path defined in security.yml. At this position you can verify the request parameter g-recaptcha-response by calling the google recaptcha api with the corresponding secret.
If the verification fails you can throw an exception and you will be redirected to the login page.
I am encountering a strange situation with MobileFirst 7.1 where users are occasionally unable to authenticate/login. The only indication that something is awry is a message in the console.log
[AUDIT ] CWWKS1100A: Authentication did not succeed for user ID . An invalid user ID or password was specified.
My custom login module uses com.worklight.core.auth.ext.LdapLoginModule (so to clarify I have a login module which authenticates using LDAP). Like I say everything seems to work most of the time but occasionally users end up in a situation where they are unable to authenticate. I suspect that it is probably related to the session in some way, but that is only a guess based on my investigation.
I have added some logging to my 'secret' adapter which prints the session state to the console log, and obviously this appears in the logs just before the failed authentication message above, but it is empty ie. the session contains nothing.The user is obviously trying to access a secure adapter at this point, and because they are not authenticated they end up at the login page (form based authentication I should say also).
Anyway, I noticed that although there appears to be no session data, the jsessionid is there and has not changed i.e. it does not change even if I refresh the browser. This may not be an issue in itself of course, but interestingly if I remove this entry and refresh my browser I am able to login successfully.
I am pretty sure that my handler code calls the relevant success/failure methods in the correct places but of course there is nothing to stop the user refreshing their browser, which causes them to be re-directed to the login page (the app has been developed using AngularJS so is effectively a single-page navigation model).
The only reproducible test I have been able to come up with is when I login to the MobileFirst console and then try to login to our MF 'desktopbrowser' app. I have read that this situation causes a session-related conflict, but as I say the occasional issue I am seeing is not caused by this (though it may be related).
So the problem seems to have been more related to the flow of logic in our application after successfully logging in, than any inherent issue with the MF Platform.
For example when a user refreshes the browser they are effectively still logged in, but because the app (based on logic we have developed) takes the user to the login page on refresh, the user is effectively re-logging in to the same session. If this failed every time it would of course have been easier to pinpoint but it does not. The solution was to force logout on refresh (when the app initialises), thus cleaning up any session data. In future iterations it may of course be better to re-establish the application based on the authenticated session after refresh, but at present that was a step too far.
Another example of this was post login if the subsequent adapter calls failed (e.g. we authenticate and then retrieve profile data from a database), then we were also not logging the successfully authenticated user out.
I have a test application that accesses two Adapters:
A JavaScript adapter protected by a SecurityTest referencing a realm
A Java adapter with a method protected by an OAuth scope corresponding to that same realm.
If I follow this sequence everything works as expected:
Attempt to access the JS adapter, I get challenged, authenticate, get data.
WL.Client.isUserAuthenticated() and WL.Client.getUserInfo() now behave as expected
Logout using WL.Client.logout()
WL.Client.isUserAuthenticated() now shows I'm not authenticated
A second attempt to access the JS adapter causes another Challenge, as expeccted.
However, with the Java Adapter logout() seems not to behave as expected.
Starting with no session, attempt to access the Java adapter, the challenge happens as expected and I get to my data
I can now access the JS adapter without further challenge and the WL.Client.getUserInfo() calls gives the expected results.
WL.Client.logout() appears to work, in that WL.Client.isUserAuthenticated() now shows I'm not authenticated
But a call to the Java adapter still works without further challenge
A call to the JS adapter does result in a challenge
If I'm running in my browser simulator environment I can destroy the OAuth session by using this command:
localStorage.removeItem("com.worklight.oauth.idtoken")
The question is:
Should the WL.Client.logout() method have destroyed the OAuth session? If not what API should I be using?
With OAuth, logout 'works' differently. See the following user documentation topic (search for "logout"): http://www-01.ibm.com/support/knowledgecenter/SSHS8R_7.0.0/com.ibm.worklight.dev.doc/dev/c_oauth_security_model.html?lang=en
The login/logout API:
The WLClient login/logout API enables a user to
log in to and log out of a specific realm, by updating the server side
security state. However, in the new OAuth-based security model,
security credentials are also kept in the access token on the client
side. The result is that using this API will cause an inconsistent
state, for example, in which the client is logged out of a realm on
the server side but still holds a valid token for that realm on the
client side. To solve this inconsistency, it is recommended to
re-obtain the access token, by using the
obtainAuthorizationHeaderForScope method, after successful login or
logout.
For example, consider a client that passed the security checks for
Realm1 and Realm2, and later calls logout(Realm2). In this case, the
access token on the client would still contain the security
credentials for both Realm1 and Realm2, and the client could use this
token to access protected resources. To refresh the token, that is, to
obtain a token for Realm1 only, the client calls
obtainAuthorizationHeaderForScope without the logged out realm Realm2.
In JavaScript the equivalent call is:
WLAuthorizationManager.obtainAuthorizationHeader("SomeRealm")
I've been creating API and consumer by following Simple API Development with Laravel from Aaron Kuzemchak. I got the problem after I success to auth via API from my consumer; I do not know how to check it, if the consummer already success logged in or not at the other pages...
For example, at the first; I show the login page, click the submit button to check the credentials via API. The login attempt is working, success to logged in and redirect to dashboard. But, if I haven't logged in and accessed the dashboard from URL, i got the dashboard :O
The API server and the consumer have separated machine and the database only exists at the API server.
Am I doing this right (with the flow for the API and Consumer) ?
At the consumer, how can I get to know if the user already logged in or not (after success attempt the credential)? (somehow? someidea?)
Thank you before... :)
This question is very confusing, probably because I haven't watched that screencast yet, but shouldn't Auth::check() be what you are looking for? It will return true or false depending on if the user is logged in.
Just to make sure:
You have a back end API built from the tutorial posted here: http://kuzemchak.net/blog/entry/laracon-slides-and-video
You're using HTTP Basic authentication as described in the above tutorial
You're building a (consumer) front end web interface for users on a separate server
Your consumer interface uses forms based authentication (a login form)
The backend API uses HTTP basic authentication (and the consumer sends an API key for the user with each request). As such, the backend won't keep track of a user being logged in. That means your consumer interface will need to do this.
You could use the Laravel Auth class for this normally, but your front end would normally have access to the database and the bundled authentication drivers could just check a username/password.
I'd say your options are:
Store details of the user in a session using the Session class (feels a bit nasty but simple)
Write an authentication driver and then use the Auth class (advanced but cleaner: http://www.karlvalentin.de/1903/write-your-own-auth-driver-for-laravel-4.html)
Just talk straight to the database using the existing Auth class and Eloquent
I'm using CAS (Central Authentication Service) from Jasig in a client JSF app running on tomcat 6 server. I would like to limit the access to the app just for the users specified in my database rather than all the users which can be authenticated using that CAS service. When the user attempts to log in, I need to check if his username is also in my database's table user and if it is - allow the access to the app. Otherwise, I would like to redirect user to a page "You don't have permission to access this part of the application". So I need authorization as well. Is there a good way to authorize the users in jsf 2.0? Thanks in advance for any help/suggestions.
Sounds like you need to design a custom Authentication Handler class in CAS. In theory, your handler would extend this [1], perform all the necessary checks and database look ups and will then be able to return a signal that indicates whether or not the user could authN.
You should then reference your custom handler in the deploerConfigContext.xml file.
For displaying the message, you could either throw an exception with the proper messages code, such that the message would appear above the login form, or you could alter the spring webflow and generate a new view-state which the user would be redirected to, if they fail to get access. The first approach is much easier to implement.
Another approach would be to take advantage of the isUserInRole() method [2] using the persondir api.
[1] http://developer.jasig.org/projects/cas/cas-server-core/cas-server/cas-server-core/apidocs/org/jasig/cas/authentication/handler/support/AbstractUsernamePasswordAuthenticationHandler.html
[2] https://wiki.jasig.org/pages/viewpage.action?pageId=47874068