After reading Andrews excellent article Spring Method Security with PreAuthorize | Okta Developer
I wanted to take the next step and see if I can get an access token with Postman so that I can test my APIs.
I used the example shown in this video to make progress
I can get an access token and submit a request to my local Spring boot app that using Spring security ver 5.1.8. The error shown in postman is
“An error occurred while attempting to decode the Jwt: Signed JWT rejected: Another algorithm expected, or no matching key(s) found”
The problem, best I can tell, is with the algorithm in the JWT. It seems to be HS256 but Spring is expecting RS256.
I took the JWT and decode it at
https://jwt.io/ who said the signature is invalid until I changed the drop down to HS256 and https://www.jsonwebtoken.io/ who identified it as HS256
I ran the spring boot app in debug mode and stepped thru the security files and found that com.nimbusds.jose Algorithm parseAlgorithm(JSONObject json) thinks it’s RS256
which explains why JwtAuthenticationProvider - this.jwtDecoder.decode(bearer.getToken()); throws an error.
btw, I don’t know what any of this means so if you think you know the answer please dumb it for me. What I would like is an easy way to get an access token in Postman so I can test.
Hi @Vladimir
Can you please provide an example access token to check out the signature algorithm in the header and issuer in the body?
Here it is
eyJraWQiOiJEM3pJSkd5VERsRHFsa1BoazA3VEpqd1M4MnZoZjlQYVpaOWN3Y3Vlcno4IiwiYWxnIjoiUlMyNTYifQ.eyJ2ZXIiOjEsImp0aSI6IkFULnFJc0EySTlGV0dyTlNudkZXM2tDLVNoTVdkOTRvV1hEWUt0LVFLOVdSMFkiLCJpc3MiOiJodHRwczovL2Rldi04OTk0MDcub2t0YS5jb20iLCJhdWQiOiJodHRwczovL2Rldi04OTk0MDcub2t0YS5jb20iLCJzdWIiOiJ2aDJAdGVzdC5jb20iLCJpYXQiOjE1NjIyNzc2NTIsImV4cCI6MTU2MjI4MTI1MiwiY2lkIjoiMG9hcmRqMG96cURNcjVMQ04zNTYiLCJ1aWQiOiIwMHV0bm1wOThlemVET3Y3VzM1NiIsInNjcCI6WyJvcGVuaWQiXX0.OW4r7R7_JI5WcN9g36B4AMrW2fBJ_XAXdfZ6rmsEMbtx5PwP33jbv2QQd2FmAdjVs5tobnZl5sXaccdOsCxeA_iowWZbq5JHAFl-ZEPxx3PdDrYByuEqYl2TDw1OnuahAlrB_l28kmmafEC45_3ORC4_ff5ogZNrACRB6zSWHv_lPDLD8DbwwyiWhbGZJGIuQN4AUxPZ_l0bEAYevXSRHQRAlh3X0KnluaIfQfzXu9paXdBEc3HQQbtmClT2fJZa_HtL08GSjlcZiVknV4OR07I4RgKPt9boH4eLwBVobTCi9MA8PGVyhc0nmFjbT2tIQbKzJLOSJennGEsD-Q4Rgg
Hi @Vladimir
Thank you for providing the access token. The algorithm used is set to RS256 in the header:
{
"kid": "D3zIJGyTDlDqlkPhk07TJjwS82vhf9PaZZ9cwcuerz8",
"alg": "RS256"
}
The reason for the verification failure is due to the issuer being set to Okta authorization server instead of a custom authorization server.
{
"ver": 1,
"jti": "AT.qIsA2I9FWGrNSnvFW3kC-ShMWd94oWXDYKt-QK9WR0Y",
"iss": "https://dev-899407.okta.com",
"aud": "https://dev-899407.okta.com",
"sub": "vh2@test.com",
"iat": 1562277652,
"exp": 1562281252,
"cid": "0oardj0ozqDMr5LCN356",
"uid": "00utnmp98ezeDOv7W356",
"scp": ["openid"]
}
To clarify, access tokens issued by Okta authorization server (eg. https://dev-899407.okta.com
) can not be verified locally, as the signing keys for them are not present on /keys endpoint in the authorization server. This is an expected behavior due as RFC restrictions.
In order to verify the tokens locally, the best solution is to use a custom authorization server (eg. set the issuer to https://dev-899407.okta.com/oauth2/default
, authorization endpoint to https://dev-899407.okta.com/oauth2/default/v1/authorize
and token endpoint to https://dev-899407.okta.com/oauth2/default/v1/token
). The access tokens issued by this authorization server will have the signing keys available on the keys endpoint https://dev-899407.okta.com/oauth2/default/v1/keys
.
1 Like
Your reply helped and the token is valid but it’s not the same type of token as with the regular login flow.
Here’s my Postman setup that works
and my issuer in the Spring config file is
okta.oauth2.issuer = https://dev-899407.okta.com/oauth2/default
When I debug the “Principal”, the type of token is different depending if the token was obtained thru postman or if the user logged in normally as shown in Andrew’s article.
@RequestMapping(value = "/api/test", method = RequestMethod.GET)
public void getToken(Principal principal ){
//Postman request with Bearer Token
if(principal instanceof JwtAuthenticationToken) {
JwtAuthenticationToken token = (JwtAuthenticationToken) principal;
}
//Normal Okta login
if(principal instanceof OAuth2AuthenticationToken){
OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) principal;
}
I think either type of token would be ok just as long as it’s the same one every time. They both have the data in it that I would need.
Thanks for your help getting me this far.