Getting refresh token in Android application from Spring OAuth2 based authentication server - spring-oauth2

I would like to authenticate android application using OAuth2 in my web service. After some research I know that I should use /oauth/authorize endpoint which gives me implicit authentication. However, in the end after redirection to login page and successful login, server returns access token. After it is expired user has to login again. This is a problem in my scenario and I would like to get also refresh token to be able to use it, to get access token when the old one has expired. Is such scenario possible using spring OAuth2?

In your AuthorizationServerConfiguration you should have a TokenServices bean that is implemented by DefaultTokenServices.
defaultTokenServices.setSupportRefreshToken(true); // enable refresh tokens
Then in your client configuration, be sure to set support for refresh tokens.
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("trusted-app")
.authorizedGrantTypes("password", "refresh_token")
.authorities("ROLE_TRUSTED_CLIENT")
.scopes("read", "write")
.resourceIds(resourceId)
.accessTokenValiditySeconds(accessTokenValiditySeconds)
.refreshTokenValiditySeconds(refreshTokenValiditySeconds)
.secret("secret");
}
When you request make a request to the token endpoint, it should include a refresh token.
/oauth/token?grant_type=password&username="+username+"&password="+password
This should get you a new access token
/oauth/token?grant_type=refresh_token&client_id=trusted-app&refresh_token="+refreshToken

Related

RapidMiner : Can't get JWT Token

