This package contains functions and types for enabling OAuth2 as a security mechanism in a microservice. It integrates with Goa generated OAuth2 security and also as part of the SecurityChain.
There are a couple of things you need to do to enable the OAuth2 security middleware. For details on OAuth2 you can find many resources on the official site: https://oauth.net.
Create a directory in which you'll keep your key-pair:
mkdir rsa-keys
cd rsa-keys
The generate 2048-bit RSA key pair:
openssl genrsa -des3 -out private.pem 2048
The output the keys in PEM form:
openssl rsa -in private.pem -outform PEM -pubout -out public.pub
Remove passphrase
openssl rsa -in private.pem -out withoutPassphrase.pem
NOTE: Make sure that the public key ends in .pub
. This is how the default
key resolver of the library locates the public keys.
Create a security file app/security.go with the following content:
package app
import (
"github.com/goadesign/goa"
)
// NewOAuth2Security creates a OAuth2 security definition.
func NewOAuth2Security() *goa.OAuth2Security {
def := goa.OAuth2Security{
Flow: "accessCode",
TokenURL: "http://localhost:8080/oauth2/token",
AuthorizationURL: "http://localhost:8080/oauth2/authorize",
Scopes: map[string]string{
"api:read": "no description",
"api:write": "no description",
}}
return &def
}
More details on how to configure the OAuth2 security are available on the official documentation:
- Docs: https://goa.design/implement/security/
- Example: https://github.com/goadesign/examples/blob/master/security/oauth2.go
Once the security specs are generated by Goa, you need to set up a security chain for the microservice.
In the main.go
file of your microservice, set up the JWT Security Chain
middleware and add it to the security chain.
import (
"github.com/blazhovsky/microservice-security/oauth2"
"github.com/blazhovsky/microservice-security/chain"
)
func main() {
// Create new OAuth2 security chain
// "rsa-keys" is the directory containing the RSA keys
// app.NewOAuth2Security() creates the OAuth2Security scheme structure
OAUTH2Middleware := oauth2.NewOAuth2Security("rsa-keys", app.NewOAuth2Security())
sc := chain.NewSecurityChain().AddMiddleware(OAUTH2Middleware)
// other initializations here...
service.Use(chain.AsGoaMiddleware(sc)) // attach the security chain as Goa middleware
}
To test the setup, you'll need to generate and sign a JWT token, then use it in the request header.
To generate a JWT, you can use different tools. In this example we'll use jwtgen command line tool. To install it:
npm install -g jwtgen
Then, to generate the JWT token, type:
jwtgen -a RS256\
-p rsa-keys/withoutPassphrase.pem\
-c "userId=599316bbf456208abcbcc186" \
-c "username=test-user"\
-c "roles=user,admin"\
-c "scopes=api:read api:write"\
-c "organizations=Org1,Org2"
which will output the JWT:
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1MDM0NzQxOTcsInVzZXJJZCI6IjU5OTMxNmJiZjQ
1NjIwOGFiY2JjYzE4NiIsInVzZXJuYW1lIjoidGVzdC11c2VyIiwicm9sZXMiOiJ1c2VyLGFkbWluIiwic2NvcGV
zIjoiYXBpOnJlYWQgYXBpOndyaXRlIiwib3JnYW5pemF0aW9ucyI6Ik9yZzEsT3JnMiJ9.WUILgtGMgILtlUSrP9
MHbNfiD1-q4mIvw-UbOqjrg4HnMLvTyXMD7Td4H4yeSjThJZxEzglUf3JdMu8_8Xf4CRnAPLqeiDOSia8SWRQeRG
majagiOkRPWYp0Ns7zlsguSXuPJ64RN2eik7ROV43qtnwahHGTfyjducSNMyK9OqzacciZE2G1WDlMlbSb2p1fZZ
oXr7je6r64qfW2g1HWjG8ojXmmqbxZO5RURUgly9fUOkPBq-y5E2yq3mZ1FdPoqi7QQ9ZeUnRv4-m0q8kXVqY3P9
4uc3HYRXxd35jBQP0JfU_aVzr_eL7b16QbyT7O_dTsbUOcOvcm4Hh54Gu4Mg
(Note that the JWT is actually one line. For readability purposes it is displayed here in multiple lines.)
Then you'll need to add the token in the Authorization
HTTP header of the request.
curl --header "Authorization: Bearer eyJ0eXAiOiJKV1Q...<full token here>...4pfw" "http://localhost:8080/profiles/me"