Playing around with OAuth sample; forked from spring-guides/tut-spring-security-and-angular-js Check the Spring's Guide/Tutorial
git clone https://github.com/yoga1290/tut-spring-security-and-angular-js.git;
cd tut-spring-security-and-angular-js/oauth2/authserver;
mvn spring-boot:run;
Header, Payload & signature as base-64 encoded string:
- Header
- alg: algorithm used for signature encryption; none | HS256| RS256
- typ: media type
- Payload
- iss: The issuer of the token
- sub: The subject of the token
- aud: The audience of the token
- exp: This will probably be the registered claim most often used. This will define the expiration in NumericDate value. The expiration MUST be after the current date/time.
- nbf: Defines the time before which the JWT MUST NOT be accepted for processing
- iat: The time the JWT was issued. Can be used to determine the age of the JWT
- jti: Unique identifier for the JWT. Can be used to prevent the JWT from being replayed. This is helpful for a one time use token.
- signature The signature is calculated by base64url encoding the header and payload and concatenating them with a period as a separator:
key = 'secretkey'
unsignedToken = encodeBase64(header) + '.' + encodeBase64(payload)
signature = HMAC-SHA256(key, unsignedToken)
- Tokens are created and signed using a private key, but verified using a corresponding public key
- In HMAC signatures, the
verification key = signing key
; an attacker can abuse this (in case of client-side verification)
We can enable annotation-based security using the @EnableGlobalMethodSecurity
annotation on any @Configuration
instance. Check Spring Security!
You can try RO Password Credentials flow to generate JWT token:
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:9999/uaa/oauth/token");
xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
xhr.send("grant_type=password&client_id=acme&scope=openid&username=user&password=password");
You can try to decode the header & payload of the JWT token:
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NzAxOTA3NjksInVzZXJfbmFtZSI6InVzZXIiLCJhdXRob3JpdGllcyI6WyJ3cml0ZSIsInJlYWQiXSwianRpIjoiMTRlNGQyYzItZmZmOC00YWNmLWE3NzktNzRkMDY0MTk5YTk1IiwiY2xpZW50X2lkIjoiYWNtZSIsInNjb3BlIjpbIm9wZW5pZCJdfQ.eb1OY2FYonzcoBmfRtIcVLIR_YWvlnPvzGkfmStBKJJdKCNcwu6X4-mwqQlyMejSIGpIYpHADrBt6Ip9WIKlca2ewAM3b5TK5okSCWuTKEPmpwhOhxBlhwOzRwoB727AQjlhwb9QA14I68Pdg8_xm_l8AS2v4fiMosb0N7vvo8yZhrHVl2zsC6Kgd5IAh9Z-BwluOhPWMKPNntYQ4MpbdrDbPs7u8wRS9_MOAVWL3A3LN2rFWbRxKUxM5PdssfeDDxfXV7ioYTGJFcoPcHnJT9j_c0oq15yuTGvepwiKF2kRsW58JixbTb0ZwxX0eHSKTb7UfpHiR7UA6YF40WdsFw'
.split('.')
.map(function(str, index) {
if(index<2) {
return JSON.parse(atob(str));
} else {
return str;
}
});
// OUTPUT:
{"alg":"RS256", "typ":"JWT"}
{"exp":1470190769,
"user_name":"user",
"authorities":["write","read"],
"jti":"14e4d2c2-fff8-4acf-a779-74d064199a95",
"client_id":"acme",
"scope":["openid"]}
// ... signature