OpenID Connect: Proper way of authenticating user - ID token or Access token? Refreshing ID tokens?











up vote
3
down vote

favorite
2












In our web application (ASP.NET), we use OpenID Connect with the authorization code flow:




  1. The user is redirected to the identity provider (e.g. Azure AD), authenticates,

  2. The authorization code is POSTed back to a page in our web application.

  3. Our web app then retrieves the refresh token, id token and access token from the identity server using the authorization code. These are stored on the clients as cookies (with the HttpOnly flag set to true). This is in order to avoid a dependency on the server's state, in case the user is routed to a different web server by the load balancer.

  4. When the user accesses a page, we validate the ID token's signature and validity period, and checking the claim we use for the identity (e.g. email address or UPN) against the user database in our application.


This works -- except that we're unable to refresh the ID token, so users are timed out after 1 hour, requiring a new login. According to the OpenID Connect specs, when refreshing tokens with the token endpoint, not all OpenID Connect providers will supply a new ID token.



The alternatives we see so far:




  1. Don't use the ID token at all. Use the access token to query the UserInfo endpoint for the user's claims, and cache it on the server (on cache miss, e.g. if routed to a different web server - simply use the provided access token from the cookie to request the UserInfo again). Since the access tokens can be refreshed, this would probably work fine.


    • Pros: We get a properly refreshed token, that are validated by the server.

    • Cons: Not all claims (e.g. aud and iss) are provided by the UserInfo endpoint, at least for Azure AD.



  2. Don't verify expiry of the ID token, just that it's not older than e.g. 12 hours.


    • Pros: Simple, requires little effort to change from the current behavior. Has all the claims that we also have today.

    • Cons: Might be a security risk? Comments?




So what is the recommended way of persisting a user's login over a longer period of time? Would using the access token with the UserInfo endpoint be a suitable solution?










share|improve this question






















  • Do you use access token for accessing some remote resources from your application backend? Is identification of a user the only thing you want from the tokens (and OAuth2 in general)? Do you care about the single sign out feature of Azure AD?
    – Ján Halaša
    Nov 14 at 7:41










  • No, we only use the access token for the UserInfo endpoint currently. Our main use case for OpenID Connect is authentication of the user -- authorization is done by our backend by other means currently.
    – Hallgeir
    Nov 17 at 11:28















up vote
3
down vote

favorite
2












In our web application (ASP.NET), we use OpenID Connect with the authorization code flow:




  1. The user is redirected to the identity provider (e.g. Azure AD), authenticates,

  2. The authorization code is POSTed back to a page in our web application.

  3. Our web app then retrieves the refresh token, id token and access token from the identity server using the authorization code. These are stored on the clients as cookies (with the HttpOnly flag set to true). This is in order to avoid a dependency on the server's state, in case the user is routed to a different web server by the load balancer.

  4. When the user accesses a page, we validate the ID token's signature and validity period, and checking the claim we use for the identity (e.g. email address or UPN) against the user database in our application.


This works -- except that we're unable to refresh the ID token, so users are timed out after 1 hour, requiring a new login. According to the OpenID Connect specs, when refreshing tokens with the token endpoint, not all OpenID Connect providers will supply a new ID token.



The alternatives we see so far:




  1. Don't use the ID token at all. Use the access token to query the UserInfo endpoint for the user's claims, and cache it on the server (on cache miss, e.g. if routed to a different web server - simply use the provided access token from the cookie to request the UserInfo again). Since the access tokens can be refreshed, this would probably work fine.


    • Pros: We get a properly refreshed token, that are validated by the server.

    • Cons: Not all claims (e.g. aud and iss) are provided by the UserInfo endpoint, at least for Azure AD.



  2. Don't verify expiry of the ID token, just that it's not older than e.g. 12 hours.


    • Pros: Simple, requires little effort to change from the current behavior. Has all the claims that we also have today.

    • Cons: Might be a security risk? Comments?




So what is the recommended way of persisting a user's login over a longer period of time? Would using the access token with the UserInfo endpoint be a suitable solution?










share|improve this question






















  • Do you use access token for accessing some remote resources from your application backend? Is identification of a user the only thing you want from the tokens (and OAuth2 in general)? Do you care about the single sign out feature of Azure AD?
    – Ján Halaša
    Nov 14 at 7:41










  • No, we only use the access token for the UserInfo endpoint currently. Our main use case for OpenID Connect is authentication of the user -- authorization is done by our backend by other means currently.
    – Hallgeir
    Nov 17 at 11:28













