Thanks, and Resource Owner "password" grant
This is a wonderful demonstration project. Thanks for putting it together.
I'm trying out the various grants and permissions and learning about the Spring OAuth implementation. That's all great.
I decided to see if I could implement "Password Grant", but haven't had much luck. Here is the essence of what i've tried. (I've tried many variations too :-)
- I created a new oauth_client_details record like this.
INSERT INTO oauth_client_details (client_id, resource_ids, client_secret, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove) VALUES ('password-client', 'todo-services', 'password-client-secret', 'read,write', 'client_credentials, refresh_token, password', '', 'ROLE_ADMIN', 7200, 0, NULL, 'false');
- I rebuilt, restarted, etc. Then I tried a curl command.
curl -X POST -u password-client:password-client-secret localhost:8081/oauth/token?grant_type=password -d 'username=user&password=user'
I get "Unsupported grant type: password"
If I try this
curl -X POST -u password-client:password-client-secret localhost:8081/oauth/token?grant_type=client_credentials
I get an access token for the client. This second test tells me that the "password-client" is found, and that the "authorized_grant_types" includes "client_credentials" and that it is reading it from the database.
===
Did you ever make more progress on implementing "password" grant? I'll be investigating and if I solve it I will report it back here.
Thanks, Tom
I think I solved this. The big mistake I had was an extra space after the commas in the authorized_grant_types column.
- In AuthorizationServerConfigurerAdapter inject an authenticationManager
import org.springframework.security.authentication.AuthenticationManager;
public class OAuthConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
...
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
endpoints
.approvalStore(approvalStore())
.authorizationCodeServices(authorizationCodeServices())
.tokenStore(tokenStore());
}
- Add the client definition (note - no spaces after the commas. VERY IMPORTANT!)
INSERT INTO oauth_client_details
(client_id, resource_ids, client_secret, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove)
VALUES
('password-client', 'todo-services', 'password-client-secret', 'read,write', 'client_credentials,refresh_token,password', '', 'ROLE_ADMIN', 7200, 0, NULL, 'false');
- Test is
$ curl -s -u password-client:password-client-secret -X POST localhost:8081/oauth/token -d 'grant_type=password&username=user&password=user'
{"access_token":"0449a561-7a2e-4a0f-9fcc-18f59479b643","token_type":"bearer","refresh_token":"79862523-338a-442e-8031-63339eaa888d","expires_in":6145,"scope":"read write"}
Hey! Sorry for the late answer (Easter with family...)! Glad that the project helps you.
Thanks for your detailed report! I actually did not yet try the password grant yet. Seems like you got it to work. I'd be interested why the authentication manager has to be set explicitly on the endpoints! If I find the time I'll look into it soon and try to write an example client that showcases this flow.
I also already started to migrate to Spring Boot 2 (although I would keep the 1.x version on a branch since not everyone has the flexibility to do that) which has some interesting changes.
Regarding why the authentication manager has to be set explicitly:
From what I read, 'password' authentication is normally deemed dangerous and to be avoided unless you are sure you can trust the client (e.g. - when the client and server are from the same company). As a result, Spring Security disables it by default, and to make it available you have to set the authenticationManager.
(I think they made this more mysterious than it needed to be :-)