Keycloak java change temporary password - java

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"]}

Related

Get access token using Spring Security with a specific use-case

Is this use-case supported for Spring Security 5, or something else, where we don't have to reinvent the wheel? Thoughts on how to (re)implement this better?
Details are as follows. 3rd party vendor supplied endpoints. We pull info from upstream source then forward to the downstream vendor. Only 2 APIs are required:
Request Access Token
Save Info
Both are actually being called via a gateway. We've been given specifics:
(A)
The token request requires Basic Auth (standard header - usual base64 encoded). Gateway User and Gateway Password are provided.
Credentials for request token are provided to us:
Grant Type = password
Consumer Id
Consumer Secret
Account User
Account Password
It responds with an access token and few other details we don't really care about and of zero value to our use-case.
There is no expires_in info in the response. But I've tested it multiple times to know it does expire. Not sure how long right now, I could do more tests to determine that.
(B)
The save request requires a different custom header for the same Gateway User / Password, then a Bearer Authorization header in the call to the Save Info API.
Right now, all implementations for above are using RestTemplate. Working fine already. But a token is requested for each save which is costly. Before writing any caching, or some other logic to wait XY minutes before another token request is made, I would appreciate any other options which may already be possibly handled via Spring-specific libraries or further advise on how to handle this scenario.
Apologies if this is not the right place to ask this, or it has already been asked before. Been searching for a similar use-case but can't seem to find one.
Thanks.
Try any one of the option
You can use OAuth2ClientContext which stores your access token.
final OAuth2RestTemplate restTemplate=new OAuth2RestTemplate(resourceDetails, clientContext);
You can create session & store your token & user details inside it.
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(user, null,null);
SecurityContextHolder.getContext().setAuthentication(authToken);
from option 1 Or option 2 you can then fetch existing token for each request at your Filter e.g. PRE_AUTH_FILTER
Then check if token expired - if yes request new token Or call refresh token
Check Oauth2 expires_in in below :-
https://www.rfc-editor.org/rfc/rfc6749?

Oauth2 in server-side access/refresh token

We are trying to implement Oauth2 on our app, in our App we are login using Sign In with Google, and this returns a lot of stuff like : UID, ACCESS_TOKEN, REFRESH_TOKEN, etc.. we are thinking to send from APP to server-side the UID and store it to DB linked with user like if it was its password.
From server side we want to on each call for instance : get_products, we are thinking to use an access_token but we don't know if it's the UID from user itself or we have to create another access_token with its refres_token with expiration time. So we have one UID from user and another access_token and refresh_token from oauth.
I'm not sure about the value you refer by UID. May be it's something that I haven't come across before.
But if it stands for USER IDENTIFIER, then you should not use it to identify the end user and maintain a session. UID could be a public identifier so anyone who knows will be able to communicate to your server. Also, think about user login through multiple devices. Your server won't be able to identify the correct session.
User access_token to initiate a session. In your server, use user-information endpoint to obtain validity details and end user information. Alternatively you may choose OpenID Connect.

How to get user information after REST authentication on client side?

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".

Android, AccountManager and OAuth