up vote
3
down vote

favorite
2









up vote
3
down vote

favorite
2






2





In our web application (ASP.NET), we use OpenID Connect with the authorization code flow:




  1. The user is redirected to the identity provider (e.g. Azure AD), authenticates,

  2. The authorization code is POSTed back to a page in our web application.

  3. Our web app then retrieves the refresh token, id token and access token from the identity server using the authorization code. These are stored on the clients as cookies (with the HttpOnly flag set to true). This is in order to avoid a dependency on the server's state, in case the user is routed to a different web server by the load balancer.

  4. When the user accesses a page, we validate the ID token's signature and validity period, and checking the claim we use for the identity (e.g. email address or UPN) against the user database in our application.


This works -- except that we're unable to refresh the ID token, so users are timed out after 1 hour, requiring a new login. According to the OpenID Connect specs, when refreshing tokens with the token endpoint, not all OpenID Connect providers will supply a new ID token.



The alternatives we see so far:




  1. Don't use the ID token at all. Use the access token to query the UserInfo endpoint for the user's claims, and cache it on the server (on cache miss, e.g. if routed to a different web server - simply use the provided access token from the cookie to request the UserInfo again). Since the access tokens can be refreshed, this would probably work fine.


    • Pros: We get a properly refreshed token, that are validated by the server.

    • Cons: Not all claims (e.g. aud and iss) are provided by the UserInfo endpoint, at least for Azure AD.



  2. Don't verify expiry of the ID token, just that it's not older than e.g. 12 hours.


    • Pros: Simple, requires little effort to change from the current behavior. Has all the claims that we also have today.

    • Cons: Might be a security risk? Comments?




So what is the recommended way of persisting a user's login over a longer period of time? Would using the access token with the UserInfo endpoint be a suitable solution?










share|improve this question













In our web application (ASP.NET), we use OpenID Connect with the authorization code flow:




  1. The user is redirected to the identity provider (e.g. Azure AD), authenticates,

  2. The authorization code is POSTed back to a page in our web application.

  3. Our web app then retrieves the refresh token, id token and access token from the identity server using the authorization code. These are stored on the clients as cookies (with the HttpOnly flag set to true). This is in order to avoid a dependency on the server's state, in case the user is routed to a different web server by the load balancer.

  4. When the user accesses a page, we validate the ID token's signature and validity period, and checking the claim we use for the identity (e.g. email address or UPN) against the user database in our application.


This works -- except that we're unable to refresh the ID token, so users are timed out after 1 hour, requiring a new login. According to the OpenID Connect specs, when refreshing tokens with the token endpoint, not all OpenID Connect providers will supply a new ID token.



The alternatives we see so far:




  1. Don't use the ID token at all. Use the access token to query the UserInfo endpoint for the user's claims, and cache it on the server (on cache miss, e.g. if routed to a different web server - simply use the provided access token from the cookie to request the UserInfo again). Since the access tokens can be refreshed, this would probably work fine.


    • Pros: We get a properly refreshed token, that are validated by the server.

    • Cons: Not all claims (e.g. aud and iss) are provided by the UserInfo endpoint, at least for Azure AD.



  2. Don't verify expiry of the ID token, just that it's not older than e.g. 12 hours.


    • Pros: Simple, requires little effort to change from the current behavior. Has all the claims that we also have today.

    • Cons: Might be a security risk? Comments?




So what is the recommended way of persisting a user's login over a longer period of time? Would using the access token with the UserInfo endpoint be a suitable solution?







asp.net authentication openid-connect refresh-token






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 12 at 9:39









Hallgeir

6641924




6641924












  • Do you use access token for accessing some remote resources from your application backend? Is identification of a user the only thing you want from the tokens (and OAuth2 in general)? Do you care about the single sign out feature of Azure AD?
    – Ján Halaša
    Nov 14 at 7:41










  • No, we only use the access token for the UserInfo endpoint currently. Our main use case for OpenID Connect is authentication of the user -- authorization is done by our backend by other means currently.
    – Hallgeir
    Nov 17 at 11:28


















  • Do you use access token for accessing some remote resources from your application backend? Is identification of a user the only thing you want from the tokens (and OAuth2 in general)? Do you care about the single sign out feature of Azure AD?
    – Ján Halaša
    Nov 14 at 7:41










  • No, we only use the access token for the UserInfo endpoint currently. Our main use case for OpenID Connect is authentication of the user -- authorization is done by our backend by other means currently.
    – Hallgeir
    Nov 17 at 11:28
















