I am getting invalid credentials while implementing the Auth Code Flow with Oauth2 Spring Security. Below is the microservices flow:
Eureka Service - Gateway - Custom Spring Authentication Service
- AM Service (pulls AM business data)
- SM Service (pulls SM business data)
I am able to authenticate and auth code is getting generated as show below
http://127.0.0.1:8060/login/oauth2/code/test-client?code=J5Qvmk&state=HLD0vIaz6GzJl4dK_HJCtt7CGojuPSBVj23bu9fL38s%3D
But then when trying to get redirected to original API call, it fails stating "Invalid credentials"
Below is the error:
enter image description here
Below is the configurations on gateway:
spring:
application:
name: gateway-service
cloud:
gateway:
default-filters:
- TokenRelay
routes:
- id: CdsaiAMServiceApplication
uri: http://127.0.0.1:8082
predicates:
- Path=/ams/**
filters:
- TokenRelay=
- StripPrefix=0
- name: Retry
args:
retries: 1
statuses: UNAUTHORIZED
methods: GET,POST,DELETE
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false
- id: CdsaiSMServiceApplication
uri: http://127.0.0.1:8866
predicates:
- Path=/sms/**
filters:
- TokenRelay=
- StripPrefix=0
- name: Retry
args:
retries: 1
statuses: UNAUTHORIZED
methods: GET,POST,DELETE
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false
discovery:
locator:
enabled: true
sleuth:
sampler:
probability: 1
zipkin:
baseUrl: ${ZIPKIN_BASE_URL:http://127.0.0.1:9411}
security:
oauth2:
resource:
user-info-uri: "http://127.0.0.1:8383/user"
client:
registration:
test-client:
provider: spring
client-id: clientId
client-secret: client-secret
authorization-grant-type: authorization_code
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
client-name: test-client
user-info-authentication-method: header
provider:
spring:
authorization-uri: "http://127.0.0.1:8383/oauth/authorize"
token-uri: "http://127.0.0.1:8383/oauth/token"
token-info-uri: "http://127.0.0.1:8383/oauth/check_token"
user-name-attribute: preferred_username
Can someone please help.
Related
We are currently working on a POC of Spring Cloud Dataflow, deployed in an Azure Kubernetes Service.
One of our requirements is to integrate it with an Azure Active Directory.
The authentication part went smoothly, but for the authorization, we need SCDF to be able to recognize appRoles of users (RBAC). But the behaviour so far seems to be that only the scopes are exposed, and if all scopes were exposed, then the user has all the service-roles (ROLE_VIEW, ROLE_DESTROY, ROLE_DEPLOY,...).
For instance, we'd like one user to have ROLE_VIEW only, and another user to have both ROLE-VIEW and ROLE_DESTROY.
What we've done so far:
Following the documentation, we created an App Registration (dataflow-server) exposing the following scopes & API permissions:
api://dataflow-server/dataflow.destroy
api://dataflow-server/dataflow.view
api://dataflow-server/dataflow.deploy
api://dataflow-server/dataflow.manage
api://dataflow-server/dataflow.schedule
api://dataflow-server/dataflow.create
api://dataflow-server/dataflow.modify
We created 2 appRoles, "role_reader" and "role_writer", to grant to specific users.
And we updated the configmap of the SCDF server to include these configurations:
spring:
cloud:
dataflow:
security:
authorization:
provider-role-mappings:
dataflow-server:
map-oauth-scopes:true
role-mappings:
ROLE_VIEW: role_reader
ROLE_DESTROY:role_writer
ROLE_DEPLOY: role_writer
ROLE_CREATE: role_writer
ROLE_MANAGE: role_writer
ROLE_SCHEDULE: role_writer
ROLE_MODIFY: role_writer
And:
spring:
security:
oauth2:
client:
registration:
dataflow-server:
provider: azure
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
client-id: <client_id_from_the_azure_app_registration>
client-secret: <client_secret>
scope:
- openid
- profile
- email
- offline_access
- api://dataflow-server/dataflow.view
- api://dataflow-server/dataflow.destroy
- api://dataflow-server/dataflow.schedule
- api://dataflow-server/dataflow.manage
- api://dataflow-server/dataflow.create
- api://dataflow-server/dataflow.deploy
- api://dataflow-server/dataflow.modify
provider:
azure:
issuer-uri: https://login.microsoftonline.com/<tenant-id>/v2.0
user-name-attribute: name
resourceserver:
jwt:
jwt-set-uti: https://login.microsoftonline.com/<tenant-id>/v2.0/keys
My understanding after reading the docs was that this should be sufficient to map the service roles (ROLE_VIEW) with the Azure AppRoles (role_reader) and allow to use RBAC.
Where did I go wrong ?
Thanks in advance for taking the time to read !
Super basic (video) but the title is nearly my comment to Top 3 ways to run your containers on Google Cloud
User Authentication (content) in 2020 about api gateway from endpoints
Maybe a focal point for an answer could be the app engine role for api gateway in 2022. swagger.yaml (#comment)
# openapi2-run.yaml
swagger: "2.0"
info: # >1 API/service; spec x-google-api-name OpenAPI document extension.
title: backbank # mastercard-backbank # API_ID optional-string
#https://cloud.google.com/api-gateway/docs/get-started-cloud-run
description: node cloud run api mastercard p.12 customer keys # Sample API on API Gateway with a Cloud Run backend
version: 0.0.1
security:
- firebase: []
securityDefinitions: #https://cloud.google.com/api-gateway/docs/authenticating-users-firebase
firebase: #bearer https://cloud.google.com/endpoints/docs/openapi/openapi-extensions
authorizationUrl: "" # empty for firebase frm bearer Authorization?
flow: "implicit"
type: "oauth2"
x-google-issuer: "https://securetoken.google.com/vaumoney"
x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken#system.gserviceaccount.com"
x-google-audiences: "vaumoney"
host: "vault-co.in"
basePath: "/" # https://stackoverflow.com/questions/71258737/making-a-cloud-firestore-rest-api-call-through-cloud-endpoints
#When the basePath property is configured in the service configuration as well,
#this header applies only to URL paths that are prefixed by the basePath property value.
#URLs that aren't part of the basePath aren't passed through regardless of the x-google-allow property.
schemes:
- https
consumes:
- application/json
produces:
- application/json
#x-google-allow:
#all
#jwt_audience: https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken#system.gserviceaccount.com/vaumoney
#x-google-endpoints:
#- name: "vault-co.in"
#allowCors: True
paths:
/:
get:
summary: Yes Hello cloud run (api gateway, load balance) service
operationId: get
x-google-backend:
address: https://vault-co.in:8080 # APP_URL endpoint(s)
protocol: h2
responses:
200:
description: This is a (Non-Graphical) Application Programming Interface
#schema:
#type: string
#default: '''ello guv'''
default:
description: Something is wrong
#schema:
#type: string
#default: '''some not 200'''
options:
summary: Enable CORS with headers
operationId: options
x-google-backend:
address: https://vault-co.in:8080 # APP_URL endpoint(s)
jwt_audience: https://vault-co.in
protocol: h2
description: |
Origin, Methods and Headers allowing headers potentially requested
tags:
- CORS
responses:
200:
description: OPTIONS responding headers
headers:
Access-Control-Allow-Origin:
type: string
#$ref: '#/definitions/String'
default: "'i7l8qe.csb.app'"
Access-Control-Allow-Methods:
type: string
default: "'GET,POST'"
Access-Control-Allow-Headers:
type: string
default: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
403:
description: OPTIONS responding headers
headers:
Access-Control-Allow-Origin:
type: string
default: "'i7l8qe.csb.app'" # '''vau.money'''
Access-Control-Allow-Methods:
type: string
default: "'GET,POST'"
Access-Control-Allow-Headers:
type: string
default: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
#content: {}
default:
description: Something is wrong
#type: string
#default: '''some not 200'''
post:
summary: Respond properly indeed
operationId: posted
x-google-backend:
address: https://vault-co.in:8080 # APP_URL endpoint(s)
jwt_audience: https://vault-co.in
protocol: h2
description: |
Successful api fetch
parameters:
- name: pageOffset
in: body
required: true
schema:
type: object
properties:
pageOffset:
description: pageOffset is required, try 0
type: string
pageLength:
description: pageLength is required, try 10
type: string
postalCode:
description: postalCode is required, try 11101
type: string
responses: # https://swagger.io/docs/specification/describing-responses/
default: #200
description: post result
#content:v3 application/json:
schema:
type: object
description: response ok
required:
- results
properties:
results:
#collectionFormat: csv
type: array
default: []
items:
type: string
meta:
type: object
properties:
title:
type: string
description:
type: string
I repeat attempts in seriatim:
gcloud api-gateway gateways delete backbank --location=us-central1
gcloud api-gateway api-configs delete backbank --api=backbank
gcloud api-gateway api-configs create backbank --api=backbank --openapi-spec=swagger.yaml --project=vaumoney --backend-auth-service-account=vaumoney#appspot.gserviceaccount.com
(a) gcloud endpoints services deploy swagger.yaml --project=vaumoney
(b) gcloud services enable vault-co.in (Principal-role permission name: "firebase-adminsdk")
gcloud run deploy backbank \
--image="gcr.io/vaumoney/endpoints-runtime-serverless:2.38.0-vault-co.in-2022-09-08r2" \
--set-env-vars ESPv2_ARGS=^++^--cors_preset=cors_with_regex++--cors_allow_origin_regex=^https:[/][/]i7l8qe.csb.app$++--cors_allow_methods=GET,POST,OPTIONS++--cors_allow_headers=Origin,Content-Type,Authorization,Referrer-Policy++--cors_allow_credentials \
--platform managed --project vaumoney
Of course, I incessantly get this:
The request was not authenticated. Either allow unauthenticated invocations or set the proper Authorization header. Read more at https://cloud.google.com/run/docs/securing/authenticating Additional troubleshooting documentation can be found at: https://cloud.google.com/run/docs/troubleshooting#unauthorized-client
But OPTIONS might be the problem (albeit "" on GET):
"This would be really useful for us, we're using cloud run for all our microservices and want to call these from a SPA via API Gateway." "We're back to Cloud Endpoints and ESPv2 for the time being, but we 100% see the benefits of the managed API Gateway, should CORS support be available for gRPC requests."
What am I to do?
I am using Spring Cloud Starter Security and Spring Boot Starter Ouath2 Client in my Reactive application and made my configurations at application.yml as you will see below.
It applies Token perfectly for the pages that has TokenRelay but the problem is I have to configure that it should not apply Token for the pages that has no TokenRelay. How I can success it ?
Could you please help me find out that issue ? You can find my codes below.
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
application.yml
routes:
- id: securedApp
uri: http://localhost:51687
predicates:
- Path=/keycloak-oidc-code/**
filters:
- TokenRelay=
- RemoveRequestHeader=Cookie
filter:
# Removes Expect Header that send to the services
remove-hop-by-hop:
headers:
- expect
security:
basic:
enable: false
ignored: /**
oauth2:
client:
registration:
sample-authorization-code:
id: MyApplication
client-id: MyApplication
client-secret:f607d7c5-991d-4605-843f-330f419ed143
client-name: SecondApplication
provider: keycloak
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
authorization-grant-type: authorization_code
client-authentication-method: post
scope: openid, address, fun
provider:
keycloak:
issuer-uri: http://localhost:8080/auth/realms/MyApplication
server:
port: 8001
SecurityConfig.java
#EnableWebFluxSecurity
#Configuration
public class SecurityConfig
{
#Bean
SecurityWebFilterChain springSecurityFilterChain( ServerHttpSecurity http ) throws Exception
{
return http.authorizeExchange().matchers( EndpointRequest.to( InfoEndpoint.class, HealthEndpoint.class)).permitAll().anyExchange().authenticated().and().oauth2Login().and().build();
}
}
Your approach is missing a point. You need to add new route for non-secured app to application.yml and you have to permit that route in security configuration that you mentioned at SecurityConfig.java.
application.yml
routes:
- id: testMyApplication
uri: localhost:61307
predicates:
- Path=/myApplication/**
SecurityConfig.java
return http.authorizeExchange().pathMatchers( "/myApplication/**"").
permitAll().anyExchange().authenticated().and().oauth2Login().and().build();
In order to add a route for a websocket based micro-service I have
Configured my application as per Spring cloud gateway documentation
- id: sample_service_web_socket_handshake_url
uri: lb:ws://sample-service
predicates:
- Path=/notification-service-ws/**
above notification-service-ws is the handshake url of websocket-service
upon accessing this websocket endpoint directly( without spring-cloud-gateway ) session has been connected with no issue
but upon trying to connect using spring-cloud-gateway the gateway gives following warning log
2020-01-09 10:44:02.923 WARN 5155 --- [-server-epoll-5] .a.w.r.e.DefaultErrorWebExceptionHandler : Failed to handle request [GET http://192.168.10.44:4260/notification-service-ws]: Response status 400 with reason "Invalid 'Upgrade' header: {Sec-WebSocket-Version=[13], Sec-WebSocket-Key=[0EJxcMdBmRhZ5suS/INKnQ==], Sec-WebSocket-Extensions=[permessage-deflate; client_max_window_bits], Host=[192.168.10.44:4260]}"
I have verified no HTTP request is being sent to websocket service
Issue resolved after adding following properties to spring-cloud-gateway application.yml file:
spring:
application:
name: burraq-api-gateway
profiles:
active: dev
cloud:
gateway:
filter:
remove-non-proxy-headers:
headers:
- Proxy-Authenticate
- Proxy-Authorization
- Keep-Alive
- TE
- Trailer
- Transfer-Encoding
This issue occurred because spring cloud gateway by default request headers as mentioned here
Has methods secure Config Server by oauth2 token ?
I plan to implement spring cloud config-server by oauth2 token,so client-server can fetch property by :
cloud:
config:
uri: http://user:password#localhost:8888
Is it feasible ?
but ... i met some problems .
I start a demo https://github.com/keryhu/spring-oauth2-config-server.git
It contains four services :
1 : eureka : start first,and can implement service register and discovery,it has no oauth2 enviroment.
2 : auth-server : JWT OAuth2 server configuration ,start secondly.
#SessionAttributes("authorizationRequest")
#EnableResourceServer
#EnableDiscoveryClient
and inmemory user :
security:
user:
password: password
3: config-server : start thirdly
#EnableDiscoveryClient
#EnableConfigServer
#EnableResourceServer
and in application.yml :
spring:
cloud:
config:
server:
git:
uri: https://github.com/keryhu/cloud-config
security:
oauth2:
resource:
jwt:
keyValue: |
-----BEGIN PUBLIC KEY-----
....
-----END PUBLIC KEY-----
4: pc-gateway : is a client-server,also a ui server. start lastly
When i test the secured uri: http://localhost:8080/hello, the page was redirected to
http://localhost:9999/uua/login
After entering "user:password",it redirects back
http://localhost:8080/hello
So i think the oauth-server and oauth-client is fine.
but.. i also set the following configuration in bootstrap.yml
cloud:
config:
uri: http://user:password#localhost:8888
When starting pc-gateway service, Fetching config from server has 401 Unauthorized errors :
INFO 954 --- [main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
WARN 954 --- [main] c.c.c.ConfigServicePropertySourceLocator : Could not locate PropertySource: 401 Unauthorized
Need help ! thanks !