Closed rgozim closed 7 years ago
It's entirely possible, although someone more experienced than I would have to chime in to advise on security of it.
I had a go at it (basically API only IdentityServer and UI hosted elsewhere) a month or so ago, but dropped it because I persuaded us to move in a different direction where having a login page on idsrv was acceptable.
At a very basic level, you'd have to create an API which returned data you needed e.g. external IdP's/Consent for a particular app. Which is simple enough. Inspect what logic the existing controllers do and look at what the views do wrt generating URL's and replicate these on API/your SPA respectively.
As for C/XSRF you can do something like this http://stackoverflow.com/a/44035774/3515174 Not sure what else needs doing for security -- as in, I'm genuinely not sure -- to me this is rather scary -- I would stick with MVC UI... Although I believe it is not intended for production, the QuickStart UI was developed by people who really know this sorta stuff inside out.
ProTip: You can pass idp through acr_values to automatically redirect to external IDP.
The UI is up to you, but the communication between the UI and the IdSvr middleware endpoints is mainly via the authentication cookie that the UI is expected to set. IMO, the UI is much easier to write in server-side rendered code, rather than SPA style.
I believe you need to look at the Resource Owner Password flow. Submit your username and pass and receive an access_token, along with a refresh_token. Make sure to set "offline_access" to true in your client config.
It would be great if you could add a sample of doing this with vanilla javascript. Then everybody could addapt it to their dear framework. The sample could be as simple as possible to just know what are the minimal required things.
Thank you! I will look at it and see how to adapt it to IdentityServer4.
@rgozim Hi! I'm right with this same drawback of the UI. In some way I manage to solve it, or as it proceeded? I'm thinking about carrying out the password flow and not the implicit one but this openly breaks the OpenID protocol, but the truth is that using Razor and trying to adapt it with Angular or React is being a real headache or very frustrating. If you have any resource to help me do this, I would greatly appreciate it.
If you don't ask user permission for sending data to the client, then you cannot claim to be using openid connect
@TomCJones Hi, I do not understand your answer, was it for me? What I need to do is change the Razor UI to a UI with Angular or React or any other framework. For now I am experimentally exploring an SPA from .NET and consume the drivers of the QuickStart and modify this logic a little to suit my Angular Front-End application, however I do not know what the result will be.
Sorry, some how I read your request as asking for an id server with no ui. That would be hard to reconcile with the standard
@TomCJones No. He is not asking for an Id server without UI. He is asking for a UI implemented using just a plain Javascript client and not a MVC ASP.NET one where logic for the UI is delivered by the server. A Javascript client must connect to the ID server just using REST
@RaulRG Thanks for clarifying it. As I was investigating, I can have a SPA directly in an MVC project and make the connection with the .NET drivers to be able to do all the authentication. Now I am experimenting with this, but it is not functioning correctly yet.
Basic local login should be possible to do. But on top of dealing with cookies, external auth provider middleware (services.AddGoogle etc) works by processing Challenge() into 302 redirect which gets processed by the browser before it gets to XHR API, so it's not possible to get at the redirect URL in JS. May need to look at adding something on the server-side HTTP pipeline to convert redirect to a 200 response with the URL to let JS process it.
@brockallen You mentioned that resource owner password grant would be a possible solution. In that case how would you store the client secret and refresh the access token? Is it possible solution to set the ISRV authentication URL to angular route?
@rgozim were you able to use angular 2? did u hit any road blocks if doing so?
Hi anyone has any opinion now?
I'm having the same kind of challenge making a UI using React to deal with all process (login, email confirmation, password reset, new user registration). The lack of guidance in this area is a pity. Would be nice if someone shares some code about this subject...
@gersonDias, i have achieved this by configuring userinteraction options login url. I set the login url to single page application url and from there, you are on your own in writing functionality for the above asked use cases.
I still achieved the antivalidateforgery token functionality, (csrf token/cookie) so that we are not losing anything by going away from MVC to a Spa
One thing i am still looking for a solution is after login to identity provider, if user goes to idp login screen (spa login url), i was not sure how to check whether user logged in or not and if user is logged in i would like to show a basic welcome page.
I'm having the same kind of challenge making a UI using React to deal with all process (login, email confirmation, password reset, new user registration). The lack of guidance in this area is a pity. Would be nice if someone shares some code about this subject...
I think everyone is having a hard time understanding the relationship between the UI and IdentityServer. The short answer is the authentication cookie. Make your UI do whatever it needs to for any of those things. It's really unrelated to IdentityServer, But when your user wants to authenticate, then you need your server code behind the UI to issue the authentication cookie using the default authentication scheme from in the ASP.NET Core host. That's it. Once that cookie is issued, requests into IdentityServer will then do their job.
@brockallen Could IdentityServer4 be leveraged for mobile application using a framework such as Flutter? Thanks!
@brockallen is there any chance to post some working example of vanilla Javasrcipt(or Angular) and IdSrv4? I think it would be very useful because lot of developers use this kind of frontend/backend implementation...
that's great, but i think there is another thing that bother all of us here, we already have login screen in angular, so is there a way to avoid MVC and contact IdentityServer from Angular app?
Facing the same question. I've been looking all over the place for examples using a SPA (ReactJS in my case) to host the login/logout/ect... UI pages. The SPA would send the login request (with username and password) to the IdentityServer4 API to get a token and store it. The token would then be added to headers on SPA requests to a couple different data API's. All the examples I keep finding are still leaning on IdentityServer4's MVC UI for the actual login.
That being said... after reading this article, I'm inclined to go with the redirect/popup and use IdentityServer4's MVC pages to log in.
Personally, this does not make any sense to me. As the person responsible for implementing the Front End, I did these types of things a nice number of times. I have implemented logins with Identity Server using Angular code in the past just like this...
login(_username: string, _password: string) {
return this.http.post(
'api/token',
`grant_type=password&username=${_username}&password=${_password}`,
this.options)
.then(res => res.json())
.then((x) => {
localStorage.setItem('token', JSON.stringify(x));
return x;
});
}
I feel like Identity Server is stepping back into the 1990s with requiring to run a Razor page. My front end is dependent on numerous Front-End architectures that are shared fro the project, like shared components (buttons) and shared theme and a WPA. It would be imposable to share this all out to the Razor page, so it should all work in harmony.
At a point when Front-End is getting more complex and dynamic, does it make sense to remove the functionality of having it integrated into your project? @abemertz
Just to clarify - you can use whatever front-end technology you want to create your login UI. Our samples use Razor. That's all.
@leastprivilege I see that you did not understand what I was writing. My issue is not 'what' tech I am using, my issue is that it has to be INTEGRATED AND PART of my application so that I can have all shared assets used in the login page, not with a redirect and a separate application.
Please let me know if I am misunderstanding something. Thanks!
if that's what you want, then I have to tell you that this is not how it works. You need to make the front-end round-trip to the token service to get SSO.
If you don't need SSO then you can embed the login UI in your client and use resource owner flow for the authentication/token requests.
If you don't need SSO then you can embed the login UI in your client and use resource owner flow for the authentication/token requests.
Can you elaborate on this or point me to an article? Thanks
@david-genger I think you do misunderstand the concept of OpenID Connect, The entire point of OpenID Connect is having a separate application for login, IdentityServer4 is just implementing that protocol.
Please check this out What is OpenID Connect? How does it work?
Not only IdentityServer4 does this, all other Identity Provider that implement the OpenID Connect protocol does the same thing. For example, Azure AD B2C, Auth0 and Amazon Cognito
If you do not want a separate application for login, I believe the easiest way is just do not use any Identity Provider, and store your user credential (ex. user and password) in your own application.
@david-genger check out this quickstart for using ROPC with IdentityServer4: http://docs.identityserver.io/en/dev/quickstarts/2_resource_owner_passwords.html
But, please don't use it: https://www.scottbrady91.com/OAuth/Why-the-Resource-Owner-Password-Credentials-Grant-Type-is-not-Authentication-nor-Suitable-for-Modern-Applications
Not recommended but you can use the resource owner password workflow and get an access token. It can be done if you own the resource api and the identity server, but again, it is not encouraged.
I think the conversation derailed from its original purpose. The main topic was about having a sample providing a "port" of the Quickstart.UI sample to implement screens such us Register, Login, Logout, Consent and others for IdentityServer4, but in Angular or React instead of just Razor. The samples provided by @leastprivilege are only for client apps, not for IdSrv4 itself. Also, I don't know how implementing the OwnerCredentials flow would be of any use in a case like this.
Not recommended but you can use the resource owner password workflow and get an access token. It can be done if you own the resource api and the identity server, but again, it is not encouraged.
If this is still an issue I can help with building an angular/react UI for login page without using a resource owner password.
If this is still an issue I can help with building an angular/react UI for login page without using a resource owner password.
I'd be interested about that
hey @CesarD - it took a while but I wrote it down here: https://medium.com/@piotrkarpaa/using-spa-react-angular-ui-with-identity-server-4-dc1f57e90b2c
Thanks for the example @karpikpl this was helpful.
Is it possible to use IS4 without any redirects whatsoever? I.e. use a single SPA which lazy-loads the authenticated JS once the user has logged in? It would be nice to have no page reloads whatsoever as part of the login process.
If this is a security concern, could someone please explain why? There are many enterprise apps which have this kind of login process (no redirects), so I'm wondering why this would not be achievable.
@Gearshxft in your client app you can set it up to open popups. This will let your app function without redirects.
Take a look at https://github.com/karpikpl/oidc-spa-client
Really struggling with this. The suggestions are all over the map. I like @karpikpl implementation, but I hate to have to override an IdentityServer4 class (OidcReturnUrlParser ). Why does IS4 assume a localUri for valid return URL?
Also, how is this any different from using the ROPC flow?
I would love if someone would explain the best/safest way to have your SPA app take the Username/Password fields, and authenticate with them.
You only have to override returnUrlParser if the IdentityServerUi is hosted on a different domain (the question here was about having the login page hosted as SPA).
When you have an SPA app and run Identity server 4 with server side rendering (like the UI samples), you don't have to override anything.
Look at the OIDC client on GitHub, there are some samples for JS clients. Similar to what I have in my repos.
@karpikpl I should have been more specific, I was wondering if it's possible with no popups or redirects at all (do everything inside a single HTML page).
If you are able to configure IS4 to use an SPA for the login page, is there any reason why you couldn't just host your entire SPA on IS4? An SPA only needs a single HTML page to serve as the entry point, so why serve a separate SPA from .NET Core at all?
What you're trying to do is possible but not using code or implicit flow (which are recommend for SPAs). You would have to use RO password grant.
The OAuth 2.0 resource owner password grant allows a client to send username and password to the token service and get an access token back that represents that user.
If you want to host everything in one app without redirects than the best option is not too use OIDC but maybe old fashioned cookies?
@karpikpl Maybe I'm missing something, but your solution has a controller method that takes username/password directly. How is it different than ROPC inadequacies?
Is the security issue here basically about URL query vs a POST containing username/password? Because query strings can be logged or cached in odd places and expose the password easier?
@foconnor-DS: the method that I assume you mentioned must be the one Login
from AuthenticateController
. That's not the same as ROPC. That's a method for IdServer's own UI (now based on an SPA instead of MVC), and it's also protected by CORS, so not any webapp can send requests to validate credentials.
Also, ROPC is meant for a client to use it directly. In this case if you are using implicit
flow, you still have to redirect the user to log into IdS4 using its SPA UI and not using your own app UI. All security issues about giving your credentials to your own app (which could do anything with them) doesn't exist and user can stay assured that he/she is only dealing with a secure login.
Hope this makes sense.
I fully understand and agree with the conclusion of this thread. However since the topic does not specify which client technology we are talking about - it should be something like Angular - I have the guts and ask:
What if HTTP redirect is not an option for some clients, but our web based clients are already using IS4? Lets say we have desktop clients as well and would like to utilize all the advantages of token based authorization and a centralized identity solution.
Would it be suggested to extend IS4 with a custom login API endpoint that returns an access token? Or is it still a security concern to send user/pwd from anywhere else than IS4 login page itself? So it is necessary for desktop apps (as well) to integrate browser based authentication?
Desktop ones would use a different flow since desktop/mobile clients can maintain secrets client side (where browser cannot)
I think device flow is pretty well described in IS4 docs.
I’ll sit later and find it
@karpikpl in your example how are cookies handled ? i know that IDSRV depends on cookies to determine whether the user is logged into the token authority or not. based on that it displays the login page or just redirects back with a successful response (based on the flow)
The cookie is still issued on the identity server domain, so when the redirect in the browser happens, cookie is included and the login page is skipped. The length of that "SSO" session is controlled independently in IS4.
I've added a logout action in the sample that's supposed to kill that cookie and force the user to see the login page again.
We've been using that in production. The thing that was confusing to most people was that expiration of JWT and expiration of the IS4 cookie are totally independent.
All the samples I've seen for IdentityServer4 use some variation of the QuickStartUI which uses MVC for the UI.
I would like to build my login/logout/etc screens using a framework such as Angular2 and I'm struggling to figure out if it's possible given that every sample in some way uses a redirect to an MVC UI implementation.
Could someone explain to me or show me a sample that is API based and uses a Framework for UI?