I'm sure this is basic and I'm missing something. I've read through other answers on SO, I've googled, I've read resources and I just can't wrap my head around what I need to do.
I'm trying to figure out how to write an app that connects to Twitch's API, specifically how to authenticate with Twitch's api. Their documentation is here: https://github.com/justintv/Twitch-API/blob/master/authentication.md
I've created an app and stored my keys.
Now comes the part where I want my user to click a button which launches the authentication on their website. From what I can tell I do this by using an AccountManager. Except... I can't figure out what I'm supposed to do.
Here's the excerpt I've found online:
AccountManager am = AccountManager.get(this);
Bundle options = new Bundle();
am.getAuthToken(
myAccount_, // Account retrieved using getAccountsByType()
"Manage your tasks", // Auth scope
options, // Authenticator-specific options
this, // Your activity
new OnTokenAcquired(), // Callback called when a token is successfully acquired
new Handler(new OnError())); // Callback called if an error occurs
According to twitch's documentation I want to send the user to:
https://api.twitch.tv/kraken/oauth2/authorize
?response_type=code
&client_id=[your client ID]
&redirect_uri=[your registered redirect URI]
&scope=[space separated list of scopes]
&state=[your provided unique token]
And I simply have no idea how these two things need to be combined.
Firstly, I recommend to read the OAuth2 RFC. This should cover everything you need to know.
The AccountManager code snippet won't help you much unless there already is an app that provides authentication for Twitch. If that's not the case you either need to use an existing OAuth2 library or implement your own.
You could write your own AccountAuthenticator but that's a different challenge (and you still need some kind of OAuth2 client).
Doing it yourself is not that hard, see below.
Steps to implement it yourself
Twitch recommends to use the "Implicit Grant Flow" for mobile apps. That's what I'm going to describe below.
1. Get a client ID
Register your app as outlined in Developer Setup to get a client ID
As redirect URI you can use something like https://localhost:12398/, the actual port doesn't really matter.
2. Build the authentication URL
In your client app you need to construct the authentication URL like so:
https://api.twitch.tv/kraken/oauth2/authorize?
response_type=token&
client_id=[your client ID]&
redirect_uri=[your registered redirect URI]&
scope=[space separated list of scopes]
Apparently [your client ID] should be replaced by the client ID you've received from Twitch, same goes for [your registered redirect URI] (that's the URL above, i.e. https://localhost:12398/). [space separated list of scopes] is the list of scopes (i.e. features your want to access), see Scopes. Make sure you URL-encode the parameter values properly.
Assuming your client ID is 123456 and the scopes you need are user_read and channel_read your URL would look like this:
https://api.twitch.tv/kraken/oauth2/authorize?
response_type=token&
client_id=123456&
redirect_uri=https%3A%2F%2Flocalhost%3A12398%2F&
scope=user_read%20channel_read
Note that you should also pass a state parameter, just use a randomly generated value. You can also append the (non-standard) force_verify parameter to make sure the user actually needs to log in each time (instead of continuing a previous session), but I think you can achieve the same by clearing the cookie store (given that you open the URL in a webview in the context of your app) before you open the login page.
With a random state the URL would look like this:
https://api.twitch.tv/kraken/oauth2/authorize?
response_type=token&
client_id=123456&
redirect_uri=https%3A%2F%2Flocalhost%3A12398%2F&
scope=user_read%20channel_read&
state=82hdknaizuVBfd9847guHUIhndzhuehnb
Again, make sure the state value is properly URL encoded.
3. Open the authentication URL
Ideally you just open the URL in a WebView inside of your app. In that case you need to intercept all request to load a new URL using WebViewClient.shouldOverrideUrlLoading
Once the client is redirected to your redirect URL you can close the webview and continue with step 4.
Theoretically it's possible to utilize the default browser to do the authentication, but I would have security concerns since an external app could learn about your client ID and the access token.
4. Extract the access token
The actual URL you get redirected to in step #3 will have the form:
https://[your registered redirect URI]/#access_token=[an access token]&scope=[authorized scopes]
or to pick up the example
https://localhost:12398/#access_token=xxx&scope=user_read%20channel_read
Where xxx is the actual access token.
If you passed a state it will be present like so:
https://localhost:12398/#access_token=xxx&scope=user_read%20channel_read&state=82hdknaizuVBfd9847guHUIhndzhuehnb
All you have to do now is to parse the (URL encoded) access token, scope and state. Compare the scopes and state to the ones that you actually sent. If they match you can start using the access_token to authenticate.
Note According to the OAuth2 RFC, the response URL MUST also contain a token_type and it SHOULD contain an expires_in duration in seconds.
Once you received the access token you can use it to authenticate as described here.
Access tokens issued by the Implicit Grant Flow usually expire after a certain time and the user needs to authenticate again. The Twitch documentation doesn't mention any expiration time, so it's possible that the token is valid forever. So make sure your app doesn't store it or store it in a secure way (like using Android's key store provider to generate and store a key to encrypt the access token).
If the implicitly issued access token expires you could consider using the "Authorization Code Flow". That's quite similar but it contains an additional step to receive the access token and a "refresh token" that can be used to renew the access token. I leave it up to you to figure out how that works.

