Using grails rest plugin with proxy authentication? - grails

I would like to use the following grails plugin to use Google shorten url API.
http://www.grails.org/plugin/rest
The problem is I need to use it with proxy authentication setting (with username and password)
The API gives me setProxy, but without username and password setting.
How can I set my proxy authentication detail here?
Let me know if there is another alternative. I can't use google-url-shortener plugin because I'm still using grails 1.2.0 which is not compatible with the plugin.
Thanks,
Robert

You could try setting the Proxy-Authorization header to authenticate to the proxy. Something similar to the following:
withRest(id: "urlshortener",
requestContentType: JSON,
body: [longUrl: "http://www.google.com/"]
proxy: [host: "myproxy.acme.com", port: 8080, scheme: "http"]) {
def response = post(path: '/urlshortener/v1/url') {
headers.'Proxy-Authorization' = 'Basic ' +
"${username}:${password}".toString().bytes.encodeBase64()
}
}

Related

Is it possible to set the Micronaut OAuth2 callback-uri as an absolute URL?

I have a Micronaut web-app that uses OpenId / OAuth2 / JWT. In some environments, everything works really well with this set up, however, in other environments, auth fails during the step where the configured callback-uri is called. For some reason, in these environments, the URL generated is "http" instead of "https". This causes the call to fail since my application is only accessible over https.
I have no clue why it is trying to use http in the first place, however, if I was able to specify the callback-uri as an absolute / full URL, then I could probably work around this anomaly in these environments.
An example yml config that I use:
application:
name: xxxxx
security:
authentication: idtoken
oauth2:
enabled: true
clients:
azure:
client-id: ${OAUTH_CLIENT_ID}
client-secret: ${OAUTH_CLIENT_SECRET}
openid:
issuer: https://login.microsoftonline.com/xxx
callback-uri: ${OAUTH_CALLBACK_URI}
redirect:
login-success: ${LOGIN_SUCCESS_URL}
logout: '/logout-handler/logout-success'
endpoints:
logout:
get-allowed: true
token:
jwt:
cookie:
cookie-same-site: none
cookie-secure: true
In this config if I set the callback-uri environment variable (OAUTH_CALLBACK_URI) to /oauth/callback/azure, for example, then the full URL that seems to be used is http://xxxxx/oauth/callback/azure. However, if I use a full URL for the environment variable, e.g. https://xxxxx/oauth/callback/azure then the full URL it uses still appends that as opposed to using it as an absolute URL, i.e. http://xxxxx/https://xxxxx/oauth/callback/azure.
Is it possible to specify this uri as an absolute one and not have it append it like the above effectively duplicating it?
Good news. This was fixed in micronaut-security 2.3.4
https://github.com/micronaut-projects/micronaut-security/pull/644

Keycloak Invalid token issuer

I have a mobile app(react-native), a resource service(spring boot) and Keycloak Authenticatioin Service(Auth-Service).
Client makes authentication directly with Auth-Service and gets the access token.
When I do a request to the resource service, the resource service checks the access token by asking to the Auth-Service. But token obtained by the client app and iss field is http://10.0.2.2:8060/auth/realms/sau and my resource service at http://localhost:8110.
Keycloak says: error="invalid_token", error_description="Invalid token issuer. Expected 'http://localhost:8060/auth/realms/sau', but was 'http://10.0.2.2:8060/auth/realms/sau'"
My question is how can I make authentication in resource service behalf my client?
Mobile App:
export const prepareRequestBody = credentials => {
const params = new URLSearchParams();
params.append('username', credentials.username);
params.append('password', credentials.password);
params.append('client_id', "nasilim-mobile-app");
params.append('grant_type', "password");
return params;
};
export const login = credentials => {
const params = prepareRequestBody(credentials);
return axios.post(LOGIN, params);
};
Resource-Service:
application.yml
keycloak:
realm: sau
resource: photo-service
bearer-only: false
auth-server-url: http://localhost:8060/auth
credentials:
secret: 69a3e80c-8360-42df-bcec-b6575a6949dc
Note: I have checked this question and I have tried to set "X-Forwarded-For" : "http://localhost:8060/" but It didn't work Keycloak returns:
{
"error": "invalid_request",
"error_description": "HTTPS required"
}
Here is a Sample Access Token that obtained by mobile client.
The "iss" claim vary in function of the request. The variable KEYCLOAK_FRONTEND_URL can change this behavior. So try do as follow in your docker-compose file:
KEYCLOAK_FRONTEND_URL: http://10.0.2.2:8060/auth
You need to configure access from your Spring Boot app to the Auth server in an external fashion, not localhost:
keycloak:
realm: sau
resource: photo-service
bearer-only: false
auth-server-url: http://10.0.2.2:8060/auth
credentials:
secret: 69a3e80c-8360-42df-bcec-b6575a6949dc
This way the token issuers will match. This will probably require either to disable SSL requirement for external request in keycloak or to configure proper SSL communication. If this is meant for production, do the right way.
See also:
https://stackoverflow.com/a/42504805/1199132
What if you can not access the auth server using the external address? This will not work. Check https://issues.redhat.com/browse/KEYCLOAK-6984
One workaround is to set the reaml public key. But it's not recommended as the adapter will not check for new key if the key is rotated.
Use the proxy-url in the adapter configuration to provide an alternative URL.
See docs.
Spring application.yml:
keycloak:
authServerUrl: http://10.0.2.2:8060/auth
proxyUrl: http://localhost:8060/auth
...
Or keycloak.json:
{
"auth-server-url": "http://10.0.2.2:8060/auth",
"proxy-url": "http://localhost:8060/auth",
...
}
At keycloak go to your realm then to realm settings and place the url you want at frontend url.
Problem is because inside "container" there is different ip(host).
Keycloak has property hostname-url. You should inform keycloak about your frontend(hosts). You can do that during starting new instance of keycloak. Command to start your keycloak is start-dev --hostname-url=url-to-your-frontend
you can provide the hostname of frontend, so the command will be look like this:
start-dev --hostname-url=http://10.0.2.2:8060
This solution is working for Keycloak version 19 and up

