Im using spring cloud, in the following layout:
registry server
oauth2 server
zuul proxy
a simple crud microservice
On the crud service, Im trying to authenticate against my oauth2 server using
security:
oauth2:
resource:
loadBalanced: true
userInfoUri: http://auth_service/users/current
I can fetch the token from the oauthserver, but when I use the token to request the crud service I got
2017-01-07 10:46:02.638 INFO 16186 --- [nio-9001-exec-4] o.s.b.a.s.o.r.UserInfoTokenServices : Getting user info from: http://auth_service/users/current
2017-01-07 10:46:02.639 INFO 16186 --- [nio-9001-exec-4] o.s.b.a.s.o.r.UserInfoTokenServices : Could not fetch user details: class java.lang.NullPointerException, null
If I change the oauth client to hit the oauth server without the loadBalanced option, it works fine
security:
oauth2:
resource:
userInfoUri: http://localhost:4444/auth_service/users/current #through zuul proxy
I tried to debug, but this nullpointer exception occurs very deep on rest template implementations. Please, I need some help here.
I have something like this in mine try this configuration to see if it might work.
zuul:
routes:
user-service:
path: /user/**
stripPrefix: false
security:
# Disable Spring Boot basic authentication
basic:
enabled: false
oauth2:
client:
accessTokenUri: http://<zuulHostname>/user/oauth/token
userAuthorizationUri: http://<zuulHostname>/user/oauth/authorize
...
Kindly check the token that you are getting does it have complete information about the user. Most importantly the userName. It should be set when you generate the token. You can see what information is in the token by parsing the token here
Related
i'm using keycloak (v. 10) for make authentication for existing spring (no boot library) application. I'am using the java-adapter from keycloak documentation i added the suggested configuration on my spring security config.
This is my keycloak.json file:
{
"realm": "cnp-server",
"auth-server-url": "http://localhost:8081/auth/",
"ssl-required": "external",
"resource": "cnpserver-client",
"public-client": true,
"confidential-port": 0
}
On this screen the configuration of keycloak client (is running on docker):
When i try to access to application, the browser make a redirection to:
http://localhost:8081/auth/realms/cnp-server/protocol/openid-connect/auth?response_type=code&client_id=cnpserver-client&redirect_uri=http%3A%2F%2Flocalhost%3A8088%2Fcnp_server_web_war%2Fsso%2Flogin&state=73ee7ebe-1949-4e94-9349-f3760f37bb4a&login=true&scope=openid
When i key the access credentials on prompt box, somethings going wrong; on Keycloak log:
WARN [org.keycloak.events] (default task-63) type=CODE_TO_TOKEN_ERROR, realmId=cnp-server, clientId=cnpserver-client, userId=null, ipAddress=192.168.32.1, error=invalid_code, grant_type=authorization_code, code_id=7972a766-f9be-4907-85a7-69e6d5d50cbf, client_auth_method=client-secret
On spring application log:
ERROR org.keycloak.adapters.OAuthRequestAuthenticator [OAuthRequestAuthenticator.java:337] - failed to turn code into token
ERROR org.keycloak.adapters.OAuthRequestAuthenticator [OAuthRequestAuthenticator.java:338] - status from server: 400
ERROR org.keycloak.adapters.OAuthRequestAuthenticator [OAuthRequestAuthenticator.java:340] - {"error":"invalid_grant","error_description":"Code not valid"}
It's seems similar to this topic, but i don't make any personal configuration on redirect-uri (and i don't know how i can change that).
Thanks
Micronaut is used in one of my projects. I am enabling JWT security feature of micronaut with built in login, logout controllers. But when I hit /login endpoint, it gives me below error:
Access to XMLHttpRequest at 'micronaut-login-endpoint' from origin 'front-end-enpdpoint' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Snippet from application.yml:
micronaut:
application:
name: app-name
server:
port: *port*
cors:
enabled: true
configurations:
web:
allowedOrigins:
- *front-end-enpdpoint*
allowedHeaders:
- Content-Type
allowedMethods:
- POST
- GET
- OPTIONS
security:
enabled: true
endpoints:
login:
enabled: true
logout:
enabled: true
oauth:
enabled: true
token:
enabled: true
jwt:
enabled: true
Can someone help me with this issue?
Can someone from the micronaut core community like #Jeff-Scott-Brown please help me?
I recently faced this issue and I was able to tackle this using this issue thread.
So, following this mdn CORS article. I found out there are two types of CORS requests, simple and preflighted. In case of auth the Authorization header is modified which requires preflighted requests. In preflighted, an http OPTIONS(http method) request is made to the server to confirm its identity. Now micronaut does not have an options end point which can be tackle by just creating the OPTIONS controller as mentioned in the github issue.
i have developed the micro service application, in that application there is a service call user service which is running on port 8281. This service handle the authentications. when i test the service in local environment this is worked fine. But if i call this service using zuul api gateway this is not working. following property in the application.yml file is use to get the redirect url in the local environment. This is worked fine.
security:
oauth2:
client:
registration:
google:
redirectUri: "http://localhost:8281/oauth2/callback/google"
But if i change this property as follow for connect with zuul api gateway.
security:
oauth2:
client:
registration:
google:
redirectUri: "http://localhost:8080/api/user/oauth2/callback/google"
This is not working and is throw this error message [authorization_request_not_found]. localhost:8080 is the zuul api gateway. zuul has configure to forward request to user service like this.
zuul:
prefix: /api
routes:
auth-service:
path: /user/**
serviceId: USER-SERVICE
stripPrefix: true
sensitiveHeaders: Cookie,Set-Cookie
so why this error is thrown ?
I'm doing a microservice project usign JHipster, i'm using Consul for Service Discovery and JWT for authentication, but here's my question:
For other clients to access my microservices, they need to authenticate by passing a JSON with the credentials via POST to the gateway and finally get de id_token. But how the gateway authenticate within the services? The gateway do something similar to what we did when there's external client? Or there's something to do with de Service Discovery?
I found this in the application-dev.yml:
security:
authentication:
jwt:
secret: my-secret-token-to-change-in-production
My guess is that the both microservice and the gateway share a common secret key, but i didn't found this key, only this section on the yml.
You found it, the secret key is used by the gateway to sign the token when it generates it, same key is used by microservices to verify signature. The gateway is a Zuul proxy that passes the authentication header to proxified microservices.
This property in Consul is available to all these apps through a local Consul agent at port 8500, see Spring Cloud Consul.
I am currently developing a application based on a micro service architecture. We use a API-Gateway implemented using Spring Cloud Netfix's Zuul Server to route the requests to our micro services.
To realize single sign on for all our services I am currently working on an OAuth2 server set up using Spring Cloud Security. The server is basically just copy and past of the implementation in Dave Syer's Repo: https://github.com/dsyer/spring-security-angular/tree/master/oauth2/authserver
The main difference is that I want to route the requests to my OAuth server through the Zuul Proxy. This way I will not have to directly expose my OAuth Server and can add and remove Login Server dynamically.
The problem is I do not seam to understand how to correctly configure this setup. When I try to access a protected resource on the OAuth server I am forwarded to the login page. This of course is as expected. But I can not figure out how to set the hostname and port used when forwarding. What I want to happen is the server to forward to an endpoint on the Zuul server that will get proxied back to the OAuth server. (The Zuul API-Gateway should be the only server the client ever talks to. Everything else will be hidden.)
As it is the host and port are read from the HttpServletRequest in LoginUrlAuthenticationEntryPoint. But the request the server sees is the request send by the Zuul proxy. So I am forwarded to an internal IP not an endpoint on the proxy.
I tried to set the URL of the login page in WebSecurityConfigurerAdapter.configure(HttpSecurity) to the absolut URL of my Zuul Proxy. But this just caused my application to complain about too many redirects. (Might have caused a loop there.)
What would be the best way to set this up?
Do I have to implement some kind of own forwarding strategy by overriding a bean?
Is there a configuration option I am missing?
Is my idea itself wrong? (In his answer to How to avoid redirect to another host with Zuul? Dave Syer says you would not normally proxy this but does not explain why.)
Update: POC can be found here https://github.com/kakawait/uaa-behind-zuul-sample
Did you try following setup (on zuul server):
zuul:
routes:
uaa-service:
path: /uaa/**
stripPrefix: false
security:
# Disable Spring Boot basic authentication
basic:
enabled: false
oauth2:
sso:
loginPath: /login
client:
accessTokenUri: https://<zuul hostname>/uaa/oauth/token
userAuthorizationUri: https://<zuul hostname>/uaa/oauth/authorize
...
Basically it works on my project only thing I have to do is to disable CSRF protection on /uaa/oauth/token route.
Auth server should be on
server:
# Use different context-path to avoid session cookie overlapping
context-path: /uaa
Tested using Spring-Cloud.Brixton.M3
Thank to #thomas-letsch, you should tweak you security like following (sample)
public void configure(HttpSecurity http) throws Exception {
http.logout().and()
.antMatcher("/**").authorizeRequests()
.antMatchers("/index.html", "/home.html", "/", "/uaa/oauth/**").permitAll()
.anyRequest().authenticated().and()
.csrf().csrfTokenRepository(getCSRFTokenRepository()).ignoringAntMatchers("/uaa/oauth/token").and()
.addFilterAfter(createCSRFHeaderFilter(), CsrfFilter.class);
}
As far as I understand your question, spring-cloud-security (for the EnableOauth2Sso part) and spring-cloud (for zuul), this is not possible to proxy the calls to the authorization server using zuul.
The main reason being that spring-cloud-security secures the Gateway independently (and before accounting for) Zuul routing's logic.
Which means that the (sample configuration from Dave Syer's OAuth2 example) spring.oauth2.client.* configuration
spring:
oauth2:
client:
accessTokenUri: http://localhost:9999/uaa/oauth/token
userAuthorizationUri: http://localhost:9999/uaa/oauth/authorize
clientId: acme
clientSecret: acmesecret
is considered before allowing any access to the Zuul's routes zuul.routes.*
Moreover this setup enables the client agent to store two Cookies: one for the Gateway and one for the Authorization Server.
I hope this helps.