Do you use access token for accessing some remote resources from your application backend? Is identification of a user the only thing you want from the tokens (and OAuth2 in general)? Do you care about the single sign out feature of Azure AD?
– Ján Halaša
Nov 14 at 7:41




Do you use access token for accessing some remote resources from your application backend? Is identification of a user the only thing you want from the tokens (and OAuth2 in general)? Do you care about the single sign out feature of Azure AD?
– Ján Halaša
Nov 14 at 7:41












No, we only use the access token for the UserInfo endpoint currently. Our main use case for OpenID Connect is authentication of the user -- authorization is done by our backend by other means currently.
– Hallgeir
Nov 17 at 11:28




No, we only use the access token for the UserInfo endpoint currently. Our main use case for OpenID Connect is authentication of the user -- authorization is done by our backend by other means currently.
– Hallgeir
Nov 17 at 11:28












2 Answers
2






active

oldest

votes

















up vote
2
down vote



accepted










It depends on how the Identity token is used. Usually it's only there for the client. It allows the client to authenticate the user based on the mandatory sub claim. It shouldn't be used for authorization. That's what the access token is for.



In the hybrid flow (code+id_token) you could check the authenticity of the user before requesting the other tokens. In that case a small token is most efficient.



In the authorization code flow (code) you'd have to request the tokens anyway using the code. It now depends on the information in the id_token. If id_token doesn't contain the profile claims then you'll need to request the information from the UserInfo endpoint.



In order to access the UserInfo endpoint you need the access token. The missing aud and iss claims may not be a problem as you request the token by the authority itself. Seems to me that the issuer and audience are known at that point.



Please note that the id_token isn't used for authorization, so there shouldn't be a security risk. Not even when the id_token is shared with resources.



The specs require you to validate the received token as described. But when you don't receive a new id_token, why validate the current one again? It may not be up to date but it's already validated.



So IMO both options are fine, though I think that the first option is more common. It's likely that the id_token is discarded after use. Because the access token is used for accessing the resources (including the UserInfo endpoint) and the refresh token for refreshing the access token.



One remark, the consent of the user is used as a filter. If the user doesn't give consent for profile information then it won't be available at all.






share|improve this answer





















  • Thanks a lot for your insights! We went for option #2 - we validate the signature of the ID token on each request to make sure it hasn't been tampered with, but we have our own validation of expiry based on a setting in our application. The reason we chose this path was, as you said, we know the token was valid at the time of issuance, so validating it again and again (other than the signature) didn't make much sense.
    – Hallgeir
    Nov 17 at 11:26


















up vote
2
down vote













First you need to understand the purpose of each token. ID Token is there to be consumed by the client (application). It contains claims which you can validate to authenticate the end user (Authentication).



Access token is there for authorization. It is intended to be used against a protected resource (ex:- API protected by OAuth 2.0 tokens). When API receives the token, it must validate it and grant access.



Refresh token is there to refresh the access token. Now OpenID Connect being an extension of OAuth 2.0, allows the usage of refresh token. But as you figured out ID token may or may not be refreshed. I have personally seen Auzre AD not refreshing ID token.



Your best solution is to use a session between front end and backend. You set this session after you validate tokens from token request. Session storage can hold access token that was originally sent. Along with that, store the refresh token. You can simply validate the ID token and discard it (given that you store all required information to session). Make sure this session to be HttpOnly and Secure (Https only). Session expiration can be equal to Access token validity.



Once access token expires, you can use refresh token to obtain a new token. And whenever you want, your backend can append access token to API requests from backend. This way you never expose access token and refresh token to front end.






share|improve this answer

















  • 1




    Hi, thanks a lot for your input on this. The issue here is though that we don't want to rely on server side state, which setting up a session basically means, since if we get routed to a different webserver by the load balancer, the session must be set up again, thus the ID token must be (or at least should be) validated again.
    – Hallgeir
    Nov 17 at 11:18













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53259388%2fopenid-connect-proper-way-of-authenticating-user-id-token-or-access-token-re%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










It depends on how the Identity token is used. Usually it's only there for the client. It allows the client to authenticate the user based on the mandatory sub claim. It shouldn't be used for authorization. That's what the access token is for.



In the hybrid flow (code+id_token) you could check the authenticity of the user before requesting the other tokens. In that case a small token is most efficient.