Angular with Rails API: "Failed to load resource: the server responded with a status of 401 (Unauthorized)"

So I am deploying an Angular 5 app with a Rails 5 back-end. I can get the data to flow properly between the two locally, but trying to connect to the deployed version of the API (which is on Heroku) I run into some authorization issue. The error is:
Failed to load https://my_api.herokuapp.com/data.json: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:4200' is therefore not allowed access.
The response had HTTP status code 404.
Cross-Origin Read Blocking (CORB) blocked cross-origin response <URL> with MIME type application/json.
See <URL> for more details.
Is this something I need to change within the Rails API or in Angular? The deployed Rails API is essentially the same as the local version so I'm not sure where the disconnect is coming from.
There are only two refrences to the API in Angular. I connect to it the same way that I do to the local server:
Angular, app-module.ts
providers: [Angular2TokenService, AuthService, AuthGuard,
// {provide: 'api', useValue: 'http://localhost:3000/'}
{provide: 'api', useValue: 'https://my_ api.herokuapp.com/data.json'}
]
Perhaps it's my use of Angular2TokenService?
Angular, environment.ts:
export const environment = {
production: false,
token_auth_config: {
// apiBase: 'http://localhost:3000'
apiBase: 'https://my_api.herokuapp.com/data.json'
}};
Thanks! Let me know of any suggestions you might have or if you need clarification.
It's issue with CORS(cross-origin-resource-sharing). You can handle it by adding callback in your API like below:
def cors_set_access_control_headers
headers['Access-Control-Allow-Origin'] = ENV['SERVER_URL'] || '*'
end
where SERVER_URL is your front-end server URL
Else you can use gem 'rack-cors' as suggested in comments by #Kedarnag Mukanahallipatna

Reactivesearch proxylike backend with cookie authentication

I have a spring backend which i'm accessing my Elastic search cluster through by a proxylike endpoint. The request has to be authorized with a cookie.
I'm currently using searchkit with supports authenticating requests through the withCredentials flag. Is there a similar option for reactivesearch or is there any other solution for authorizing the request with a cookie?
I could add: the backend exposes a swagger client which runs on a different domain than my frontend client. This client "owns" the cookie and thus i cannot read the cookie from my frontend client
You can use the headers prop in ReactiveBase to pass custom headers along with the requests. Link to docs. Since there is no withCredentials you could read the cookies and set in custom headers to verify the requests at the proxy middleware.
<ReactiveBase
...
headers={{
customheader: 'abcxyz'
}}
>
<Component1 .. />
<Component2 .. />
</ReactiveBase>
Here is a sample proxy server but its in NodeJS
Okey so it turns out, Reactivesearch uses fetch and fetch wants credentials: 'include' for cookie authentication. This may not be placed in the headers that Reactivesearch supplies and must be placed on the root object for the request.
It's possible to do this by implementing beforeSend on ReactiveBase.
const Base = ({ children }) => {
const onBeforeSend = props => {
return {
...props,
credentials: 'include',
}
}
return (
<ReactiveBase
app="app-name"
url="url"
beforeSend={onBeforeSend}
>
{children}
</ReactiveBase>
)
}

Authorization headers for google login using restlet

Using restlet, I want to make a post to android's c2dm service. I have tried this from a generic rest client and all worked ok.
However, when I try to post using restlet, I get a (401) - Unauthorized response.
For authorization, I need to set the following header:
Authorization: GoogleLogin auth=my_auth_token
How do I set this header using restlet? I know I need to set a challenge response, but I'm not sure about it's parameters. Is "GoogleLogin " my ChallengeScheme? Do i use it like this:
ChallengeScheme.valueOf("GoogleLogin")
What about setting the token?
Thanks
You can create a custom scheme and set the challenge response with this scheme for your requests :
ChallengeScheme sc = new ChallengeScheme("Google_Login", "GoogleLogin", "Android c2dm service");
clientResource.setChallengeResponse(sc, auth, myauthtoken);

Resources