google api androidpublisher error code 403

I am stucking with the following problem like one month already, I am trying to verify an inapp purchase by using the following api :https://developers.google.com/android-publisher/authorization
I followed every step from the documentation(doing everthing with Postman Rest Client from Chrome), I can retrieve an accesstoken and a refresh token, but whenever when I try to query a purchase it results in error code 403 access not configured, BUT I CONFFIGURED IT IN THE SETTINGS!
anybody with an idea maybe?
It is far from straightforward to get an accesstoken for this API. This blog post helped get me started in the right direction, but I've outlined my own process that does not depend on using any external scripts to work. The steps are:
Obtain a client ID and secret (one-time)
Obtain a Refresh Token (one-time)
Use the Refresh Token to obtain an Access Token (once per hour)
4 Use the access token to access the API
Each of these steps are detailed below:
Obtaining Client ID and Secret
Go to the the Google Developer's console
Go to your project page
Select "Consent Screen" on the left side and make sure that the email address and Product name fields are set
Select "Credentials" from the left menu, and select "create a new client id"
Leave Application type set to "Web application" and set "Authorized redirect URI" to https://localhost. You do not need to change the Authorized JavaScript Origins.
Click "Create Client ID" and record the Client ID and Client secret that result.
Obtaining a Refresh Token
In web browser, enter the following URL (substituting correct value for client_id):
https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=https://localhost&client_id=XXXX
Accept any requests for authorization that appear
You will then be redirected to a URL like this:
https://localhost/?code=4/k0TenvwICIgmBoQOazJy4_EnJr6-.clLqtp_vVAIbEnp6UAPFm0GASPqQigI
Copy the code from the latter part of this URL
Use wget to convert this code into refresh token; substitute CODE, CLIENT_ID, and CLIENT_SECRET
wget --debug --post-data="grant_type=authorization_code&code=CODE&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&redirect_uri=https://localhost" https://accounts.google.com/o/oauth2/token
The resulting JSON file will contain an access_token and a refresh_token. Record the refresh_token value
Obtaining an Access Token
send a POST request to https://accounts.google.com/o/oauth2/token with the following fields set (substitute REFRESH_TOKEN, CLIENT_ID, CLIENT_SECRET)
grant_type=refresh_token
refresh_token=REFRESH_TOKEN
client_id=CLIENT_ID
client_secret=CLIENT_SECRET
You will get back a JSON string containing an access_token that will be good for one hour.
Using the Access Token to make API request
Fetch from
https://www.googleapis.com/androidpublisher/v1.1/applications/PACKAGENAME/inapp/SKU/purchases/PURCHASETOKEN
with an Authorization header containing the access token, e.g:
Authorization: Bearer ya29.1.AADtN_WoM4-4Fb1voFL-emcUWluijCzwvc9Z-FYM9SPvK03HCbGkdROJTVVPSLHK2IlVJQ
You may also be able to pass the access token as an HTTP query parameter, e.g.
https://www.googleapis.com/androidpublisher/v1.1/applications/PACKAGENAME/inapp/SKU/purchases/PURCHASETOKEN?authorization_token=AUTHTOKEN
I had a similar problem as you. Answer by mmigdol is helpful, but it didn't help me. I finally managed to solve it by looking at links generated here: https://developers.google.com/oauthplayground/
Apparently, Android publisher scope
https://www.googleapis.com/auth/androidpublisher
needs to be added into the link requesting authorisation code (before even generating refresh token) by adding:
&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fandroidpublisher
to get this:
https://accounts.google.com/o/oauth2/auth?redirect_uri=<YOUR_REDIRECT_URI>&response_type=code&client_id=<YOUR_CLIENT_ID>&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fandroidpublisher&approval_prompt=force&access_type=offline

Categories

Resources