In the authorization code flow (code) you'd have to request the tokens anyway using the code. It now depends on the information in the id_token. If id_token doesn't contain the profile claims then you'll need to request the information from the UserInfo endpoint.



In order to access the UserInfo endpoint you need the access token. The missing aud and iss claims may not be a problem as you request the token by the authority itself. Seems to me that the issuer and audience are known at that point.



Please note that the id_token isn't used for authorization, so there shouldn't be a security risk. Not even when the id_token is shared with resources.



The specs require you to validate the received token as described. But when you don't receive a new id_token, why validate the current one again? It may not be up to date but it's already validated.



So IMO both options are fine, though I think that the first option is more common. It's likely that the id_token is discarded after use. Because the access token is used for accessing the resources (including the UserInfo endpoint) and the refresh token for refreshing the access token.



One remark, the consent of the user is used as a filter. If the user doesn't give consent for profile information then it won't be available at all.






share|improve this answer





















  • Thanks a lot for your insights! We went for option #2 - we validate the signature of the ID token on each request to make sure it hasn't been tampered with, but we have our own validation of expiry based on a setting in our application. The reason we chose this path was, as you said, we know the token was valid at the time of issuance, so validating it again and again (other than the signature) didn't make much sense.
    – Hallgeir
    Nov 17 at 11:26















up vote
2
down vote



accepted










It depends on how the Identity token is used. Usually it's only there for the client. It allows the client to authenticate the user based on the mandatory sub claim. It shouldn't be used for authorization. That's what the access token is for.



In the hybrid flow (code+id_token) you could check the authenticity of the user before requesting the other tokens. In that case a small token is most efficient.



In the authorization code flow (code) you'd have to request the tokens anyway using the code. It now depends on the information in the id_token. If id_token doesn't contain the profile claims then you'll need to request the information from the UserInfo endpoint.



In order to access the UserInfo endpoint you need the access token. The missing aud and iss claims may not be a problem as you request the token by the authority itself. Seems to me that the issuer and audience are known at that point.



Please note that the id_token isn't used for authorization, so there shouldn't be a security risk. Not even when the id_token is shared with resources.



The specs require you to validate the received token as described. But when you don't receive a new id_token, why validate the current one again? It may not be up to date but it's already validated.



So IMO both options are fine, though I think that the first option is more common. It's likely that the id_token is discarded after use. Because the access token is used for accessing the resources (including the UserInfo endpoint) and the refresh token for refreshing the access token.



One remark, the consent of the user is used as a filter. If the user doesn't give consent for profile information then it won't be available at all.






share|improve this answer





















  • Thanks a lot for your insights! We went for option #2 - we validate the signature of the ID token on each request to make sure it hasn't been tampered with, but we have our own validation of expiry based on a setting in our application. The reason we chose this path was, as you said, we know the token was valid at the time of issuance, so validating it again and again (other than the signature) didn't make much sense.
    – Hallgeir
    Nov 17 at 11:26













up vote
2
down vote



accepted







up vote
2
down vote



accepted






It depends on how the Identity token is used. Usually it's only there for the client. It allows the client to authenticate the user based on the mandatory sub claim. It shouldn't be used for authorization. That's what the access token is for.



In the hybrid flow (code+id_token) you could check the authenticity of the user before requesting the other tokens. In that case a small token is most efficient.



In the authorization code flow (code) you'd have to request the tokens anyway using the code. It now depends on the information in the id_token. If id_token doesn't contain the profile claims then you'll need to request the information from the UserInfo endpoint.



In order to access the UserInfo endpoint you need the access token. The missing aud and iss claims may not be a problem as you request the token by the authority itself. Seems to me that the issuer and audience are known at that point.



Please note that the id_token isn't used for authorization, so there shouldn't be a security risk. Not even when the id_token is shared with resources.



The specs require you to validate the received token as described. But when you don't receive a new id_token, why validate the current one again? It may not be up to date but it's already validated.



So IMO both options are fine, though I think that the first option is more common. It's likely that the id_token is discarded after use. Because the access token is used for accessing the resources (including the UserInfo endpoint) and the refresh token for refreshing the access token.



One remark, the consent of the user is used as a filter. If the user doesn't give consent for profile information then it won't be available at all.






share|improve this answer












It depends on how the Identity token is used. Usually it's only there for the client. It allows the client to authenticate the user based on the mandatory sub claim. It shouldn't be used for authorization. That's what the access token is for.



