Announcement Announcement Module
Collapse
No announcement yet.
Understanding roles/authorities in relation to users, urls, and clients Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Understanding roles/authorities in relation to users, urls, and clients

    I am not sure I understand how roles (aka authorities) work in relation to users, urls, and clients

    I have a custom query for testing on my jdbc-user-server as follows

    Code:
    <security:jdbc-user-service id="jdbcUserService" data-source-ref="dataSource"
    				users-by-username-query="
                        SELECT  username, password, user_status = 'ACTIVE' as enabled
                        FROM    users
                        WHERE   username = ?"
    				authorities-by-username-query="
                        SELECT  u.username, 'ROLE_USER' as authority
                        FROM    users u
                        JOIN    roles r USING (role_id)
                        WHERE   u.username = ?" />
    So every user has a role of ROLE_USER. My client has an value of 'ROLE_FOO' in the 'authorities' column in the oauth_client_details table. I am testing using the implicit flow right now.

    Which of these is correct (or are both wrong)?
    1. Since my user has ROLE_USER and my client has ROLE_FOO, I should not even be able to get a token for that client. My problem is that right now I can and that seems wrong to me.
    2. Any authenticated user can get a token for any client regardless of role, but after that the URLs I can hit are restricted by client role. Thinking about this now this doesn't even make sense as why would it take the client role over the user role. I guess maybe I am missing the understand of how these two roles complement each other. Where can I find a good explanation of this?

  • #2
    I agree that the names can be confusing, and perhaps it doesn't help that the client has a field called "authorities" because there is no automatic connection between that and a user role (as defined in your user authentication token as "authorities"). The access decision on a protected resources is totally up to you, so you can make it as simple as you like - you can deny access based on the client's authorities, the user's, or neither. An example of using neither is to base the decision on scope of the token, which is actually more natural for OAuth2 resources, but adds a layer on top of normal Spring Security decisions (e.g. using ScopeVoter). If you do that then the client and user authorities can (and should) still be used at token minting time to decide on a scope for the token (such a feature is not built in to Spring OAuth2, but it's easy to add one if you have opinions about how it should be done using a UserApprovalHandler and/or AuthorizationRequestManager).

    Comment


    • #3
      I think I follow what you are saying. At the end of the day, there are essentially 3 different things that can be used to secure a resource: a users authorities (standard spring security), a clients authorities (spring oauth), and the OAuth scope (spring oauth). The users authorities should automatically work to protect a URL, but that is pretty much it. To make a users authorities work with a clients authorities is up to me. Is it true then that the default implementation in SpringSec OAuth is that a clients authorities doesn't do anything? i.e. I can set it to ROLE_ADMIN, login with a user ROLE_USER, and still get a token. For later requests to the resource server with that token, that is when ROLE_USER comes into play? I still feel I am missing something

      After looking through the code I think I know what I have to do. Can you confirm for the following use case that the way I would have to make sure that the authenticated users authorities match up to the clients authorities is in the UserApprovalHandler:
      * User goes to website and logs in normally. User has ROLE_USER authority
      * Now user hits OAuth URL: http://localhost:8080/auth-webapp/oa...n&state=foobar
      * Since user is already authenticated, I cannot use my custom AuthenticationProvider because authenticate() is never called as they are already authenticated
      * So... have to use the custom UserApprovalHandler (that I am already using)

      Assuming that is the best spot, do you happen to know where some existing code in spring security is that I can use to compare authorities? I don't want to re-invent this wheel if I don't have to

      Thanks so much!! Great module!
      /Collin

      Comment


      • #4
        Originally posted by cadiolis View Post
        I can set it to ROLE_ADMIN, login with a user ROLE_USER, and still get a token. For later requests to the resource server with that token, that is when ROLE_USER comes into play? I still feel I am missing something
        Not really, it's just that there is no connection in principle between user and client authorities. They are just data made available to you to compute scopes and access decisions.

        do you happen to know where some existing code in spring security is that I can use to compare authorities? I don't want to re-invent this wheel if I don't have to
        Not in Spring Security per se. But we did a lot of work on a specific model of authorities and scopes in Cloud Foundry. What we chose to do there was to use the token scope for access decisions and let the auth server compute the scopes based on client and user meta-data (including authorities). It might not match what you want exactly but you can see it here: https://github.com/cloudfoundry/uaa/...stManager.java.

        Comment


        • #5
          Still working through the details of this. Perhaps I can ask a simpler, more direct question.

          Imagine I have two users with two different roles: ROLE_FOO and ROLE_BAR. Now I have an OAuth client with a role/authority ROLE_FOO. What I want to do is prevent a user with ROLE_BAR from even being able to get a token for the client with ROLE_FOO. Where should I hook in to do something like that?

          My current thoughts are
          * Custom approval handler isApproved()
          * Custom approval handler updateBeforeApproval
          * I was also looking at DefaultAuthorizationRequestManager, but it seems that does not have access to both the users authorities and clients authorities
          * Forgot about roles, use scopes and a ScopeVoter

          Comment


          • #6
            AuthorizationRequestManager is the right strategy I think. You have access to the client id and to the user authentication (through the normal Spring SecurityContext) if there is one. The example I gave uses both.

            If the rule you need is simple and generic we could put it in the framework as an alternative to DefaultAuthorizationRequestManager.

            Comment

            Working...
            X