I have Spring REST backend and Angular frontend.
Authentication is performed using a POST request to "/login" URL with username and password inside request JSON body (I use form based authentication).
REST backend replies with OK code. Everything is fine and I can perform other requests from frontend that requires authentication.
But frontend need to know what is the role of authenticated user so that it can display a proper view/rote for it. And where can we get this role on a frontend? The only response we got from authentication was OK and that is fine for REST.
We can get user information by performing GET request to "/users/[user_id]". But we don't have user id, just user name.
So the question is - what is a correct way for REST to get role (or other user information) from frontend having just user name?
As a workaround I can create new request on a backend that takes user name instead of id, or I can add user id to authentication response. But I'm not really sure that is a correct way from REST perspective.
You can not override HTTP Methods.So,if you are planning to write GET call with diffrent query parameters with the same path,then it is not allowed.You need to write two GET paths.
e.g.
GET /users/userid/{id}
GET /users/username/{name}
And in the second call,you can add desired logic for getting role in the second one.
There are two way's of doing it.
1) After successful authentication from the server, do one more $http call to the server with username from which you can fetch details from a server logic that fetches and store that result in the $rootScope.This info will be available through out the app.
2) When you are authenticating the user, if the user is valid then fetch his details and store those in an object.
Now in your server logic while returning response you can do like below
response.setHeaders("User",userDetilsObj);
NOTE: response is a HttpServletResponse object.
After the request is completed as you said we will get a status OK response that is 200. To access the user details at JS side follow below code
if(response.status == '200/OK'){
$rootScope.user = response.getHeaders().User;//In this object all the user details set at server side are available now..
}
Hope this gives you some light on how to achieve your desired results.
Get the user information from server at the the time when you authenticates the user.Pass the user details on successful user authentication.
After discussing the issue with #JBNizet in comments I decided to change REST endpoint from "/users/:user_id" to "/users/:user_name".
Related
I have my authorisation url - https://www.reddit.com/api/v1/authorize?client_id=xuJKekGTr1-V8Q&response_type=code&state=dfDfsd4gdf&redirect_uri=http://localhost:8080/redditimageuploader/callback&duration=permanent&scope=submit
But I don't really know what to do from here? I've found a few guides online but it's just a lot of jargon I don't really understand. When I click on the "allow" button, it takes me to the url that I defined as my redirect_uri, and appended to the end of the string is the state that I set, as well as code= and then a string - so I assume I need to do something with those, but I don't know what.
I was wondering if there is a super simple "explain like I'm 5" step-by-step guide on what to do from here?
It's a standard OAuth flow. From the doc :
When the user clicks the "Sign on with Reddit" button on your website, you must redirect the user to the authorisation URL at Reddit - the one in your question, starting with https://www.reddit.com/api/v1/authorize and enriched with the request params you specified. Reddit will then ask the user to sign in, and whether or not he wants to authorise your app access to the requested scope. See https://github.com/reddit-archive/reddit/wiki/OAuth2#allowing-the-user-to-authorize-your-application
If the user agrees, then Reddit will redirect the user to the redirect URI you specified as request param in the authorisation URL (in your case, http://localhost:8080/redditimageuploader/callback). Reddit will add a state request param: you need to ensure that this is the same as the one in your request.
Retrieve the access token with a POST request to https://www.reddit.com/api/v1/access_token, including the following data in your data: grant_type=authorization_code&code=CODE&redirect_uri=URI. Replace CODE with the value you received and URI with your same redirect URI as in the first step.
The response to this third step should return you an access token: store this for future requests on behalf of the user. See https://github.com/reddit-archive/reddit/wiki/OAuth2#retrieving-the-access-token
Extra steps are available and documented for error handling and access token operations (invalidation / renewal).
So, once you've correctly implemented the first step, all you need to do is create an endpoint (the one called when your redirect URI is redirected to) which will :
check the state request param
Retrieve the access token (third step) and store it
Let me know if this is clear enough.
I've reset the user password and set it as temporary in keycloak.
Is there some REST API to change temporary password to regular when user will log in? It is important not to use keycloak's user interface. I've heard about experimental API but I can't find any of its documentation. Thanks for help
I've heard about experimental API but i can't find any its
documentation.
I think you are referring to this Keycloak Admin API
Assuming that:
I've reset user password and set it to new temporary in keycloak.
is done via endpoint already, then what you can do is to get the ID from that user, which you can get by using the endpoint:
curl -X GET <KEYCLOAK_HOST>/auth/admin/realms/<REALM_NAME>/users/?username=<USER_NAME>
From the JSON response, extract the user ID. Then you call the following endpoint:
PUT <KEYCLOAK_HOST>/auth/admin/realms/<REALM_NAME>/users/<USER_ID>/reset-password
with the request payload:
{"type":"password","value":"<THE_PASSWORD_THAT_YOU_WANT_TO_SET>","temporary":false}
If what you want is to first set the password as temporary, and then when the user logs in for the first time, force the user to set to a new non-temporary password, then you need to call the following endpoint:
PUT <KEYCLOAK_HOST>/auth/admin/realms/<REALM_NAME>/users/<USER_ID>
with the request payload:
{"requiredActions":["UPDATE_PASSWORD"]}
When I tried to find the solution for the challenge I'm facing at the moment, I was provided with many approaches which didn't seem to quite fit my problem.
Here's what I'm facing:
I have a back-end integrated with Spring Security and the front-end is all built using AngularJS. We have 2 sets of users - legacy and new. The new feature requires when a legacy user signs in, redirect the user to the password reset page and have the legacy user reset his password to meet the new password standards.
This is the approach I have taken to deal with this:
Create a filter that intercepts every user request, checks if the user is a legacy user or not. If he is, redirect the user to the password reset page.
The challenge I'm facing at the moment is to let AngularJS know from the filter that it should redirect the user to the password reset page.
When I call sendRedirect on the HttpServletResponse, it's not redirecting to the destination page. I know I'm missing something here. Can someone help me with the approach here?
Thanks.
Like Dvorog said in his comment, you have to send a redirect response to your client, such as 302. You should specify the redirect location in the header.
Then, in client side, you can manage the header in the error callback
$http.get('/someUrl').success(function(data, status, headers, config) {
})
.error(function(data, status, headers, config) {
// check status and get headers informations(ie location) here to make redirection
});
You will find more detail in the documentation
Since you asked for a better solution (in the comments) this is what I would do:
Create a guard that will be assigned on all of the routes that require the user to be authenticated in order to access them. This guard should check the role of the authenticated user, and if the user is a legacy one, then redirect the user to the "change password" site. This way, you won't have to implement special logic on the backend and send redirect requests.
On android client, I create Credentials, then choose account using AccountPicker and set the account name. On GAE, I have User parameter in every endpoint method. (I described it here)
Android Client ID, Web client ID and audiences are configured correctly.
On endpoint, the user is not null and has correct email set. But when I call user.getUserId() I get null. Is this user authenticated or not?... It really makes me nervous not to know that...
What you describe is odd, and I don't know why you get null when you call getUserId(), but never-the-less I would say, Yes, you are authenticated.
If you want to be sure, then you could try using that authentication from a web client - I read that once you have authenticated an Android user you are automatically given minimal account authentication for web too. So create a minimal servlet that includes the following code:
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
Load the page while signed in with the same account you authenticated from Android and see whether it acts like it already knows you, or whether it prompts the user as it would for a different, un-authenticated user.
This is a bug on google's side.
There seems to be a clunky workaround: save User to datastore and read it back.
Hi am regarding facebook php server side login..
http://developers.facebook.com/docs/authentication/server-side/
in that
$code = $_REQUEST["code"];
what is the meaning of this..., what is this code ?
Once the user has authorized your app, you should make a server side
request to exchange the code returned above for a user access token.
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID
&redirect_uri=YOUR_REDIRECT_URI
&client_secret=YOUR_APP_SECRET
&code=CODE_GENERATED_BY_FACEBOOK
Note the "CODE_GENERATED_BY_FACEBOOK" comment.
$_REQUEST['code'] is most likely a token that guards against CSRF. Facebook will create this and give it to your application via $_REQUEST['code'] (could be a POST, GET or whatever).
If you're not sure what $_REQUEST is, you should read the PHP manual entry for it.
$code is like authorization token that you exchange for an access token that you will use later to make calls to facebook api. The part you're looking at handles redirect from facebook after user logged in to facebook and authorized your application to access their information. at this point facebook redirects user back to your site and passes code as a get parameter and that line grabs that code from $_REQUEST, which in this context is the same as $_GET['code']