I am refering below document to get JWT Token .
However when I call the API /api/rest/tokenservice it doesn't return the token but returns a web interface asking for login . How can I get JWT Token
REST API Url :
https://docs.rapidminer.com/9.10/hub/rest-api/index.html
Response of postman:
In order to query the internal tokenservice endpoint, you need a valid "session". In the native installation method, you can use basic auth as "session" as outlined in the documentation.
curl -u user:pass "http://localhost:8080/api/rest/tokenservice"
{
"idToken": "the-valid-token",
"expirationDate": "the-exp"
}
However, for this to work when you've deployed RapidMiner AI Hub with Keycloak (and docker), you need to 1. enable basic auth for Keycloak, 2. access the route by first having a valid "login session" (cookie name is RM_SERVER_JSESSIONID) or 3. use a valid Keycloak token.
Enable basic auth in Keycloak
rm-server-homedir/configuration/keycloak/keycloak.json
{
...
"enable-basic-auth": true,
...
}
Valid cookie value
Login via web interface, open the browser's developer tools and use the very same RM_SERVER_JSESSIONID cookie value inside the REST request issued to the /api/rest/tokenservice endpoint.
Not sure what you like to achieve, e.g. schedule a process via REST, I like to outline that you can easily add a process and trigger via Web Service. The triggered process could make use of the Admin Tools extension. You still need to enable Keycloak's basic auth though if you like to trigger it from "outside". A guide how to use the extension can be found here.
Valid Keycloak token
Retrieve a valid Keycloak access token (from Keycloak's token endpoint, e.g. via OpenID Connect) and query the
/api/rest/tokenservice endpoint with Authorization: Bearer .
Disclaimer: This answer is used with permission of the original author from the RapidMiner community.

500 server error when authorization request includes the scope `https://api.banno.com/consumer/auth/offline_access`

For my external application I have a requirement to retrieve a refresh token without sending the user through the consent flow.
I have tried following the documentation which describes the available scopes and says that using the scope https://api.banno.com/consumer/auth/offline_access will cause the authorization server to return a refresh token without sending the user through a consent flow.
When I make an authorization request with the scope https://api.banno.com/consumer/auth/offline_access, the authorization server is erroring with a 500 error.
When I make the request without the https://api.banno.com/consumer/auth/offline_access scope my request will succeed, but I will not get a refresh token back.
Is this in the context of requesting a Refresh Token as part of a Plugin?
The original question doesn't specify, but we've had at least one other developer report an issue with requesting a Refresh Token when using an External Application as part of a Plugin.
(Using an External Application to request a Refresh Token outside of the context of a Plugin is unaffected.)

Create JWT Blacklist in Spring Cloud Gateway

I integrated spring cloud gateway with oauth2 login. After logout in scg, the user still can access resource server because the user has valid token. I need to invalidate this valid token in some way. there is blacklist solution as my researches (https://stackoverflow.com/a/53994938/5079581) and i will implement this.
by creating filter, i take jwt in step of "/logout" and put it to blacklist.
public class ExampleWebFilter implements WebFilter {
#Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
ServerHttpRequest request = serverWebExchange.getRequest();
String uri = request.getPath().pathWithinApplication().value();
HttpHeaders headers = request.getHeaders();
if(uri.equals("/logout")) {
List<String> auth = headers.get("Authorization");
}
return webFilterChain.filter(serverWebExchange);
}
}
auth list always returns null. i think that my filter works before token relay filter. how can i access the jwt at gateway? is there any code sample or demo for this? Thanks.
In spring cloud gateway + security oauth2 integration, JWTs are stored in gateway as session. At first, i thought there was an error about saving JWT as session, as it becomes stateful. But, when you logged out, this session is removed and there is no JWT anymore, so there is no need to create blacklist. this way of working is a clever solution.
So, what was my problem? I had 2 seperate servers (gateway, oauth2 server). two sessions are created as a result of the operation. SESSION for gateway, JSESSION for oauth2 server. when you logged out at gateway, only SESSION is removed, but JSESSION is still alive. because of that, the gateway goes oauth server(and still signed in oauth2 server) and get new JWT.
To log out completely in system, you also need to logged out from ouath2 server at the same time.

How to refresh an OAuth token before calling the Execution API?

I am calling the app script execution API from my web app. I am getting ScriptApp.getOauthToken() and storing it inside sheet. When I open my web app I will get the stored access token and calling the execution API with the help of it.
But the problem is, after some time the token is getting expired and it is saying
authorization is required
when I call execution API.
Is there any way to keep access token alive or refreshing it whenever is needed?
I. You cannot and you should not. At least not natively
There is no native Google Apps Script service method for obtaining and exchanging a refresh token (and you would need one if you want to refresh an expired OAuth 2.0 token) for a bearer token. That said, there is no practical reason in storing the short-lived token obtained via getOauthToken method - if a user authorized your application, you can request a token on the fly each time you need to make a request.
II. If you still want to, use a library
There is an officially endorsed library for Google Apps Script that manages OAuth 2.0 flow for you. When using it, you can obtain a refresh token if you set the offline access to true when issuing the token.
III. If you really want to DIY, you can always make your own flow
It is possible to perform a complete Oauth 2.0 flow (both with and without user interaction) by using only the native tools by building a custom JWT token and exchanging it with Google Identity Platform endpoints. But that means you will have to manage everything:
Build JWT custom token headers and payload, then base64 urlencode them and sign with an appropriate signature and concatenate into a token.
Exchange the custom JWT for a short-lived bearer token, validate it and extract expiration time, then persist the token.
Each time you get the token from storage, check for the expiration time, and reissue the token again using the procedure in point 1 - 2.
Handle token revocation (note that you will not be able to invalidate it from Google's servers, only in your application).
And many more caveats along the way.
Note that the token cannot be "kept alive", it goes against the idea behind the OAuth protocol - the lesser the lifespan of an individual token, the better the security of your application.

Integration of Spring Oauth2 implementation with the HTML front end using javascript

I am implementing spring oauth2 for securing my rest api. Basically i am limiting the use of rest api to particular users rather then limiting to every users.
I had implemented the backend and secured my api using spring oauth2.
I am following this steps:
1)Send the GET request with the five parameters.
localhost:8080/SpringRestSecurityOauth/oauth/token?grant_type=password&client_id=Awyi123nasdk89&client_secret=asdj39m32##$s&username=rahul#gmail&password=rahul#9831
2) Server validates the user with the help of spring security and return the json response with access code.
{
"access_token": "22cb0d50-5bb9-463d-8c4a-8ddd680f553f",
"token_type": "bearer",
"refresh_token": "7ac7940a-d29d-4a4c-9a47-25a2167c8c49",
"expires_in": 119
}
3)I access protected resources by passing this access token as a parameter, the request goes something like this:
localhost:8080/SpringRestSecurityOauth/api/users/?access_token=8c191a0f-ebe8-42cb-bc18-8e80f2c4238e
4) In case the token is expired, user needs to get a new token using its refreshing token that was accepted in step(2). A new access token request after expiration looks something like this:
localhost:8080/SpringRestSecurityOauth/oauth/token?grant_type=refresh_token&client_id=restapp&client_secret=restapp&refresh_token=7ac7940a-d29d-4a4c-9a47-25a2167c8c49
All the above step are working fine. Now i need to implement this on my client side. So that a particular client can access this call. I am using HTML/CSS as client side technology.
How client can get the access token? Should it be stored in the browser local storage? Or it should be generated every time the rest call is been made?
Any example would help me to proceed further.
I'm implementing my project like you. I use angularjs and get the access token from response json then store it into cookies.
This link provide sample code for you: http://www.baeldung.com/rest-api-spring-oauth2-angularjs. (See Frontend - Password Flow).
Because refresh token should keep secret and the client is html app, you should see this link http://www.baeldung.com/spring-security-oauth2-refresh-token-angular-js for handling refresh token.
For html client, after obtaining access token using refresh token when access token is expired, I use http-auth-interceptor ([http]://witoldsz.github.io/angular-http-auth/) to retry all rest requests failed because of expired access token.
I'm sorry that I have not enough reputation to post more than 2 links.