Spring-security-oauth: How can an @EnableOAuth2Sso client use the password grant_type?

Created on 10 Mar 2016  路  14Comments  路  Source: spring-projects/spring-security-oauth

I'm trying to figure out a way to setup an @EnableOauth2Sso client to use the password grant_type. This would make sense in the scenario where the client app is a trusted one (let's say it is on the same realm as the resource server).

In that case, the user doesn't have to go through the extra step of granting the application access to his resources.

Any thoughts are highly appreciated.

stackoverflow

Most helpful comment

My input is the same as above. You don't need password grant in a browser app. Use auto approve to skip the redirect and approval.

All 14 comments

If you don't like making your users click the extra "approve" button just make the client an auto approve, but please don't use password grant.

Although OpenID Connect has not been mentioned, in my mind auto approval is a form of previous administrative consent. This is the relevant section of the OpenID Connect Core 1.0 spec:

_3.1.2.4. Authorization Server Obtains End-User Consent/Authorization_

_Once the End-User is authenticated, the Authorization Server MUST obtain an authorization decision before releasing information to the Relying Party. When permitted by the request parameters used, this MAY be done through an interactive dialogue with the End-User that makes it clear what is being consented to or by establishing consent via conditions for processing the request or other means (for example, via previous administrative consent). Sections 2 and 5.3 describe information release mechanisms._

I guess that's accurate, but it describes quite well a feature of Spring OAuth, so there's no need to have a formal implementation of OIDC to get auto approvals.

@dsyer I have same requirement.
Both OAuth server and the client app are in the same domain.

  • Client app for organization's internal end users.
  • Specially OAuth is for 3rd party clients (A future plan)

Therefore I want to provide a custom login form (_password grant_) in the client application to provide a better user experience, rather than redirecting my own end users to my own OAuth server within the organization.
Since the client is 100% trusted, I think there is no issue.
But it seems OAuth2RestTemplate does not provide that support.

Also I may be implementing _implicit_ grant access with JS client, which is often labeling as

less secure

than above or may be doing a customization to the OAuth2RestTemplate to get going with password grant.

Appreciate any input.

My input is the same as above. You don't need password grant in a browser app. Use auto approve to skip the redirect and approval.

Scenario I'm struggling with:
If I'm implementing a first party client-app which talks to my API, then why would my client-app redirecting users to another place(Ex: My Authorization Server) when they just want to enter user name and password to log in?
Since I'm the provider of API and the client-app everybody trusts each other.

Am I asking or trying to do something which is not appropriate orwrong in terms of security?
or
Does OAuth2RestTemplate not support password grant ?

Am I asking or trying to do something which is not appropriate or wrong

It's more subtle than that. I'm recommending auth code as a better user experience, and as a way to give you more flexibility (when you want more than just password-based authentication for instance). If you trust all the parties, there is no security issue (but it pays to be cautious as well).

Does OAuth2RestTemplate not support password grant ?

Yes, of course (did you try it?).

@sura2k, if you really want the password grant for your client, this is how configure the OauthRestTemplate:

The problem with the password grant type is that the user's credentials are passed between systems with every request and this might expose you to some security threats even if the client is on the same realm as the API.

    @Bean
    @Qualifier("myRestTemplate")
    public OAuth2RestOperations restTemplate(@Value("${oauth.token}") String tokenUrl) {

        OAuth2RestTemplate template = new OAuth2RestTemplate(fullAccessresourceDetails(tokenUrl), new DefaultOAuth2ClientContext(
                new DefaultAccessTokenRequest()));
        template.setAccessTokenProvider(userAccessTokenProvider());
        return template;
    }

    @Bean
    public AccessTokenProvider userAccessTokenProvider() {
        ResourceOwnerPasswordAccessTokenProvider accessTokenProvider = new ResourceOwnerPasswordAccessTokenProvider();
        return accessTokenProvider;
    }

    @Bean
    public OAuth2ProtectedResourceDetails fullAccessresourceDetails(String tokenUrl) {
        ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
        resource.setAccessTokenUri(tokenUrl);
        resource.setClientId("user_member");
        resource.setGrantType("password");
        resource.setScope(ArraysList.asList(new String[]{"openid"}));
        resource.setUsername("uu");
        resource.setPassword("pp");
        return resource;
    }

@nucatus your use of a @Bean to declare the OAuth2ProtectedResourceDetails and the OAuth2RestTemplate is probably not a brilliant plan (it's hard coding a single set of user credentials). Most people want to create these things on the fly, or use a @Scope("request") bean so you can mutate it in a thread-bound way (prototype scope would also work, with an ObjectFactory for instance).

Yes, @dsyer, I know about all those shortcomings of the given implementation. Thanks for the hint with the prototype scope. Didn't know about it.

I made available this code only for demo purposes, to show how OAuth2RestTemplate can be configured to use the password grant.

but it pays to be cautious as well

Yes, agree

did you try it?

Yes and No.
Tried to configure, but I seems it only works for single user/password (hard coded) (Just like the sample of @nacatus)
I checked the source and that is the way I found as the default - may be I'm wrong.

I hesitated to use @Scope("request") or prototype bean, because,

  1. Almost in all cases the beans we declare are singleton
  2. I thought if there is no default configuration to create user session/token on the fly, there is something I do not know.

With above inputs, may be @Scope("session") fit in to my case, and I should try this.

It works with @Scope("session") scope.
Token expiration is already handled by the OAuth2RestTemplate

@dsyer Following helped a ton.

Most people want to create these things on the fly, or use a @Scope("request") bean so you can mutate it in a thread-bound way (prototype scope would also work, with an ObjectFactory for instance)

@sura2k Do you have an example on how I can pass in the Username and Password to the Session scoped ResourceOwnerPasswordResourceDetails ?

@Rocks360 Sorry I don't have any. Initially I didn't understand what dsyer explained, but later I realized that it is not an ideal way to go with. I'm not sure whether the framework upgraded to do so without a hassle.

Was this page helpful?
0 / 5 - 0 ratings