The OpenID Connect Implicit Client specification indicates the optional prompt=login parameter value for Implicit Clients SHOULD prompt the end-user for reauthentication.
Is the right way to interpret SHOULD either of the following:
prompt=login implementations meeting the SHOULD requirement should prompt users to reauthenticate when appropriate but may not in certain situations, e.g. prompt the user to reauthenticate where there is no active session, but do not prompt when the user has an active session.
prompt=login implementations meeting the SHOULD requirement MUST prompt users to reauthenticate.
If the right way to implement the SHOULD requirement is the #2 option above, to always authenticate, how does one handle the situation where the user is only prompted to authenticate if the session has expired? Would this be to omit the prompt parameter?
Implementations from Microsoft Azure, Okta, and Salesforce use MUST for reauthentication.
References:
OpenID: The Authorization Server SHOULD prompt the End-User for reauthentication. If it cannot reauthenticate the End-User, it MUST return an error, typically login_required.
MS Azure: prompt=login will force the user to enter their credentials on that request, negating single-sign on.
Okta: Can be either none or login. The value determines if Okta should not prompt for authentication (if needed), or force a prompt (even if the user had an existing session). Default: The default behavior is based on whether there’s an existing Okta session.
Salesforce: The authorization server must prompt the user for reauthentication, forcing the user to log in again.
For session management, You can use the max_age parameter as defined in the openid spec
Set the max_age to your desired session duration during sign-in to force identity provider to ask for credentials when session expires.
Related
I am using Microsoft authentication for user but I don't want to keep the user credentials to be saved in cookies so that it should ask every time performing a particular action in application.
I have created a simple web app with external authentication from Microsoft but when a user gets signed in it doesn't ask user for credentials from second time and redirect to RedirectUrl directly because user information is already there in Cookies. Normally this behavior looks fine but I have certain tasks in my Web App which needs authentication from External Source (Microsoft) every time these tasks get performed by user. I tried setting token lifetime in Azure but it says lifetime can not be lesser than 10 minutes.
Note: I can't call signout user because it is not a silent signout.
How can I achieve it?
You can set prompt=login parameter in the authentication request. Then the user should be prompted to re-authenticate even if the user has already been authenticated.
Reference:
https://learn.microsoft.com/en-us/azure/active-directory/azuread-dev/v1-protocols-oauth-code#request-an-authorization-code
https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-js-prompt-behavior
I am using Microsoft Azure authentication for user Login ,
After login of user there is change password section in my application where user provide his current password and new password so my query is
Is there is any Api(Graph) to GET Current Password for that user OR Any API(Graph) through which we authenticate current Password which provided by user
Is there any other scenario which help me to authenticate current password which was given by user while changing password
Or any other way to get current password for that user
thanks
There is no way to get the current password for users.
It would be a massive security vulnerability and imply they store them insecurely.
There is a way to authenticate a user like that, but it won't work if the user has e.g. MFA.
I would suggest a different approach.
Check how old the authentication is (id token has the time it was issued).
If it is older than, say, 15 minutes, require the user to authenticate with AAD (prompt=login).
You can also require MFA for the login if you know all your users use it.
Then they should be able to give a new password, which you can then set with Graph API.
So instead of making a call to check the current password, require a fresh ID token and rely on AAD to check the user credentials.
Also, the users should be able to change it themselves already as written in docs: https://learn.microsoft.com/en-us/azure/active-directory/user-help/active-directory-passwords-update-your-own-password
I am using the passport-ad library for my backend to protect my endpoint. How can I make sure that the bearer access token is new (e.g. issued time is within a certain threshold?)
For my frontend using MSAL, what is the best practise to force re-authentication when the user tries to access sensitive info?
Prompt is an optional parameter you can include during the authorization code flow, when the client directs the user to the /authorize endpoint. Prompt dictates the type of interaction that is required by the user. In MSAL.NET, you can choose from the following Prompts:
SelectAccount -> force the STS to present the account selection dialog containing a list of accounts for which the user has a session
Consent -> forces the user to be prompted for consent, even if consent was granted previously
ForceLogin -> the user will always be prompted for credentials by the service, even if not necessary (I think this is the one you want, when you say "force re-authentication")
NoPrompt -> no prompt value will be sent and the STS will determine which UI to show the user based on the previous sessions
For example:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
scope=offline_access+openid+profile
&client_id=37efsf6-14a6-44ae-97bc-6eba6916741e
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%3A12345
&response_mode=query
&resource=https%3A%2F%2Fservice.contoso.com%2F
&state=12345
&prompt=login
More info here.
New users are on-boarded via an offline process. At the end they are directed to a custom policy that does a password reset. This allows the user to choose their own password.
This is essentially the standard custom password reset policy without the need to validate the email. The user name is passed via a signed JWT token.
This all works and a valid ID token is returned.
The problem is getting a refresh token when this token expires.
We haven't found a way to do this.
Setting an "offline_access" scope doesn't seem to do anything.
Trying the "silent refresh" approach (prompt = "none") returns an error message stating that you don't have a session.
The applications are SPA built around adal.js.
An example of the password reset message is:
https://login.microsoftonline.com/tenant.onmicrosoft.com/oauth2/v2.0/authorize
?p=B2C_1A_Custom-PasswordReset
&client_id=xxx
&redirect_uri=yyy
&scope=openid%20offline_access&response_type=id_token
&prompt=login
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=JWT
Anyone ever got this working?
For a single-page application, a refresh token isn't issued, since this isn't considered to be secure.
Applications that use the implicit flow must implement a silent authentication to refresh tokens.
The silent authentication might be failing because your "Custom-PasswordReset" journey doesn't include the DefaultSSOSessionProvider SSO session provider to set the SSO claims in the user session.
As an example of this, see the LocalAccount-PasswordSet technical profile in the Wingtip sample, which is invoked to set the first-time password for a pre-verified user.
I am trying to determine the best way to enforce password expiration rules in my solution.
The server-side exposes a REST API for operations with a custom active Security Token Service (of sorts). Client applications pass user credentials to a REST endpoint where the user is authenticated on the server. The response includes a custom security token representing the user which is then passed to other API methods so the call can be authorized. The server is stateless and does not maintain any reference to the identity or claims information (i.e. session-less).
We have password expiration rules that are enforced by the server. So, when authenticating a user, it is possible that their password has expired. I need to communicate this to the client so they can do whatever is needed to have the user change their password. (There is another REST endpoint for changing the password on the server.)
Questions
It seems to me that authenticating a user with an expired password should fail. However, I need to know the identity of the user changing the password when making the second API call, so should I go ahead and return a token even when the password has expired?
How should I inform the client that a password change is required? I thought about including this as a claim in the token, but that would require me to reissue a new token after the password has been changed or modify the original token which isn't allowed. My other thought was a custom HTTP Status Code that I would correspond to meaning Password Change Required.
The answer to this question probably depends on the previous two, but I don't want to authorize a user that has an expired password if the token is passed to any other APIs (besides changing the password). What's the best way to handle this?
So, what I ended up doing (certainly not the be-all-end-all solution) is having my Authenticate endpoint return an AuthenticationResultCode enumerated value in the response in lieu of a simple pass/fail boolean. Possible values for the enumeration include:
ValidCredentials - the user was authenticated and the AuthenticationToken is included in the response.
InvalidCredentials - the user was not authenticated
CredentialsExpired - the user was authenticated but their password has expired. I have yet to determine if the AuthToken will be included with this result.
NoCredentials - no credentials were provided to the request
Now the client has more information about the result than a pass/fail value (which I really never checked anyway) and I can take the appropriate action in response such as automatically displaying the ChangePasswordDialog when CredentialsExpired is received.
Like I said, still working out whether or not I should still send the token when the credentials are expired because I don't want to be able to authorize a user if their credentials are expired but they've already been authenticated once and I don't think it makes sense to re-authenticate after changing the password (after all, I have to be authenticated so I can change the password in the first place). Maybe just a simple IsLocked or IsExpired property on the client will suffice...