service to service authentication with Spring cloud Oauth 2 - spring-boot

I'm using multiple microservices with Spring Cloud stack and oauth2 is used to protect resources and provide SSO.
I'm able to authenticate from a user interface with login and password.
But i also need to call a service from another service. My issue is that the service need to be authenticate. This kind of call:
ResponseEntity<String> responseEntity = restTemplate.exchange("http://anoter-service/hello", HttpMethod.GET, null, new ParameterizedTypeReference<String>() {});
Any idea on how to authenticate a service calling another one ?
I have this exception:
Caused by: org.springframework.security.oauth2.client.resource.UserRedirectRequiredException: A redirect is required to get the users approval
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.getRedirectForAuthorization(AuthorizationCodeAccessTokenProvider.java:359)
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.obtainAccessToken(AuthorizationCodeAccessTokenProvider.java:205)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.createRequest(OAuth2RestTemplate.java:105)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:592)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:503)
at org.springframework.web.client.RestTemplate$$FastClassBySpringCGLIB$$aa4e9ed0.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
at org.springframework.cloud.netflix.metrics.RestTemplateUrlTemplateCapturingAspect.captureUrlTemplate(RestTemplateUrlTemplateCapturingAspect.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:620)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:609)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
at org.springframework.security.oauth2.client.OAuth2RestTemplate$$EnhancerBySpringCGLIB$$3473d19a.exchange(<generated>)

I would just log in programatically through the same authentication entry point your users do. Create credentials for your services and set their permissions in this area. I don't think you should try to treat your services any differently.
You will likely have to set up your rest template to watch for 403s and when encountered perform a log in, but that should be fairly easy to code.

Related

How to configure StandardOauth2AccessTokenProvider properly?

We are currently trying to access the Google Spreadsheet REST API through InvokeHTTP.
However, we are struggling to get the StandardOauth2AccessTokenProvider configured properly.
We upgraded our Nifi instance to version 1.16.3 in order to provide the scope, however, we are not sure which data needs to be put into the Client ID and Client Secret.
We tried the following options:
Create Oauth2 credentials in the Google Cloud console and provide these
Combine the above approach with a google username and password (in User Password mode)
Create a service account and provide its credentials
Whenever we try to send any request to the Google Spreadsheets API, we always get the same stack trace:
2022-09-29 11:47:18,193 ERROR [Timer-Driven Process Thread-2] o.a.nifi.processors.standard.InvokeHTTP InvokeHTTP[id=86d7424e-0183-1000-cd72-d2071e1add8b] Failed to properly initialize Processor. If still scheduled to run, NiFi will attempt to initialize and run the Processor again after the 'Administrative Yield Duration' has elapsed. Failure is due to java.io.UncheckedIOException: OAuth2 access token request failed
java.io.UncheckedIOException: OAuth2 access token request failed
at org.apache.nifi.oauth2.StandardOauth2AccessTokenProvider.getAccessDetails(StandardOauth2AccessTokenProvider.java:330)
at org.apache.nifi.oauth2.StandardOauth2AccessTokenProvider.acquireAccessDetails(StandardOauth2AccessTokenProvider.java:289)
at org.apache.nifi.oauth2.StandardOauth2AccessTokenProvider.getAccessDetails(StandardOauth2AccessTokenProvider.java:243)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.nifi.controller.service.StandardControllerServiceInvocationHandler.invoke(StandardControllerServiceInvocationHandler.java:254)
at org.apache.nifi.controller.service.StandardControllerServiceInvocationHandler.invoke(StandardControllerServiceInvocationHandler.java:105)
at com.sun.proxy.$Proxy108.getAccessDetails(Unknown Source)
at org.apache.nifi.processors.standard.InvokeHTTP.initOauth2AccessTokenProvider(InvokeHTTP.java:864)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.nifi.util.ReflectionUtils.invokeMethodsWithAnnotations(ReflectionUtils.java:145)
at org.apache.nifi.util.ReflectionUtils.invokeMethodsWithAnnotations(ReflectionUtils.java:133)
at org.apache.nifi.util.ReflectionUtils.invokeMethodsWithAnnotations(ReflectionUtils.java:78)
at org.apache.nifi.util.ReflectionUtils.invokeMethodsWithAnnotation(ReflectionUtils.java:55)
at org.apache.nifi.controller.StandardProcessorNode.lambda$initiateStart$6(StandardProcessorNode.java:1662)
at org.apache.nifi.engine.FlowEngine$3.call(FlowEngine.java:123)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:750)
Caused by: com.fasterxml.jackson.core.JsonParseException: Unexpected character ('<' (code 60)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
at [Source: (StringReader); line: 1, column: 2]
at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:2391)
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:735)
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:659)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._handleOddValue(ReaderBasedJsonParser.java:2005)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken(ReaderBasedJsonParser.java:802)
at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4761)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4667)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3629)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3597)
at org.apache.nifi.oauth2.StandardOauth2AccessTokenProvider.getAccessDetails(StandardOauth2AccessTokenProvider.java:324)
... 26 common frames omitted
Is this due to a possible Consent Screen? Any pointers on what we are doing wrong?

