I am currently working on an implementation of IdentityServer4.
The client I am doing the work for, currently runs IdentityServer3 and has alot of valid refresh tokens stored in their Tokens table.
I possible, they would like to be able to reuse these refresh tokens in the new IdentityServer4 implementation, so that the upgrade will be a seamingless experience for their customers (i.e. they don't need to log in again).
Doing some testing on the subjects, I have noticed that the hashed keys are encoded differently in IdentityServer4's PersistedGrants table than it was in IdentityServer3's Tokens table, so simply copying the tokens into the new database, doesn't work.
Are there any backwards compatibility with old IdentityServer3 refresh tokens in place for IdentityServer4?
No. Migrating to IdentityServer4 is going to require everyone to login all over again. Even if the refresh tokens were backwards-compatible or could somehow be migrated, there are a lot of other places (for example, the revised Data Protection APIs, various cookie content) where a new ASP.NET Core ID4 server won't be able to smoothly take over from an existing ID3 implementation.
Also, be aware that both the IdentityServer4 QuickstartUI and EF persistence implementations are not intended to be treated as production-ready code. As of ID4 both of those concerns are officially considered your responsibility and those repos are meant as sample/reference code only. (The same is true of the ASP.NET Core EF Identity template, although Microsoft is less up-front about this.)
Related
I have some questions regarding Identityserver4 in the following context:
I have a number of domains (domainA, domainB, domainC ect.) and I’d like all of them to use Identityserver4 for authentication, but I’d like only one implementation of Identityserver4 (with asp.net identity and EF) and have the all domains use this implementation as clients. All domains is in a hosted environment with MS SQL as database, if that has any relevance.
Question 1:
Can IdentityServer4 run in a subfolder/area of domainA, and if so what are the necessary steps for getting this to work, e.g. the endpoints shown in the .well-known endpoint?
Question2:
What are the pitfalls, if any, in hosting Identityserver4 in a subfolder/area under domainA, and also having domainA use Identityserver for authenticating users for the rest of the site, and how to avoid the pitfalls if there are any?
The authorization part that permits one user to do this and not that, and the opposite for another user is not the concern of Identityserver4, but the respective domains/sites own responsibility as I understand what I can find online. In order to make use of roles and roleclaims in asp.net identity core 2 in each domain/site there has to be a user in that domain/site, that has a reference to a user in Identityserver4 in order for the domain to use Identityserver4 for authentication.
Question 3:
How do I avoid that the user must register both on the domain and in Identityserver4, one registration would be preferable and have the other made behind the scenes along with the reference?
I hope someone can provide the answers to one or all of my questions. Links to relevant blogs etc. are welcome, but I have scoured the web to find useful answers without any luck – hopefully some of you have better search engine skills than me.
Q1
Yes you can. IdentityServer is OWIN hosted environment, thus it will be working as a middleware for your domainA, if you set it up so. Having a public endpoint entirely depends on your domainA.
Q2
The possible problem you will possibly encounter would be performance issues. your domainA is going to receive requests from domainB and domainC including, of course, domainA itself. And IdentityServer's checks-up such as authentications, validations, issuing tokens could be obviously time consuming jobs compared to the plain HTTP requests.
While the middleware is doing its job, the performance will hit slightly lower rate then domanB and domainC. But this is a necessary, unavoidable backfire because you added one another layer in your HTTP windows to deal with the authentication / authorization / validation issues on your service endpoints.
You may want to scale out your IdentityServer if the traffic gets much more huger then you expected and you feel your authorization server is dragging the whole services down. I recommend you to perform some stress tests beforehand and compare the performance differences between the services using the identity service and the services using none of that.
Q3
This could be highly opinionated answer. But as you mentioned ASP.NET Identity and EF I think you already know the answer. It seems that you're going to manage the token and identity information in your own hosted DBMS. Then consider it done with the possible duplicated registrations. Your DBMS and your implementation for storing and fetching such data will do it for you as long as you've done it right.
If you're not going to use DBMS for the identity and token data, and use a cache or a file system instead, then you will have to pour some efforts into the implementation in order to guarantee concurrency on the transactions for such data.
I've been thinking about this quite a while and it's bugging my head off, lets say we have a website a mobile app and a database.
Usually when we develop our websites we pretend to store our database credentials in a configuration file and connect the website directly to the database without using a multi-tier architecture, but when it comes to a mobile application such Android or iOS this applications can be engineer reversed meaning that there's a risk of exposing your database credentials.
So I started thinking about this multi-tier architecture and kind of thinking about how Facebook and other social network do their job, they usually make an API and use a lot of HTTP Requests.
Usually social networks APIs have a app_id and a secret_key, this secret key would be used to increase the safety of the application but I'm thinking about how could I store these keys inside my application since I would go back to the begining of my discussion, if I was to use Java I could use the Java Preference Class but that isn't safe either has I saw in this question, plus I would need to make sure my HTTP Requests are CSRF safe.
So, how could I store these keys inside my app? What's the best way to do it, since hard-codding it's out of the question.
You should always require users to log in - never store credentials or private keys in an app you'll be distributing. At the very least, don't store them unless they're specific to the user who has chosen to store them after being validated.
The basic idea is that the user should have to be authenticated in some manner, and how you do that is really too broad to cover in a SO answer. The basic structure should be:
User asks to authenticate at your service and is presented with a challenge
User responds to that challenge (by giving a password or an authentication token from a trusted identity provider).
Service has credentials to access the database, and only allows authenticated users to do so.
There are entire services out there built around providing this kind of thing, particularly for mobile apps.
You might store the users own credentials on the device, and if so it should be encrypted (but you're right, a malicious app could potentially pick them up).
Bottom line: never distribute hard coded access to a database directly.
I've done a lot of research on "best practices" surrounding this and have read blog post after blog post, SO question after SO question, and OWASP article after OWASP article. I've arrived at a few clear answers but some unknowns.
First, the "Do's":
Use JWT for authorizing users on my REST API [1] [2]
Store the JWT in a HTTPOnly/Secure cookie and build in CSRF protection. Do NOT store in HTML5 local storage [3] [4] [5] (Actually, this point is debatable, is it easier to protect against XSS or CSRF? [6])
Verify the signing method of the JWT [7]
Now I started with the assumption that having a SPA (built with Angular) and using HTML5 sessionStorage would be secure enough for short-lived tokens, but there is a point to be made that XSS attacks can happen from a "bad actor" originating in the one of many libraries loaded in from a CDN.
For my specific use case, I do not plan on having long-lived tokens - expiration after 10 minutes of non-use but I'm still figuring out if I want to track expiration by session or use refresh tokens - StormPath recommends the former (no longer stateless?) but I believe big players using JWTs use refresh tokens (Google uses them but states you need to store them in secure, long-term storage which means HTML5 localStorage is again, out of the question).
I would like to make it so my users don't have to log back in if they refresh the page (hence the need to store the token on the client side). I would also like to use my SPA as a "mobile app" with the help of Cordova. The obvious pitfall here is that if I use cookies, there is no baked-in cookie support/storage with Cordova and I'm urged to switch to HTML5 local storage instead. Since on mobile I don't really need to worry about refreshing pages, I can just let my token live in memory and expire with the strategy I settle on.
If I take this approach, cookie-based JWT on Desktop, "Bearer" headers on mobile, I now need an authentication end-point that will give tokens two different ways, and when I authorize on the REST API side, I need to support both cookie-based JWTs (with CSRF) and header based JWT verification. This complication has me worried as I don't know if I can accurately foresee security implications here.
To summarize the barrage of thoughts above:
Create an authentication handler that would hand out tokens via HttpOnly/Secure cookies to desktop, and by payload for mobile.
On my REST API, support both methods of verification - header based and cookie-based - including CSRF protection for the cookie-based approach.
Is there any reason why I wouldn't want to take this approach? I assume if I take XSS on my SPA as a serious risk, then I need a classic login-page for authentication to set the proper cookies because if I do authentication via the SPA, then any XSS attack could potentially intercept that as well (both on mobile and Desktop)! However, on mobile, I'd need to inject the JWT into SPA, maybe through some custom DOM element (meta tag?), but at that point I can just let the SPA perform the login and not consider XSS a threat on mobile devices. Cordova packages all assets into the install package so that's somewhat better but then why not take the same approach on the Desktop version?
My application takes very little user input, it is primarily a dashboard/reporting tool. There will be a "message center" but it's content should always be user-created (by only that user) and sanitized. In my use-case then, would it be ok to deviate from "best practices" and rely on localStorage not counting XSS as a serious risk for my SPA? This would simplify this entire thing (use HTML5 sessionStorage as originally planned) and reduce complexity, which would reduce attack surface for potential security blunders. I just want to make sure I understand the risks before moving forward.
Is there no secure way to make this secure other than by building a native app for mobile and not using Cordova to convert my SPA to a mobile app? I'd hate for this to be the case, but it might very well be.
I'd appreciate all thoughts on the matter!
When thinking of designing javascript based cross-platform applications to run a mobile device, many of the caveats with designing regular web browser based applications do not necessarily apply.
As far as security is concerned, whether you decide to use JWT or simple OAuth tokens, ensure that all your communications are via https.
Please use localStorage as much as you want.
If you consider the anatomy of a http request, all it really is sending some text based message divided into multiple sections to a server. The header of the request is no more secure than any other part of it including the cookies. So the points of interest from a security perspective are generation/validation/invalidation of the token, storage of the token on the device and the transport mechanism of the requests.
Generation/Validation/Invalidation: Generate the tokens on your server. Use some technology/strategy to ensure that there is no possibility for collisions or bleeding. Also, ensure that your strategy will allow you invalidate a token on the server which then subsequently denies access to data requested from the server on further usage of the token. It is then up to you in your app to handle the users UI journey when the server denies access to resources.
How you store the token on the device is constrained to what the device OS make makes available to you. Regarding whether using a native app is better than cross-platform, I think creating a native-cordova plugin to store your token using any specific native strategy if one is unsatisfied with the "out of the box" ones (such as local storage) is possible, although in my experience this is usually overkill. Happy to be corrected on this one if anyone has a different experience.
Please use HTTPS ALWAYS without exception for ALL Webservice end point communications. Is HTTPS foolproof, NO, but you wouldn't build a house without a front door simply because dedicated burglars could learn to pick locks. This secures the transport mechanism considerably.
Usually, this is all native apps have to work with too anyway.
I've created a website within the company that utilizes our active directory server to authenticate. I am concerned about security surrounding setting up relying parties with "localhost" domains.
I've pretty much followed this guide on setup. You'll notice about halfway down the page, there is a step to set up the development environment, localhost:44336 as a relying party.
I am concerned that someone could easily get the location of our federation metadata document, and simply roll their own project utilizing the same port and get access to our active directory. Is this a valid concern, or am I worrying over nothing? What would be a better alternative to having to use localhost in this configuration?
Yes it's safe. The metadata document only describes information about endpoints and about the token that active directory is issuing. It doesn't inherently have anything sensitive about it.
The actual authentication is still going to be handled by AD and unless the curious user already has a way to successfully authenticate against your AD then it's rather useless for him to hookup into that document.
Could they potentially create an app that uses your authentication protocol? Sure, but what would be the point if nobody can actually authenticate against it. Allowing this sort of behavior to happen is one of the points of ADFS.
I've created a angularjs app which uses php for handling the database queries and enforcing an authentication schema.
When the user logs in into the app, he does so in php and php fetches the user data into a session. Then angularjs issues a http post request to a php page to read the fetched data.
After that, whenever a user asks for data, angular issues a post to a php page.
I'm considering using a framework for doing the authentication and the database queries in a better way. My security knowledge is primitive and I fear that I have mistakes in my code.
After doing a research I found laravel which seems straightforward and easy.
Now my questions are:
Can a php framework such as laravel do these things for me?
Is there something else I could use to have people authenticate and making sure that they are doing the CRUD operations they are authorized to do?
What are the keywords I'm searching about, is it routing, is it php restful? I'm asking in order to do further research on the matter.
Is there any other way in which a SPA could work with CRUD operations and Authenticating in a "safe" manner using php?
I know that the above questions are not programming questions per se, but I don't know where to ask (because I feel I cannot communicate what I want to learn about/ *that's why the keywords question above).
Thank you
There's basically two kinds of relevant "routing" both based on URLs, either client side or server side. AngularJS has the $routeProvider which you can configure so when the location changes (handled by $location) the client side template and controller being used also change. On the server side you may have redirects or "routes" that map a URL to a particular PHP file (or Java method) where at the destination it parses the incoming URL to get extra information/parameters.
I know nothing about laravel, but googling laravel and authentication came back with this which looks promising:
http://bundles.laravel.com/category/authentication
I also know things like Zend framework provide many similar options for plugging in some authentication code.
Ultimately if you're writing the CRUD operations something in your code is going to have to do deal with the role based execution of code or access to data.
RESTful is it's own thing. At a very basic level a RESTful interface uses HTTP "verbs/vocuabulary" like PUT, POST, DELETE, GET (part of the request headers which is just data that comes before any body data in the request) are given special meaning like update an entry etc. It's mostly orthogonal to the issue of authentication though if you do true REST I'm not sure if using the SESSION for maintaining authentication would be allowed since it's not completely stateless in that case (anyhow just an academic argument). Point being you can use the other ideas of REST or use some implementation that is "RESTful" and it can be written in any language or you can choose not to do this, either way you still have the issue of controlling resources (functions/methods/data) that you want to control and this issue is not the same as choosing RESTful or not RESTful (if you wanted to keep true to REST for reasons of scalability across a cluster of servers etc. you could follow guidance here How do I authenticate user in REST web service?). Also to note here the $resource in AngularJS provides an abstraction above $http specifically for handling restful services.
IMHO you should be searching for two things
1 php security/authentication
2 php hacking/hacks/vulnerabilities
You can simply write your own authentication mechanism using a session to keep track of the signed in user. http://php.net/manual/en/features.sessions.php There is no difference in a SPA vs a traditional web app as far as the server is concerned, these are simply differences in the client side code.
Any security you intend on putting in place is really only as good as your understanding of that security. I wouldn't trust someone else's plugin from the internet to handle authentication for me unless time was an extremely critical factor and security not so much. One thing that you hadn't mentioned but I think is worth looking into and necessary for any of this to really be secure is SSL. If you don't have your data encrypted there is always a possibility of a man in the middle attack (someone getting the plaintext username and password as their submitted to the database) or session hijacking (someone getting the sessionid of an active session then using that to act as the original user). Basically I would suggest you keep doing research regarding best practices and personally look over any code you plan to use to be sure you understand how it's working and what kind of security it provides you with.
I also wanted to mention, though it's a bit off topic languages wise, that Java Spring has some really nice stuff for dealing with authentication and handling access to services and data. If security is a major concern I would probably strongly consider running a Java server (not to say Java has never had it's issues or that it's automatically more secure but there's a lot of production code that has withstood the test of time). There's the free Tomcat J2EE Server or IBM WebSphere if you need to massively distribute an application. If interested search for Java, Spring, Hibernate (ORM), MyBatis, Data Access Objects. Those are all the parts (some optional) I can think of you would need to put together a service layer in Java. Good intro in the video on the left of this page:
http://static.springsource.org/spring-security/site/index.html
Also SSL isn't a silver bullet, but every layer of security helps.
Kevin Mitnick said in one of his books that lots of places have "hard-shell candy security" (paraphrasing) where breaking the outer layer means you get to all the mushy goodness inside. Any direct answer I would bank will result in this type of security.
Depending on the scope of the project it might be necessary to have security professionals do penetration testing on the system to determine if there are vulnerabilities so they can be plugged.