clouway / oauth2-server

OAuth2 Server Library
Other
47 stars 22 forks source link

doc: sample docs for using of the library #82

Open mgenov opened 6 years ago

mgenov commented 6 years ago

We've got this on email:

Hello!

I would like to create a new oauth2 server, and I have found your
oauth2-server library on gitlab. I was able to compile the example-app
project, but I'm not sure how to use it. I don't see the endpoints. For
example, http://127.0.0.1:8888/oauth2-example-app/login.html or /oauth
or /oauth/login etc. All of them give me 404 not found.

Do you have a getting started documentation for this library?
mgenov commented 6 years ago

The usage of the library is relatively simple. You just have to extend the OAuth2Servlet which you have to bind to something like /o/oauth2/v1/* :

The urls:

/o/oauth2/v1/auth /o/oauth2/v1/token /o/oauth2/v1/userInfo?access_token=access token

Here is an example servlet:

class OAuth2SupportServlet @Inject constructor(private val tokens: Tokens,
                                               private val jwtKeyStore: JwtKeyStore,
                                               private val keyStore: KeyStore,
                                               private val identityFinder: IdentityFinder,
                                               private val resourceOwnerIdentityFinder: ResourceOwnerIdentityFinder,
                                               private val clientFinder: ClientFinder,
                                               private val clientAuthorizationRepository: ClientAuthorizationRepository) : OAuth2Servlet() {
  override fun config(): OAuth2Config {
    return OAuth2Config.newConfig()
            .tokens(tokens)
            .jwtKeyStore(jwtKeyStore)
            .keyStore(keyStore)
            .identityFinder(identityFinder)
            .resourceOwnerIdentityFinder(resourceOwnerIdentityFinder)
            .clientAuthorizationRepository(clientAuthorizationRepository)
            .clientFinder(clientFinder)
            .loginPageUrl("/ServiceLogin?continue=")
            .build()
  }
}

The implementations of these interfaces will provide the information which is required for the auth, token and userInfo endpoints.

nagylzs commented 6 years ago

Hello! Here is the first question The ClientAuthorizationRepository was changed after version 1.0.2. The authorize method was changed from this:

Optional<Authorization> authorize(Client client, String identityId, Set<String> scopes, String responseType);

into this:

Optional<Authorization> authorize(AuthorizationRequest authorizationRequest);

I started to create my own server using the example app (checked out from git), but I got this error because the 1.0.2 version downloaded from maven still has the old interface.

Are you going to release these changes (1.0.3) anytime soon? Thanks.

VasilMitovClouway commented 6 years ago

We are updating the README so it will be easier for new users to start using our library and adding a few improvements to the error responses with description added to them. Expect a new release soon.

VasilMitovClouway commented 6 years ago

On the next release our library will support PKCE for the authorization flow More on PKCE here: https://tools.ietf.org/html/rfc7636

mgenov commented 6 years ago

@nagylzs late this night or tomorrow current master will be bumped into v1.0.3

nagylzs commented 6 years ago

Fabolous. 👍

nagylzs commented 6 years ago

I'm almost ready with my first test server. Most of it was just copied out from the example app, and I'm going to add the storage implementations later.

I' don't know how to start the authorization process. I have tried the login endpoint:

http://127.0.0.1:8080/r/oauth/login?response_type=code&client_id=a77a6523-61d6-4a22-aaa0-dfa175741859&redirect_uri=http%3A%2F%2F127.0.0.1%3A8080%2Fversion&scope=photos&state=1234zyx

The login page is displayed correctly. If I write in a bad username/password, then the response has no SID assigned. If I write in the good username/password then the response contains the new SID. All is fine, except that it does not redirect me to anywhere. The LoginEndpoint.login method returns a String, and it does not redirect to redirect_uri. It actually returns the "continueUrl" but I'm not sure what it means.

Sorry if I ask a dumb question.

nagylzs commented 6 years ago

Sorry, I mixed up the authorization url and the login url. It is working with /oauth2/auth

mgenov commented 6 years ago

Yes, auth endpoint of the library is redirecting non authenticated users to the configured loginPageUrl which is served by the application.

btw, v1.0.3 is bumped and it's available in the sonatype repository. In a hour or something will be available and in maven central.

nagylzs commented 6 years ago

Okay, now I have a working Oauth2 server, and I got redirected to my oauth callback. I'm trying to find the endpoint that can be used to exchange the authorization code for a token. In the example app, OAuth2ServletBinding is configured at "/oauth2/*", and OAuth2ServletBinding extends OAuth2Servlet. So I guess I need to exchange for a token at /oauth2/token?grant_type=authorization_code&code=...&redirect_uri=...&client_id=...&client_secret=...

Now I guess I can get a JWT token instead by specifying grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer is that right?

And finally, is it possible to exchange the authorization code for a JWT token without specifying the client secret? Or do I always have to do the exchange through a trusted client? (Flow for single page applications, as described here: https://aaronparecki.com/oauth-2-simplified/#single-page-apps )

nagylzs commented 6 years ago

Duplicated userInfo page? The UserInfoEndPoint class in the example app shows user info about a user. (/r/oauth/oauth/userInfo/:token) It looks to me that OAuth2Servlet class does the very same thing with FkRegex(".*/userInfo", ...) So why do we have both? Is it for demonstration only?

mgenov commented 6 years ago

Only functionality is re-plicated. The idea is that it's an example REST endpoint which receives token and user info is retrieved which is associated with that token. It looks a little bit weird As resource service & identity provider are re-represented as single app.

The actual architecture should look something like this:

screen shot 2017-12-27 at 11 04 29

e.g resource service receives access token (header, param) and it's then checked in the identity provider to ensure that it's valid and for retrieving of the identity of the user.

mgenov commented 6 years ago

Okay, now I have a working Oauth2 server, and I got redirected to my oauth callback. I'm trying to find the endpoint that can be used to exchange the authorization code for a token. In the example app, OAuth2ServletBinding is configured at "/oauth2/*", and OAuth2ServletBinding extends OAuth2Servlet. So I guess I need to exchange for a token at /oauth2/token?grant_type=authorization_code&code=...&redirect_uri=...&client_id=...&client_secret=...

If servlet is bound to /oauth2/* then token endpoint should be /oauth2/token

Now I guess I can get a JWT token instead by specifying grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer is that right?

Yes, you have to provide JwtKeyStore implementations which provides key for verification.

And finally, is it possible to exchange the authorization code for a JWT token without specifying the client secret? Or do I always have to do the exchange through a trusted client? (Flow for single page applications, as described here: https://aaronparecki.com/oauth-2-simplified/#single-page-apps )

oauth2-server supports and public clients about this purpose, e.g the publicOne flag of Client need to be set to true. This is the code which is performing this logic: https://github.com/clouway/oauth2-server/blob/master/oauth2-server/src/main/java/com/clouway/oauth2/ClientAuthenticationCredentialsRequest.java#L45