Google Login consent page does not ask for permission for all scopes my application requests

I have created a small java app that downloads and handles all photos uploaded by my familys devices to Google Drive.
But now Google Drives is no longer used for storing photos, so I need access to Google Photos instead.
But no matter what I do, I cannot get access via the java API.
And now I figured out the problem. Even though I have updated my applications scope requirements in the google dev. console (pic 1), google does NOT ask for permission for the Photo Library scopes at login (pic 2).
And thus I am not allowed access the the Photo Library, but get:
com.google.api.gax.rpc.PermissionDeniedException: io.grpc.StatusRuntimeException: PERMISSION_DENIED: Request had insufficient authentication scopes.
at com.google.api.gax.rpc.ApiExceptionFactory.createException(ApiExceptionFactory.java:55) ~[gax-1.45.0.jar:1.45.0]
at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:72) ~[gax-grpc-1.45.0.jar:1.45.0]
at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:60) ~[gax-grpc-1.45.0.jar:1.45.0]
at com.google.api.gax.grpc.GrpcExceptionCallable$ExceptionTransformingFuture.onFailure(GrpcExceptionCallable.java:97) ~[gax-grpc-1.45.0.jar:1.45.0]
at com.google.api.core.ApiFutures$1.onFailure(ApiFutures.java:68) ~[api-common-1.8.1.jar:?]
at com.google.common.util.concurrent.Futures$CallbackListener.run(Futures.java:1015) ~[guava-28.0-jre.jar:?]
at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:30) ~[guava-28.0-jre.jar:?]
at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1137) ~[guava-28.0-jre.jar:?]
at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:957) ~[guava-28.0-jre.jar:?]
at com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:748) ~[guava-28.0-jre.jar:?]
at io.grpc.stub.ClientCalls$GrpcFuture.setException(ClientCalls.java:492) ~[grpc-stub-1.10.1.jar:1.10.1]
at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:467) ~[grpc-stub-1.10.1.jar:1.10.1]
at io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39) ~[grpc-api-1.21.0.jar:1.21.0]
at io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23) ~[grpc-api-1.21.0.jar:1.21.0]
at io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40) ~[grpc-api-1.21.0.jar:1.21.0]
at io.grpc.internal.CensusStatsModule$StatsClientInterceptor$1$1.onClose(CensusStatsModule.java:700) ~[grpc-core-1.21.0.jar:1.21.0]
at io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39) ~[grpc-api-1.21.0.jar:1.21.0]
at io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23) ~[grpc-api-1.21.0.jar:1.21.0]
at io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40) ~[grpc-api-1.21.0.jar:1.21.0]
at io.grpc.internal.CensusTracingModule$TracingClientInterceptor$1$1.onClose(CensusTracingModule.java:399) ~[grpc-core-1.21.0.jar:1.21.0]
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:500) ~[grpc-core-1.21.0.jar:1.21.0]
at io.grpc.internal.ClientCallImpl.access$300(ClientCallImpl.java:65) ~[grpc-core-1.21.0.jar:1.21.0]
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:592) ~[grpc-core-1.21.0.jar:1.21.0]
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access$700(ClientCallImpl.java:508) ~[grpc-core-1.21.0.jar:1.21.0]
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:632) ~[grpc-core-1.21.0.jar:1.21.0]
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37) ~[grpc-core-1.21.0.jar:1.21.0]
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123) ~[grpc-core-1.21.0.jar:1.21.0]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_212]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_212]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_212]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [?:1.8.0_212]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_212]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_212]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_212]
Suppressed: com.google.api.gax.rpc.AsyncTaskException: Asynchronous task failed
at com.google.api.gax.rpc.ApiExceptions.callAndTranslateApiException(ApiExceptions.java:57) ~[gax-1.45.0.jar:1.45.0]
at com.google.api.gax.rpc.UnaryCallable.call(UnaryCallable.java:112) ~[gax-1.45.0.jar:1.45.0]
at com.google.photos.library.v1.internal.InternalPhotosLibraryClient.listAlbums(InternalPhotosLibraryClient.java:913) ~[google-photos-library-client-1.3.0.jar:1.3.0]
at com.google.photos.library.v1.internal.InternalPhotosLibraryClient.listAlbums(InternalPhotosLibraryClient.java:891) ~[google-photos-library-client-1.3.0.jar:1.3.0]
at com.google.photos.library.v1.PhotosLibraryClient.listAlbums(PhotosLibraryClient.java:201) ~[google-photos-library-client-1.3.0.jar:1.3.0]
at dk.fafdifh.photo.manager.cron.PhotoSynchronizer.fetch(PhotoSynchronizer.java:208) ~[classes/:?]
at java.lang.Iterable.forEach(Iterable.java:75) [?:1.8.0_212]
at dk.fafdifh.photo.manager.cron.PhotoSynchronizer.fetch(PhotoSynchronizer.java:132) [classes/:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_212]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_212]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_212]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_212]
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) [spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) [spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_212]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:1.8.0_212]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_212]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:1.8.0_212]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_212]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_212]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_212]
Caused by: io.grpc.StatusRuntimeException: PERMISSION_DENIED: Request had insufficient authentication scopes.
at io.grpc.Status.asRuntimeException(Status.java:533) ~[grpc-api-1.21.0.jar:1.21.0]
... 23 more
Oh, and by the way - yes; I have tried deleting all credentials from the application, revoking the application's access to my account and start from scratch. To no avail.
I have not tried creating an entirely new application in google dev console, but...
I figured it out!
What scopes are included in the consent page is NOT decided by what scopes are added to the application in the dev. console auth page.
It is (of course, stupido!) decided by what scopes are listed in the GoogleAuthorizationCodeFlow scopes list.
So simple...

