kakawait / uaa-behind-zuul-sample

Spring AuthorizationServer load balanced behind Zuul
320 stars 156 forks source link

Couple of small questions (or maybe suggestions) #24

Closed srinivas-os closed 7 years ago

srinivas-os commented 7 years ago

Hi,

I am new to spring boot and spring security, and trying to build an app protected with oauth2 + zuul. I am using your wonderful sample code for learning how to build my own. So first of all, thanks a lot for putting this up!

My questions:

a) In resource server app (dummy-service), you've used EnableResourceServer. The documentation for this states

In order to use this filter you must EnableWebSecurity somewhere in your application, either in the same place as you use this annotation, or somewhere else.

So is this required in your app, and if so how does it work fine without this?

b) The controller method secret, which is protected by PreAuthorize, seems to be accessible for user without admin role, at least on my box. After doing some digging, it looks like we need to add the below to DummyServiceApplication to make it work:

@EnableGlobalMethodSecurity(prePostEnabled = true)

Is this correct?

c) As I understand, the decoding/validation of the auth token happens locally in the resource server. This would mean that resource server is not aware of any changes in user details (for eg: password), since it doesn't contact auth server after receiving token. Is this correct? I am not pointing this out as an issue (I understand it is a demo app), but just thought I'd validate my understanding.

kakawait commented 7 years ago

Hi @srinivas-os thank you for your feedback.

About a) I have no idea in fact. I think documentation ask us to put @EnableWebSecurity in order to disable default spring boot security, cf https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-security

To switch off the default web application security configuration completely you can add a bean with @EnableWebSecurity (this does not disable the authentication manager configuration or Actuator’s security).

Because that can (may) cause some conflict between @EnableResourceServer and default spring boot security which enable basic auth.

But why it works? I think is because dummy service is using following configuration

security:
  basic:
    enabled: false

Else it's a good question, I will try to find time to ask that question to Spring's guys on Gitter channel.


About b), you're totally right. It was just a missing from my part. Same thing if you want to use other security annotations like @Role or @Secured you need to active it.

I will fix it asap (or you can propose PR).


About c) yes in that sample, I would present stateless decoding/validation using JWT+OpenID access token. So yes resource server can decode (is just base64) and validate (most important thing) since RSA pubkey is present on resource server https://github.com/kakawait/uaa-behind-zuul-sample/blob/master/dummy-service/src/main/resources/application.yml#L25

However this access token is only use for server-to-server communication, thus (I have to test to confirm) if user details changes that will be automatically updated since api gateway will fetch a new access token for the given user session.

But as I explained on first paragraph that stateless choice can be changed, in fact there is 3 possibles modes:

  1. resource server can decode/validate JWT+OpenID access token by itself since RSA pubkey is installed (current version)
  2. resource server can decode/validate JWT+OpenID access token by itself but RSA pubkey is not installed and must be fetched from the authorization server
  3. resource server cannot decode/validate JWT+OpenID access token and must be validated through authorization server

As you can understand first solution is most performante one since no communications is needed, but can be complicate to manage in large environment (since install RSA Pubkey needs some organization, and think about when RSA pair should be updated...).

Second version is an answer to above drawback.

And third version is simplest version since resource server does not need to implement JWT, and everything is delegated to authorization server but each request leads to request to authorization server

PS: user password is never shared, password stay on authorization server / uaa

srinivas-os commented 7 years ago

Thanks for the quick response!

"if user details changes that will be automatically updated since api gateway will fetch a new access token for the given user session."

I understood everything in your reply except above. In case of approach no. 1, how/when would this happen?

I watched the sequence of requests in wireshark, and once initial login and authorization gets completed, there are no further requests made to the auth server from gateway or resource server. Just browser -> zuul -> resource server (and reverse path for response). Perhaps it would happen when the token gets expired - is that what you mean?

kakawait commented 7 years ago

As I said

I have to test to confirm

I may wrong, api gateway may keep token in cache (or in session) somewhere while access token is valid (regarding expiration date).

In that case, yes, information will be unfresh. But I think the only way to resolve is to validate access token each time through authorization server to retrieve fresh user details.


After is kind of compromise, like in cache strategy, between performance and freshness :)


I didn't work on that sample for few months that why I'm not sure :)

srinivas-os commented 7 years ago

Thanks! I got all the info now. I am closing it.