Announcement Announcement Module
Collapse
No announcement yet.
Identify end user from bearer token Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Identify end user from bearer token

    I have a webservice that is secured using OAuth 2.0. I have a website client where users log in. Upon logging the user in the website uses the password grant to obtain an access token from the webservice.
    Subsequent requests are made to the webservice with the access token.

    The webservice needs to know some end user id to be able to carry out some of the requests. So my questions are:
    1. Does the bearer access token have any such information that would enable the webservice to find out who the end user is that the website is acting on behalf of?


    2. If not, what is the best way to add/store additional end user information into the bearer token when it is issued by the webservice. This way the webservice can use it when servicing resource requests. In terms of the oauth configuration where would this be done?


    Please provide as much info as possible as I'm finding Spring OAuth support/configuration a huge learning curve.

  • #2
    I understand one option is to add the additional info in the access token value. This makes sense to me. How do I do this?

    The following is the token store config I am using
    Code:
    <bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
        <bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
            <property name="tokenStore" ref="tokenStore" />
            <property name="supportRefreshToken" value="true" />
            <property name="clientDetailsService" ref="clientDetails" />
        </bean>
    How do I plug in my custom info to the generated token values?

    Comment


    • #3
      The spec doesn't say what information is in a token. Normally you will find an OAuth2Authentication the Spring SecurityContext if you use the <resource-server/> filter and that would contain the user's authentication details. Because the spec is intentionally open you can expect to find plenty of other information in tokens if your auth server decides to put it there. As your second post suggests, additional information can be added by the auth server (e.g. using a TokenEnhancer).

      Comment


      • #4
        Where is the TokenEnhancer plugged in? In other words where does it belong in the oauth config?

        Comment


        • #5
          Got it! DefaultTokenServices

          Thanks

          Comment


          • #6
            Hi, This appears to be a liitle more complex then initially anticipated. I have implemented my own TokenEnhancer but there arent any modifiers on the OAuth2AccessToken so I cant do anything! I just want to modify the access token that has been created and add a little extra info through whatever means.

            What is the simplest way to do this?

            Comment


            • #7
              You can do anything you want. Just create a new token, modify it and return it. DefaultOAuth2AccessToken has a copy constructor and setters for all its properties.

              Comment


              • #8
                I was wondering about the first part. How do I retrieve userid after doing a bearer authentication. One way is to retrieve it from the Principal Object as depicted below. Controller initialiser is as follows.

                <bean id="myNameController" class="com.company.spring.oauth.controllers.MyName Controller"/>

                Sample controller Code

                @Controller
                public class MyNameController {

                @RequestMapping("/users/myname")
                @ResponseBody
                public String getMyDetails(Principal principal){
                return
                "<myname>\n" +
                " <username userid="+principal.getName()+"/>\n" +
                "</myname>";
                }
                }


                But doing a OAuth2Authentication.getName() makes it PLatform neutral (we are developing this as a reusable component & its upto the consumer to Plugin their Platform specific Principal handler library. Whats the best way to do this?

                Comment


                • #9
                  Sorry, I didn't really understand the question. You don't like using Principal.getName()? Or OAuth2Authentication isn'tworking in your use case?

                  Comment


                  • #10
                    Originally posted by Dave Syer View Post
                    Sorry, I didn't really understand the question. You don't like using Principal.getName()? Or OAuth2Authentication isn'tworking in your use case?
                    Thanks for getting back Dave. I should have probably set the context a bit more.

                    The above URL requires bearer (token) authentication and I dont like using Principal.getName() to retrieve the username. Was trying to understand how to expose in OAuth2Authentication within the Controller I showed above so that I have access to User's details including the userid.

                    I didnt do due diligence when I asked the question, but its working for me.

                    <bean id="tokenStore" class="org.springframework.security.oauth2.provide r.token.InMemoryTokenStore" />
                    <bean id="myNameController" class="com.company.spring.oauth.controllers.MyName Controller">
                    <property name="tokenStore" ref="tokenStore" />
                    </bean>


                    Sample controller Code

                    @Controller
                    public class MyNameController {

                    private TokenStore tokenStore;

                    public TokenStore getTokenStore() {
                    return tokenStore;
                    }

                    public void setTokenStore(TokenStore tokenStore) {
                    this.tokenStore = tokenStore;
                    }

                    @RequestMapping("/users/myname")
                    @ResponseBody
                    public String getMyDetails(@RequestHeader("Authorization") String bearer){
                    return
                    "<myname>\n" +
                    " <username userid="+tokenStore.readAuthentication(bearer.spli t(" ")[1]).getName()+"/>\n" +
                    "</myname>";
                    }
                    }

                    Comment


                    • #11
                      Fine if that works, but you should consider TokenStore to be an internal detail of the implementation of DefaultTokenServices (and not use it directly if possible). If you like decoding the token twice (once in the authentication filter and once in the controller) you can inject a ResourceServerTokenServices into your controller, and that would be preferable. Personally, I would prefer to use the Principal (it should be an instance of OAuth2Authentication if the correct filter is in place).

                      Comment


                      • #12
                        Originally posted by Dave Syer View Post
                        I would prefer to use the Principal (it should be an instance of OAuth2Authentication if the correct filter is in place).
                        Interested with the above suggestion. I am fairly new to Spring, but let me try that.

                        Cheers

                        Comment

                        Working...
                        X