Skip to content

Commit 924044b

Browse files
Anil AllewarAnil Allewar
Anil Allewar
authored and
Anil Allewar
committed
auth server changes to support all grant types and added extensive documentation in README on how to use the different grants
1 parent 95bd6b8 commit 924044b

File tree

5 files changed

+144
-4
lines changed

5 files changed

+144
-4
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ build
1515
bin
1616
.settings
1717
.gradle
18+
.DS_Store
19+
.classpath

auth-server/README.md

+126-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,129 @@
22

33
## Prerequistes
44

5-
* Running Mysql with HostName=db, username=root, password=password, database = auth-db
6-
7-
* If you have docker you can simply run - docker run -d -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=auth --name auth-db -p 3306:3306 mysql
5+
### Setting Authentication Schema Information
6+
* The mysql database information is available on the config server GitHub configuration.
7+
* Please look up the "application.yml" file under the "config-server" project for the location of GitHub repository where the database information has to be updated.
8+
* At the GitHub repository, update the "auth-server.yml" file section below for the mysql database where the authentication schema would be stored.
9+
```
10+
spring:
11+
datasource:
12+
url: jdbc:mysql://192.168.59.103:3306/auth
13+
username: root
14+
password: password
15+
driver-class: com.mysql.jdbc.Driver
16+
```
17+
* At a minumum, you would need to change the JDBC URL to point to where your mysql server is running.
18+
19+
### Running Mysql
20+
* Hosted mysql
21+
* If you have hosted mysql, please create the `auth` database and have `username=root`, `password=password`.
22+
* You can obviously have different values for user/password/database; just ensure that the "auth-server.yml" file in the configuration Github repository has the correct values.
23+
* Docker container
24+
* If you have docker you can simply run the following command on the docker prompt. Note that we are specifically naming the container as auth-db (using --name auth-db) instead of docker provided random names so that we can use the predefined name in subsequent commands.
25+
```
26+
docker run -d -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=auth --name auth-db -p 3306:3306 mysql
27+
```
28+
* To get the IP address of the VM where mysql is running
29+
`boot2docker ip`
30+
* Checking the mysql logs
31+
`docker logs -f auth-db`
32+
* Note that sometime the server goes down maybe because your m/c sleeps and this cause the mysql container to go bad.
33+
* In this case first stop the docker container by typing
34+
`docker stop auth-db`
35+
* Run the below command to remove stopped container.
36+
`docker rm $(docker ps -a -q)`
37+
* Start the mysql container again by using the `docker run -d -e........` command specified above.
38+
39+
### Projects that need to be started before
40+
* [config server](../config-server/README.md) - For pulling the configuration information
41+
* [webserver-registry](../webserver-registry/README.md) - For starting the Eureka server since the authorization server also is a micro-service that needs to be registered with Eureka server.
42+
43+
### Running the application
44+
* Build the application by running the `./gradlew clean build` gradle command at the "auth-server" project root folder on the terminal.
45+
* Run the application using either of the 2 below
46+
* If you want to run the application in debug mode, then `./gradlew bootRun`; this would start the debugger at port 4100 that can be connected as remote java application.
47+
* If you want to run the application as jar file, then `java -jar build/libs/sample-auth-server-0.0.1.jar'
48+
* When testing the authentication and authorization flow, ensure that you don't have cookies and HTTP basic credentials stored in the browser cache. The simplest way to do that say in `Chrome` is to open a new `incognito window`.
49+
50+
### Testing different authorization grant types
51+
#### Authorization code
52+
* This flow is typically used by web server apps(server-to-server communication) to authorize the user and then get the token using POST from the server.
53+
* The user needs to be authenticated (if required), before the request is sent to the authorization server.
54+
* The authentication credentials are user `dave` and password `secret`. You can add more user if required in the `com.rohitghatol.microservice.auth.config.OAuthConfiguration` class; look at the `AuthenticationManagerConfiguration` inner class for user initialization.
55+
* After opening an incognito window, paste the following URL(**Note: response_type=code**) in the browser bar
56+
```
57+
http://localhost:8899/oauth/authorize?response_type=code&client_id=client&redirect_uri=http://localhost:8090/index.html
58+
```
59+
* Provide authentication information user `dave` and password `secret`.
60+
* Click on the "Authorize" button to provide permission for the OAuth server to provide token to the client.
61+
* If you have the [web-portal](../web-portal/README.md) project running, then you should land on the index page with the OAuth code in the URL; something like `http://localhost:8090/index.html?code=5s3OgY#/`
62+
* Once you have the access code, you can get the actual OAuth access token by making the following POST request using curl.
63+
```
64+
$ curl client:secret@localhost:8899/oauth/token \
65+
-d grant_type=authorization_code -d client_id=client \
66+
-d redirect_uri=http://localhost:8090/index.html -d code=5s3OgY
67+
```
68+
* Response received would be something like
69+
```
70+
{"access_token":"5a3feb70-8ee8-49fd-af25-528259c8cffd","token_type":"bearer","refresh_token":"5f578b3e-5301-4995-9f7f-5473784d0184","expires_in":29,"scope":"read"}
71+
```
72+
73+
#### Implicit
74+
* Implicit grants are used in browser based application when we can't show the client secret on the browser side.
75+
* After opening an incognito window, paste the following URL(**Note: response_type=token**) in the browser bar.
76+
```
77+
http://localhost:8899/oauth/authorize?response_type=token&client_id=client&redirect_uri=http://localhost:8090/index.html
78+
```
79+
* The response redirect us to the redirect website with the access token in the query string.
80+
```
81+
http://localhost:8090/index.html#/access_token=52b48575-f5af-42b7-80bd-6ba69a6297fd&token_type=bearer&expires_in=29&scope=read
82+
```
83+
84+
#### Password
85+
* The password grant is used to provide the username and password to the authorization server and get the access token directly.
86+
* It typically would be used by mobile/desktop application that use a service to get the access token and have implicit access to the user's credentials.
87+
* Use a client like postman chrome extension to make the POST request for password grant (**Note: grant_type=password**).
88+
```
89+
http://localhost:8899/oauth/token?grant_type=password&username=dave&password=secret&redirect_uri=http://localhost:8090/index.html
90+
```
91+
```
92+
Use basic authentication in postman and provide the client and client_secret for the basic authentication
93+
Username - client
94+
Password - secret
95+
```
96+
* The following curl command can be used to verify password grant
97+
```
98+
$ curl --request POST -u client:secret "http://localhost:8899/oauth/token?grant_type=password&username=dave&password=secret"
99+
```
100+
* The response received is
101+
```
102+
{"access_token":"61f349c2-2f08-465a-948d-ccbc25e79c7c","token_type":"bearer","refresh_token":"a537af34-a151-4759-94d3-efe1501daf51","expires_in":29,"scope":"read"}
103+
```
104+
105+
#### Client credentials
106+
* The client credential grant is used by the client themselves to get an access token without the context of the user involved.
107+
* This might be required if the application wants to do some book keeping activities (like changing the registered url) or gather statistics.
108+
* Use a client like postman chrome extension to make the POST request (**Note: grant_type=client_credentials**) for client_credentials grant. Note that **No Auth** should be selected for the authentication scheme since we are bypassing the user here.
109+
```
110+
http://localhost:8899/oauth/token?grant_type=client_credentials&client_id=client&client_secret=secret
111+
```
112+
113+
#### refresh token
114+
* By default, the access token provided by the authorization server is short lived and will expire based on the "expires_in" value provided.
115+
* If you access a protected resource with an expired token, it will respond back by saying that the token has expired.
116+
* In this scenario, the application can request another access token from the authorization server by using the refresh token.
117+
* Assume that we already received the access token for password grant, then we can use the following POST request from chrome postman extension. Note that **grant_type=refresh_token** and you need to provide the refresh_token value that was received in the response for the password grant.
118+
```
119+
http://localhost:8899/oauth/token?grant_type=refresh_token&client_id=client&refresh_token=a537af34-a151-4759-94d3-efe1501daf51
120+
```
121+
```
122+
Use basic authentication in postman and provide the client and client_secret for the basic authentication
123+
Username - client
124+
Password - secret
125+
```
126+
### Getting protected resources
127+
* Once you have the access token, put the value in a header called "Authorization" and value as "Bearer <access_token_value> and make the request.
128+
```
129+
curl -H "Authorization: Bearer e30770ef-8e6f80-bd24-39391c9e1453" http://localhost:8081/user
130+
```