In the hybrid flow (code+id_token) you could check the authenticity of the user before requesting the other tokens. In that case a small token is most efficient.



In the authorization code flow (code) you'd have to request the tokens anyway using the code. It now depends on the information in the id_token. If id_token doesn't contain the profile claims then you'll need to request the information from the UserInfo endpoint.



In order to access the UserInfo endpoint you need the access token. The missing aud and iss claims may not be a problem as you request the token by the authority itself. Seems to me that the issuer and audience are known at that point.



Please note that the id_token isn't used for authorization, so there shouldn't be a security risk. Not even when the id_token is shared with resources.



The specs require you to validate the received token as described. But when you don't receive a new id_token, why validate the current one again? It may not be up to date but it's already validated.



So IMO both options are fine, though I think that the first option is more common. It's likely that the id_token is discarded after use. Because the access token is used for accessing the resources (including the UserInfo endpoint) and the refresh token for refreshing the access token.



One remark, the consent of the user is used as a filter. If the user doesn't give consent for profile information then it won't be available at all.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 13 at 12:07









Ruard van Elburg

4,97321125




4,97321125












  • Thanks a lot for your insights! We went for option #2 - we validate the signature of the ID token on each request to make sure it hasn't been tampered with, but we have our own validation of expiry based on a setting in our application. The reason we chose this path was, as you said, we know the token was valid at the time of issuance, so validating it again and again (other than the signature) didn't make much sense.
    – Hallgeir
    Nov 17 at 11:26


















  • Thanks a lot for your insights! We went for option #2 - we validate the signature of the ID token on each request to make sure it hasn't been tampered with, but we have our own validation of expiry based on a setting in our application. The reason we chose this path was, as you said, we know the token was valid at the time of issuance, so validating it again and again (other than the signature) didn't make much sense.
    – Hallgeir
    Nov 17 at 11:26
















Thanks a lot for your insights! We went for option #2 - we validate the signature of the ID token on each request to make sure it hasn't been tampered with, but we have our own validation of expiry based on a setting in our application. The reason we chose this path was, as you said, we know the token was valid at the time of issuance, so validating it again and again (other than the signature) didn't make much sense.
– Hallgeir
Nov 17 at 11:26




Thanks a lot for your insights! We went for option #2 - we validate the signature of the ID token on each request to make sure it hasn't been tampered with, but we have our own validation of expiry based on a setting in our application. The reason we chose this path was, as you said, we know the token was valid at the time of issuance, so validating it again and again (other than the signature) didn't make much sense.
– Hallgeir
Nov 17 at 11:26












up vote
2
down vote













First you need to understand the purpose of each token. ID Token is there to be consumed by the client (application). It contains claims which you can validate to authenticate the end user (Authentication).



Access token is there for authorization. It is intended to be used against a protected resource (ex:- API protected by OAuth 2.0 tokens). When API receives the token, it must validate it and grant access.



Refresh token is there to refresh the access token. Now OpenID Connect being an extension of OAuth 2.0, allows the usage of refresh token. But as you figured out ID token may or may not be refreshed. I have personally seen Auzre AD not refreshing ID token.



Your best solution is to use a session between front end and backend. You set this session after you validate tokens from token request. Session storage can hold access token that was originally sent. Along with that, store the refresh token. You can simply validate the ID token and discard it (given that you store all required information to session). Make sure this session to be HttpOnly and Secure (Https only). Session expiration can be equal to Access token validity.



Once access token expires, you can use refresh token to obtain a new token. And whenever you want, your backend can append access token to API requests from backend. This way you never expose access token and refresh token to front end.






share|improve this answer

















  • 1




    Hi, thanks a lot for your input on this. The issue here is though that we don't want to rely on server side state, which setting up a session basically means, since if we get routed to a different webserver by the load balancer, the session must be set up again, thus the ID token must be (or at least should be) validated again.
    – Hallgeir
    Nov 17 at 11:18

















up vote
2
down vote













First you need to understand the purpose of each token. ID Token is there to be consumed by the client (application). It contains claims which you can validate to authenticate the end user (Authentication).



Access token is there for authorization. It is intended to be used against a protected resource (ex:- API protected by OAuth 2.0 tokens). When API receives the token, it must validate it and grant access.



Refresh token is there to refresh the access token. Now OpenID Connect being an extension of OAuth 2.0, allows the usage of refresh token. But as you figured out ID token may or may not be refreshed. I have personally seen Auzre AD not refreshing ID token.



