I'm relatively new to Restlet, so currently I am experimenting with Restlet 2.1, and I want to add user authentication
I am currently using Apache ReverseProxy, and planning to use it as SSL-proxy, so I'll probably encrypt/decrypt on Apache, Restlet will get plain text
I found sayings about using the Restlet ChallengeAuthentication, but can not find it on 2.1 API doc, and since Restlet just updated their site, most Urls are just broken
so it'd be really nice if someone can give me some guide on how to build it or give me a functional link to some examples eg:
how do I check for authentication,
how do I detect cookie,
how do I set a secure cookie,
how do I read from that encrypted cookie
also another design question, would I be better off using a function that tries to decrypt the cooke for auth, than actually storing the cookie data in a DB like Redis?
Thanks in advance!
i did authentication using 2.1.2 restlet on GAE.
following code may help you how to provide authentication in restlet
ChallengeAuthenticator guard = new ChallengeAuthenticator(getContext().createChildContext(), ChallengeScheme.HTTP_BASIC,"Your application.");
MapVerifier verifier = new MapVerifier();
verifier.getLocalSecrets().put(userName, password.toCharArray());
guard.setVerifier(verifier);
guard.setNext(this);
guard.setNext(anyclass.class);
router.attach("/v1", guard);
and this link http://restlet.org/learn/tutorial/2.1/ for more information about restlet.
Related
For the first time, we are developing a new project that needs to support the browser (a website) and a mobile app built on react-native.
We have plenty of experience developing for the web, but little to no experience in the mobile app world.
We are now defining our API and trying to make it work for both platforms - This will be a basic JSON API, running on Flask. The API will have some public endpoints, and some protected ones as well (that require auth). We want a cross platform auth solution.
Typically, for the web, we have always relied on cookie based sessions (encrypted) that frameworks like Flask provide. We have been successfully using these in various scenarios: loading HTML templates directly from the web framework, or even when the frontend application runs on React (same domain + HttpOnly + secure cookies).
The introduction of react-native could potentially bring some new challenges, and some of our developers worry about not being able to continue to use our typical session based cookies - They are advocating to using something like JWT for authorization, for both the browser and app (and yes, I know that we can't compare sessions to token based auth).
I'm not a big fan of token based authorization (for a number of reasons, could entertain that conversation if anyone wants to waste some time...), and I can't seem to understand why we shouldn't stick to our normal encrypted "Cookie" value.
Here is how I imagine this could work, based on using the Flask cookie session:
A user hits /api/login with some credentials
The endpoint will validate the user and return back whatever response + the Set-Cookie header with a value of session=<encrypted string>
Any further requests from the browser/app would send back the cookie value again.
Essentially, nothing would change for typical browser implementations, this is how browsers work by default.
The react-native documentation mentions a few issues with cookie based authentication: https://reactnative.dev/docs/network#known-issues-with-fetch-and-cookie-based-authentication
From what I can gather (my knowledge is extremely limited on this subject), react-native might not always respect the Set-Cookie header. Which is OK - we would just have to make sure to send back the expected header with any further requests.
This, in theory, would fulfil our requirements.
I'm looking for feedback on my "solution", am I missing anything? Did I get HTTP completely wrong?
React Native actually provides networking similar to that of websites developed with basic JavaScript, which also supports cookie based authentication, however there are some serious caveats as mentioned in here
The following options are currently not working with fetch
redirect:manual
credentials:omit
Having same name headers on Android will result in only the latest one being present. A temporary solution can be found here:
https://github.com/facebook/react-native/issues/18837#issuecomment-398779994.
Cookie based authentication is currently unstable. You can view some of the issues raised here:
https://github.com/facebook/react-native/issues/23185
As a minimum on iOS, when redirected through a 302, if a Set-Cookie header is present, the cookie is not set properly. Since the redirect
cannot be handled manually this might cause a scenario where infinite
requests occur if the redirect is the result of an expired session.
Therefore, I would advise against using it as it is unstable and might give you a hard time dealing with it
I also suggest looking into frameworks that handle authentication for you, such as auth0
Hope you find this helpful :)
I am ashamed to admit that I burned four full days trying to get Spring Security 3.1 to play nicely with Google Sign-in in a standard JSF web application. Both are awesome frameworks in their own right but they seemed incompatible. I finally got it to work in some fashion but strongly suspect that I have missed some fundamental concept and am not doing it the best way.
I am writing an app that our helpdesk uses to track system testing during maintenance activities when our systems are down and cannot host the app, so it is hosted externally. Our Active Directory and IdP are down during this activity so I cannot use our normal authentication systems. Google Sign-in is a perfect solution for this.
Google Sign-in works great in the browser using Google Javascript libraries and some simple code. The browser communicates with Google to determine if the user is already signed in, and if not, opens a separate window where the user can submit credentials and authenticate. Then a small bit of Javascript can send a concise, ephemeral id_token returned from Google to the server which the server can use to verify the authentication independently with Google. That part was easy. The beauty is that if the user is already signed into Gmail or some other Google app, authentication has already happened and Google does not challenge the user again.
Spring Security works great on the server side to protect specified resources and authenticate a user with a username and password. However, in this case, we never see the username or password - the credentials are protected by secure communication between the browser and Google. All we know is whether or not the user is authenticated. We can get the Google username, but Spring Security expects credentials that it can use to authenticate, to a database, in-memory user base, or any other system. It is not, to my knowledge, compatible with another system that simply provides yea-or-nay authentication in the browser.
I found many good examples online that use Spring Boot with EnableOAuth2Sso (e.g. here) but surprisingly few that use Spring Security in a standard app server which does not support EnableOAuth2Sso, and those few did not show any solution I could discern.
Here is how I've done it. I followed Google's simple directions here to provide authentication in the browser. I added this code to the onSignIn() method to send the id_token to the server.
var xhr = new XMLHttpRequest(); // Trigger an authentication for Spring security
xhr.open("POST", "/<my app context>/j_spring_security_check", true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
var params = "profileID=" + profile.getId() + "&fullname=" + profile.getName() + "&email=" + profile.getEmail() + "&id_token=" + googleUser.getAuthResponse().id_token
+ "&j_username=" + profile.getEmail() + "&j_password=" + id_token;
xhr.send(params);
window.location.replace("/<my app context>/index.xhtml");
Unfortunately the Spring Authentication object, when passed to the AuthenticationProvider that I provided, did not contain anything but the j_username and j_password parameters as Authentication.getPrincipal() and Authentication.getCredentials(), but this is all I really needed. This is a bit of an abuse of those parameters since I have set them to email and id_token, not username and password.
I wanted to pass the user's full name and email, which Google provides in Javascript as googleUser.getName() and googleUser.getEmail(), to the backend as well. Since Spring Security does not accommodate anything but the username/password, and I was using Primefaces/JSF, I used Primefaces RemoteCommand to call a method on the backing bean with this information. This also feels a little clumsy.
In addition, I had to use window.location.replace() (in code above) because Spring Security did not redirect to my index.xhtml page as expected when I set this in the context with:
<security:form-login login-page='/login.xhtml' authentication-failure-url="/login.xhtml?error=true" default-target-url="/index.html" always-use-default-target="true" />
I have no idea why this does not work.
However, the app does now behave as I want in that it authenticates the user and the authenticated user can access the resources specified in Spring Security, and I wanted to share this in case anyone is doing a similar thing. Can anyone suggest a cleaner/better way? Thanks in advance.
We are starting project based on the great jhipster work.
While we would like to keep the option to be session based (with a login page), we also have the need for enalble clients pass user info in the header of each request,
(e.g. Authenticate: username:password) to have it session less like without login, as regular users do.
Do we have this implemented OOTB? If not, what is the best approach for having that?
Thanks ahead for any comment & answer.
JHipster supports both "session-based" (with a login page, and the Spring Security token is stored in the HTTP Session), and OAuth2 (which is stateless, and the token are stored in the database).
The OAuth2 mechanism also uses a login page, but I guess you could make it work without it if needed -> isn't this the best solution for you?
We also have another stateless mecanism in the pipe, see https://github.com/jhipster/generator-jhipster/issues/892
I am developing a stateless RESTFul API based on JavaEE 6 and it is important not to store anything in the session.
I am using socialauth java based social auth provider.
I would like to know if there is a way to rebuid SocialAuthManager after a successful authentication without having to retrieve it from the session as documentation explains:
session.setAttribute("authManager", manager);
And then:
SocialAuthManager manager = (SocialAuthManager)session.getAttribute("authManager");
I want to avoid this.
I would like to do something like this:
SocialAuthManager manager = new SocialAuthManager(PARAMS TO REBUILD PREVIOUS AUTH WORKFLOW);
Thanks in advance.
I'm developing social auth with 4.10 version of this lib.
After user get redirection url and is authorized, then I do connection to social service by this way:
AccessGrant accessGrant = manager.createAccessGrant(network.getId(), params);
Optional<Profile> profile = Optional.ofNullable(manager.connect(accessGrant).getUserProfile());
manager.disconnectProvider(network.getId());
Where params - params from request of success callback API. After getting user profile I disconnect manager for reusing it. Also be aware of concurrency when using this method.
I just wonder if it's possible to access a .htaccess protected directory through a server-side API? Browsers can handle the authentication well but how to do that through API?
Many thanks.
The answer is yes, as long as your web api provides a mechanism for you to enter the credentials to satisfy the HTTP Basic Authentication check.
For example if you are using apache httpclient in java you can use a block like the following to enter the credentials.
CredentialsProvider oCredProvider = new BasicCredentialsProvider();
AuthScope oAuthScope = new AuthScope(m_sServer, AuthScope.ANY_PORT, AuthScope.ANY_REALM);
UsernamePasswordCredentials oCreds = new UsernamePasswordCredentials(sUsername, sPassword);
oCredProvider.setCredentials(oAuthScope, oCreds);
httpclient.getCredentialsProvider().setCredentials(oAuthScope, oCreds);
Without knowing which web api you are using, it is difficult to answer.
I would suggest you do a simple search, for example if you are trying to perform HTTP BAsic Authentication within the context of AJAX and javascript, just google
"AJAX javascript HTTP Basic Authentication", and you will probably find a more relevant example for your specific situation.