auth-server/application.yml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
logging:
2+
level:
3+
org:
4+
springframework: DEBUG

auth-server/build.gradle

+8
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ distDocker {
5757
exposePort 8080
5858
}
5959

60+
bootRun {
61+
jvmArgs = ['-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=4100,suspend=n','-Dspring.profiles.active=dev']
62+
}
63+
64+
run {
65+
jvmArgs = ['-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=4100,suspend=n','-Dspring.profiles.active=dev']
66+
}
67+
6068
task createWrapper(type: Wrapper) {
6169
gradleVersion = '2.0'
6270
}

auth-server/src/main/java/com/rohitghatol/microservice/auth/config/OAuthConfiguration.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ public void configure(ClientDetailsServiceConfigurer clients)
6666
clients.jdbc(dataSource)
6767
.passwordEncoder(passwordEncoder)
6868
.withClient("client")
69-
.authorizedGrantTypes("client_credentials", "refresh_token","password")
69+
.authorizedGrantTypes("authorization_code", "client_credentials",
70+
"refresh_token","password", "implicit")
7071
.authorities("ROLE_CLIENT")
7172
.resourceIds("apis")
7273
.scopes("read")
@@ -88,6 +89,8 @@ public void init(AuthenticationManagerBuilder auth) throws Exception {
8889
// @formatter:off
8990
auth.jdbcAuthentication().dataSource(dataSource).withUser("dave")
9091
.password("secret").roles("USER");
92+
auth.jdbcAuthentication().dataSource(dataSource).withUser("anil")
93+
.password("password").roles("ADMIN");
9194
// @formatter:on
9295
}
9396

0 commit comments

Comments
 (0)