How can i use this library to login through password credentials.
I am using this library for implicit flow but did not find a way to use password flow to get back access token.
if it does not, is there a way to set access token manually so does i can use profile, claims and all other features such as events. don't wanna use another library in order to decode access token.
Not currently supported.
Password flow would be extremely useful
@brockallen any idea already when 1.4.0 comes out?
Not anytime soon -- I'm swamped.
Ditto to the above. Anyway we can assist, or is it purely a bandwidth issue? Currently using our own in-house solution.
Yes, it's a bandwidth issue. If you want to take a stab at it, then comment here with your ideas on how you'd envision it being added into the existing style of the library (meaning would it go into UserManager, or not? Maybe there's a new class for this specific workflow.).
I was thinking a natural extension to the UserManager. Basically:
signinPassword(username: string, password: string): Promise<User>;
In theory it should be simple since it's just a straight forward API request, but I'd imagine it gets most complicated as a lot of the library infrastructure assumes (I believe), the implicit flow which can't wholely be resused.
Edit: I believe the refresh case is also complicated too? As you'd only be able to refresh either by A) storing rs owner creds in memory or B) make sure you get a refresh token w/ offline_access (new optional setting) and issue a a grant_type: refresh request instead of the current method of silently renewing.
Edit Edit: Query session status would also need to switch to using an introspection point. Signout would also probably need something like signoutPassword(): Promse<void>. Should it handle revocation? Is that valid?
Yea, as you're finding it's complicated :)
But definitely not insurmountable!
The API changes would basically amount to:
interface MetadataService {
+ getIntrospectionEndpoint(): Promise<any>;
}
class UserManager extends OidcClient {
+ signinPassword(args: IPasswordSigninArguments): Promise<User>;
+ signoutPassword(): Promise<void>;
}
interface User {
+ refresh_token?: string;
}
+ interface IPasswordSigninArguments {
+ username: string;
+ password: string;
+ [key: string]: any;
+ }
Some flag would probably also need to be added to user to signify that the access_token of the password type.
Signin would make a simple XHR request to the token endpoint with the appropriate args. SigninRequest and SigninResponse should need very little changes to fit that.
SilentRenewService would need to have _tokenExpiring updated utilize refresh token. If the developer hasn't configured offline_access, then silent renew will not be supported and fail.
querySessionStatus would need to be updated to use introspection endpoint. (Though I think I may be missing something here)
Signout would just clear the local state. I'm not seeing what else would need to be updated as I believe everything else "just works".
SessionMonitor has me scratching my head though. I'm not sure how that fits into the bigger picture?
Am I missing anything?
getIntrospectionEndpoint
Why introspection? That's for APIs.
SessionMonitor has me scratching my head though. I'm not sure how that fits into the bigger picture?
This would not work, as ROPF is not really OIDC, thus there's no session.
querySessionStatus would need to be updated to use introspection endpoint
Also would not work since there's no session at the OP.
getIntrospectionEndpoint
Why introspection? That's for APIs.
Fair enough. I misunderstood the purpose :)
Hmm. Maybe a seperate UserManager-esque class would make sense. Rip out all the persistent session related bits and only keep signin, signout, and revoke. What would it be called though?
ResourceOwnerClient?
That works here. Though it might be confusing since it doesn't have "Manager" and people might take that to mean it doesn't take care of all the storage and other bits at first glance.
Well, there's already an OidcClient that's more protocol, and UserManager that's additional features on top. You could provide a similar separation -- protocol vs management.
Yup that makes sense. Maybe just ResourceOwnerClient for now. I'm currently rewriting our in house equivalent of this and I'll see if I can make it so I can pull the relevant bits out and pull something together for a PoC PR.
Any updates on a ResourceOwnerClient?
Here's a very rough PoC of a resource client:
https://gist.github.com/RichiCoder1/88903001dae4bb186dae79bd5f6adeb8
Duplicates a lot of stuff from OidcClient and ResourceValidator fyi. Can clean up further if I'm headed in the right direction. Also makes extensive use of async/await, which I can replace with .then later.
I really need Resource Owner Password flow and because of that I use other front library(temporary).
I still wait for support this flow...
Writing a resource owner password flow OAuth2 client is a simple HTTP call. You don't need this library for that, to be honest.
i have Angular project with a lot of Micro app that just one of them need password flow other apps use implicit flow and all of them need to work integrated.
This is not a priority, but if it is for your company then feel free to contact me to sponsor the feature.
I have tried implement password flow. I called several methods from my code. The problem is that I could not get sub from access_token and so I could not fill profile. So it looks like that the problem is that I could not get user because its sub is compared to profile user.
Access_token is difficult to parse, to load userinfo I should know sub....
var t = await userManager.metadataService.getTokenEndpoint();
var res = await fetch(t, {
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'grant_type=password&username=${this.state.login}&password=${this.state.password}&scope=api1%20offline_access%20profile%20email%20openid&client_id=cch-postman-password',
mode: "cors"
});
var r = await res.json();
console.log(r);
userManager.createSigninRequest({
response_type: 'token',
scope: 'api1 offline_access profile email openid',
//loadUserInfo: false,
})
.then((e: SigninRequest) => {
console.log(e.state);
return userManager.signinRedirectCallback(Helper.getParamsString({
access_token: r.access_token,
expires_in: r.expires_in,
token_type: r.token_type,
scope: 'api1 offline_access profile email openid',
state: e.state.id,
nonce: e.state.nonce,
}))
})
.then((e) => {
})
Maybe you have meant filling profile from identity token?
ResponseValidator._processClaims contains
if (this._settings.loadUserInfo && response.access_token) {
... return this._userInfoService.getClaims(response.access_token).then ...
if (claims.sub !== response.profile.sub) {
return Promise.reject(new Error("sub from user info endpoint does not match sub in access_token"));
}...}...}
In my case access_token is jwt_token, but ResponseValidator does not fill response.profile in absence of id_token. "response_type" equal to token (not id_token) does not get userInfo from userInfo endpoint in this case. And I could not find place to call parse jwt methods for setting profile sub.
Any Guesses, when this will be implemented? I also tried out, to get The Token, via the Backend (which works quite well). But the renewal and authorization then won麓t work as expected.
Given that resource owner password grant is deprecated in OAuth2.1 I don't foresee adding it ever.
I have not seen good suggestions about imlementing identity server's client part with the same design as the rest site. I don't understand why identity server should use MVC while the real site does not use it.
Is custom two factor authorization through oauth forbiden too?
@brockallen Hmm I've seen there an possibility, to renew the Token that way. What way would be then given, to enable Authentication via the Credentials without an implicit-Flow (or any, which redirects the User)?
@brockallen really quick one, if Resource Password Owner Grant is being deprecated in OAuth2.1, what would be the way (if any) to use an equivalent of a Password Flow as opposed to the implicit flow? I guess my use case is that I have 2 clients, one SPA which uses the implicit flow with the standard redirect and now I would like to implement a mobile APP with its own login page without the need of the redirect. How could I achieve it - or is there any other library I could use for that, assuming I'm targetting Identity Server 4?
Thanks
@brockallen How could I achieve it - or is there any other library I could use for that, assuming I'm targetting Identity Server 4?
I had tried to solve this task a year ago with cordova and ios/android requrements. There are good suggestions that client received the authorization code from the redirect URI. Usage of external browser components was depricated. New components did not allowed to see redirect url (or this feature were not implemented). Ios and android have very different structure of local url. Identity Server 4 allows none. So to make redirect you must use library to make custom scheme. Than Identity Server does not allow custom scheme, but you can put somewhere page that you will use as redirect url that will make the redirect to your custom scheme. And if all of this is correctly setup you have your login...
@yulObraz my use case here is that _"I don't want to abandon the actual APP to be redirected to the Identity server login page" and still it's not very clear to me as to which type of flow configuration should be using. I'm not sure if I'm missing here something obvious.
Resource owner flow is the only flow that does not redirect. It's not part of OIDC (it's OAuth2 only) and it's been deprecated. This library will not implement it.
Most helpful comment
Password flow would be extremely useful