Your best solution is to use a session between front end and backend. You set this session after you validate tokens from token request. Session storage can hold access token that was originally sent. Along with that, store the refresh token. You can simply validate the ID token and discard it (given that you store all required information to session). Make sure this session to be HttpOnly and Secure (Https only). Session expiration can be equal to Access token validity.



Once access token expires, you can use refresh token to obtain a new token. And whenever you want, your backend can append access token to API requests from backend. This way you never expose access token and refresh token to front end.






share|improve this answer

















  • 1




    Hi, thanks a lot for your input on this. The issue here is though that we don't want to rely on server side state, which setting up a session basically means, since if we get routed to a different webserver by the load balancer, the session must be set up again, thus the ID token must be (or at least should be) validated again.
    – Hallgeir
    Nov 17 at 11:18















up vote
2
down vote










up vote
2
down vote









First you need to understand the purpose of each token. ID Token is there to be consumed by the client (application). It contains claims which you can validate to authenticate the end user (Authentication).



Access token is there for authorization. It is intended to be used against a protected resource (ex:- API protected by OAuth 2.0 tokens). When API receives the token, it must validate it and grant access.



Refresh token is there to refresh the access token. Now OpenID Connect being an extension of OAuth 2.0, allows the usage of refresh token. But as you figured out ID token may or may not be refreshed. I have personally seen Auzre AD not refreshing ID token.



Your best solution is to use a session between front end and backend. You set this session after you validate tokens from token request. Session storage can hold access token that was originally sent. Along with that, store the refresh token. You can simply validate the ID token and discard it (given that you store all required information to session). Make sure this session to be HttpOnly and Secure (Https only). Session expiration can be equal to Access token validity.



Once access token expires, you can use refresh token to obtain a new token. And whenever you want, your backend can append access token to API requests from backend. This way you never expose access token and refresh token to front end.






share|improve this answer












First you need to understand the purpose of each token. ID Token is there to be consumed by the client (application). It contains claims which you can validate to authenticate the end user (Authentication).



Access token is there for authorization. It is intended to be used against a protected resource (ex:- API protected by OAuth 2.0 tokens). When API receives the token, it must validate it and grant access.



Refresh token is there to refresh the access token. Now OpenID Connect being an extension of OAuth 2.0, allows the usage of refresh token. But as you figured out ID token may or may not be refreshed. I have personally seen Auzre AD not refreshing ID token.



Your best solution is to use a session between front end and backend. You set this session after you validate tokens from token request. Session storage can hold access token that was originally sent. Along with that, store the refresh token. You can simply validate the ID token and discard it (given that you store all required information to session). Make sure this session to be HttpOnly and Secure (Https only). Session expiration can be equal to Access token validity.



Once access token expires, you can use refresh token to obtain a new token. And whenever you want, your backend can append access token to API requests from backend. This way you never expose access token and refresh token to front end.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 13 at 3:12









Kavindu Dodanduwa

5,44611230




5,44611230








  • 1




    Hi, thanks a lot for your input on this. The issue here is though that we don't want to rely on server side state, which setting up a session basically means, since if we get routed to a different webserver by the load balancer, the session must be set up again, thus the ID token must be (or at least should be) validated again.
    – Hallgeir
    Nov 17 at 11:18
















  • 1




    Hi, thanks a lot for your input on this. The issue here is though that we don't want to rely on server side state, which setting up a session basically means, since if we get routed to a different webserver by the load balancer, the session must be set up again, thus the ID token must be (or at least should be) validated again.
    – Hallgeir
    Nov 17 at 11:18










1




1




Hi, thanks a lot for your input on this. The issue here is though that we don't want to rely on server side state, which setting up a session basically means, since if we get routed to a different webserver by the load balancer, the session must be set up again, thus the ID token must be (or at least should be) validated again.
– Hallgeir
Nov 17 at 11:18






Hi, thanks a lot for your input on this. The issue here is though that we don't want to rely on server side state, which setting up a session basically means, since if we get routed to a different webserver by the load balancer, the session must be set up again, thus the ID token must be (or at least should be) validated again.
– Hallgeir
Nov 17 at 11:18




















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53259388%2fopenid-connect-proper-way-of-authenticating-user-id-token-or-access-token-re%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to change which sound is reproduced for terminal bell?

Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents

Can I use Tabulator js library in my java Spring + Thymeleaf project?