Keycloak Client doesn't have secret available with Access Type Public

I am using Keycloak 3.4.3 and protecting Spring based Rest service.
Below is Keycloak client configuration:
Client Protocol: openid-connect<br>
Access Type: public<br>
Standard Flow Enabled: ON<br>
Implicit Flow<br>
Direct Access Grants Enabled: ON<br>
Authorization Enabled: OFF<br>
Is it important to provide secret with Access Type as public. If yes, how can I provide secret as I couldn't find any option in the Keycloak client configuration. Please help.
2018-02-28 15:19:10.216 WARN 7813 --- [nio-8080-exec-2]
a.a.ClientIdAndSecretCredentialsProvider : Client 'democlientid'
doesn't have secret available 2018-02-28 15:19:10.375 ERROR 7813 ---
[nio-8080-exec-2] o.k.adapters.OAuthRequestAuthenticator : failed to
turn code into token
java.net.ConnectException: Connection refused (Connection refused)
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:na]
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:400)
~[na:na]
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:243)
~[na:na]
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:225)
~[na:na]
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:402)
~[na:na]
at java.base/java.net.Socket.connect(Socket.java:591) ~[na:na]
at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121)
~[httpclient-4.5.5.jar!/:4.5.5]
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
~[httpclient-4.5.5.jar!/:4.5.5]
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:144)
~[httpclient-4.5.5.jar!/:4.5.5]
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:134)
~[httpclient-4.5.5.jar!/:4.5.5]
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:610)
~[httpclient-4.5.5.jar!/:4.5.5]
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:445)
~[httpclient-4.5.5.jar!/:4.5.5]
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:835)
~[httpclient-4.5.5.jar!/:4.5.5]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
~[httpclient-4.5.5.jar!/:4.5.5]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
~[httpclient-4.5.5.jar!/:4.5.5]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
~[httpclient-4.5.5.jar!/:4.5.5]
at org.keycloak.adapters.ServerRequest.invokeAccessCodeToToken(ServerRequest.java:111)
~[keycloak-adapter-core-3.4.3.Final.jar!/:3.4.3.Final]
at org.keycloak.adapters.OAuthRequestAuthenticator.resolveCode(OAuthRequestAuthenticator.java:336)
~[keycloak-adapter-core-3.4.3.Final.jar!/:3.4.3.Final]
at org.keycloak.adapters.OAuthRequestAuthenticator.authenticate(OAuthRequestAuthenticator.java:281)
~[keycloak-adapter-core-3.4.3.Final.jar!/:3.4.3.Final]
at org.keycloak.adapters.RequestAuthenticator.authenticate(RequestAuthenticator.java:139)
~[keycloak-adapter-core-3.4.3.Final.jar!/:3.4.3.Final]
at org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.authenticateInternal(AbstractKeycloakAuthenticatorValve.java:203)
~[spring-boot-container-bundle-3.4.3.Final.jar!/:3.4.3.Final]
at org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve.authenticate(KeycloakAuthenticatorValve.java:50)
[spring-boot-container-bundle-3.4.3.Final.jar!/:3.4.3.Final]
at org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve.doAuthenticate(KeycloakAuthenticatorValve.java:57)
[spring-boot-container-bundle-3.4.3.Final.jar!/:3.4.3.Final]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:586)
[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.invoke(AbstractKeycloakAuthenticatorValve.java:181)
~[spring-boot-container-bundle-3.4.3.Final.jar!/:3.4.3.Final]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
[tomcat-embed-core-8.5.27.jar!/:8.5.27]
In case anyone else finds this question - the answer seems to be that public access types are for browser logins using Keycloak's UI only. Eg you can't use a Spring UI with the Keycloak plugin - they must use the Confidential access type (in which case you get a "Credentials" tab in the Clients section of the admin UI giving the secret).
See https://www.keycloak.org/docs/4.8/server_admin/#oidc-clients and scroll down to "Access Type"
If you will check the client admin-cli under the master realm ,you will easily able to understand why the by default mentioned access-type=public for this client.
FYI just check the below details from official documents
Access Type
This defines the type of the OIDC client.
Confidential access type is for server-side clients that need to perform a browser login and require a client secret when they turn an access code into an access token, (see Access Token Request in the OAuth 2.0 spec for more details). This type should be used for server-side applications.
public
Public access type is for client-side clients that need to perform a browser login. With a client-side application there is no way to keep a secret safe. Instead it is very important to restrict access by configuring correct redirect URIs for the client.
Bearer-only access type means that the application only allows bearer token requests. If this is turned on, this application cannot participate in browser logins.
So your client have Public access type so it mean you want to do login for client-site application so for public access-type keyclock wont give secret key.
Apart from your question,another advantage of this,user can use keyclock from command prompt as well. You can login like this
/opt/keycloak/bin/kcadm.sh config credentials --server https://<IP ADDRESS>:8666/auth --realm master --user admin --password admin --client admin-cli
you can perform admin task like
Creating a new realm.
Creating clients under new realm
Creating users/group etc.
You have a configuration error; the server address is not right.

Java: Access job History server and application timeline server on kerberized hadoop cluster?

I have used kerberos rest template to access the job history server on kerberized hadoop but this code is throwing me an exception:
KerberosRestTemplate kerberosRestTemplate = new KerberosRestTemplate(properties.getProperty("userKeytabPath"),properties.getProperty("userprincipal")); System.out.println(kerberosRestTemplate.getForObject(jobhistoryurl, String.class));
Exception:
Exception in thread "main" org.springframework.web.client.RestClientException: Error running rest call; nested exception is org.springframework.web.client.HttpClientErrorException: 401 Authentication required
at org.springframework.security.kerberos.client.KerberosRestTemplate.doExecute(KerberosRestTemplate.java:196)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:530)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237)
at com.datametica.hiveconnection.hiveconnectioncheck.HivePortCheck.main(HivePortCheck.java:57)
Caused by: org.springframework.web.client.HttpClientErrorException: 401 Authentication required
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:614)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:570)
at org.springframework.security.kerberos.client.KerberosRestTemplate.doExecuteSubject(KerberosRestTemplate.java:202)
at org.springframework.security.kerberos.client.KerberosRestTemplate.access$100(KerberosRestTemplate.java:67)
at org.springframework.security.kerberos.client.KerberosRestTemplate$1.run(KerberosRestTemplate.java:191)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:360)
at org.springframework.security.kerberos.client.KerberosRestTemplate.doExecute(KerberosRestTemplate.java:187)
... 3 more
So is there any extra parameters that i have to pass in request headers to access kerberos secured apis?
Also before Accessing this api i have logged in a user via same user principal and keytab provided in kerberosRestTemplate Using UserGroupInformation class of hadoop security.
UserGroupInformation.loginUserFromKeytab(properties.getProperty("userprincipal"),properties.getProperty("userKeytabPath"));
I have check the current user logged in(via ugi of current user) before accessing job history and it is giving me that user is logged in and with kerberos authentication but i am still getting 401 status from job history server.

I am unable to publish post on user facebook wall using Spring Social

I am successfully logged with my app using Spring Social Facebook. But i am unable to post on user Facebook wall. I got below error
POST request for "https://graph.facebook.com/197550980606288/feed" resulted in 403 (Forbidden); invoking error handler
{"error":{"message":"(#200) The user hasn't authorized the application to perform this action","type":"OAuthException","code":200,"fbtrace_id":"DQHUBlkYCOo"}}
2016-03-07 11:03:17,040 - ERROR [qtp696479026-23] - coach - Exception Occurred while posting a link on facebook for user Id : {}, exception is : {}
org.springframework.social.InsufficientPermissionException: Insufficient permission for this operation.
at org.springframework.social.facebook.api.impl.FacebookErrorHandler.handleFacebookError(FacebookErrorHandler.java:120)
at org.springframework.social.facebook.api.impl.FacebookErrorHandler.handleError(FacebookErrorHandler.java:65)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:566)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:524)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:495)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:343)
at org.springframework.social.facebook.api.impl.FacebookTemplate.publish(FacebookTemplate.java:266)
at com.viprasi.web.controller.FacebookController.postOnWall(FacebookController.java:115)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)

Resources