eclipse-archived / smarthome

Eclipse SmartHome™ project
https://www.eclipse.org/smarthome/
Eclipse Public License 2.0
862 stars 786 forks source link

Add support for conditional access based on user role #579

Open kaikreuzer opened 8 years ago

kaikreuzer commented 8 years ago

migrated from Bugzilla #423548 status NEW severity enhancement in component Core for --- Reported in version unspecified on platform PC Assigned to: Project Inbox

On 2013-12-08 15:16:18 -0500, Kai Kreuzer wrote:

Migrated from https://code.google.com/p/openhab/issues/detail?id=387

On 2015-09-25 03:52:04 -0400, Kai Kreuzer wrote:

Some input from my side what I see should be covered. There are multiple levels of access control that can be addressed:

  1. Global access control as it is done in openHAB 1 (see https://github.com/openhab/openhab/wiki/Security#authentication). I.e. for any access to the runtime, the user needs credentials and is then assigned a role. JAAS is probably a good option here. Note that the solution has to work in general for any OSGi HttpService, it must not be specific to Jetty (while in openHAB 2, we can add a Jetty-specific configuration for JAAS then).
  2. Restrict certain urls and/or http verbs for certain roles. See the example discussed in https://www.eclipse.org/forums/index.php/t/1068387/.
  3. Restrict access on certain data, e.g. return a HTTP 403 when my kids try to access localhost:8080/classicui/app?sitemap=admin. This could be implemented in phases, the most important resource would be sitemaps, then come items, things, rules, etc. But in general this mechanism should be available on all resources. Configuration of such restrictions should not only be by resource name, but possibly also by type/tag, e.g. do not grant access to any item that is tagged as "security".
  4. Filter data within requests, i.e. if I do not have rights for sitemap "admin" (see 3), the REST url /rest/sitemaps should not even list it. Sitemaps that refer to items that I am not allowed to access should filter out these widgets automatically.
  5. Check implications on automation rules. Normally, rules are executed by the system and not the user. But we could imagine that a trigger was caused by some user (e.g. an item state change) and thus the rule could be regarded to be executed on behalf of this user - then again, the permissions should be checked and e.g. sending commands to restricted items must be blocked.

Does anybody has further ideas/requirements?

GradyD commented 8 years ago

I'd like to see a way to use my google account, so support for external OAuth2 providers.

It would also be nice to open up a guest mode if you are connected locally but not expose that externally.

ozel commented 8 years ago

+1 for Global access control as it is done in openHAB. we want to use openhab2 in an organization-wide newtork do to show control for visit points and exhibitions.

kaikreuzer commented 8 years ago

@ozel Does that mean your are volunteering for implementing it? :-)

ozel commented 8 years ago

@kaikreuzer sorry, that's way out of my skills. I come from an embedded C world with precicely defined typing etc. and struggle a lot these days in just getting my openHab java rules working relibaly... However, I follow https://community.openhab.org/t/authentication-in-oh2/1723/24 and as soon as there's something to test I'll volunteer for that

splatch commented 8 years ago

Some time ago in my fork I added few classes which could potentialy cover authentication support in ESH. Main purpose is to avoid any specific framework for handling that and letting vendors customize with their own choice. For this reason even JAAS is not enforced, however could be used to implement basic login.

Linked commit introduces following structures:

In perfect world internal code should utilize Authentication object to calculate access and visibility to items, that's why I put all auth-related stuff in core bundle. Authentication object should be also kept in HTTP session to avoid resending credentials with every requests (to deny usage of basic/digest scheme).

digitaldan commented 8 years ago

@splatch do you know how would this be enforced in the addons/bundles? I was playing around with implementing simple http based auth this morning. The only way I could successfully do this in a standard way was to create a custom HttpContext object that implements the "handleSecurity" function.

My knowledge of OSGI dependency injection is zero, it would be nice if the call to the "createDefaultHttpContext()" which all bindings with rest endpoints seem to use would return a context that does authentication (and could redirect to your bundle)

kaikreuzer commented 8 years ago

@splatch Your concept looks good to me, I think it is a good starting point for tackling this feature - so feel free to create a PR with it and a basic implementation of the providers and resources.

@digitaldan I think nothing speaks against introducing a custom HttpContext that we could provide as a service to all our JAX-RS resources and servlets. The "defaultHttpContext" could still stay the current one which does not require any authentication (we will still need this, e.g. for providing communication endpoints for UPnP, the hue emulator, etc.

digitaldan commented 8 years ago

@kaikreuzer sounds good to me. @splatch can't wait to see a simple implementation of this!

splatch commented 8 years ago

@digitaldan @kaikreuzer We will need custom http context anyway, over which we could delegate security checks to underlying Authorization mechanism and verify if access is granted or not. Feel free to add PR with custom context anyway.

kaikreuzer commented 8 years ago

Feel free to add PR with custom context anyway.

PR to where? I thought we are currently waiting for a PR by you here first?

splatch commented 8 years ago

PR to where? I thought we are currently waiting for a PR by you here first?

I will start putting all things together around infrastructure, any help with surroundings is welcome. Maybe @digitaldan will be able to base his PR upon my changes.

digitaldan commented 8 years ago

The HttpContext object is easy:

public class AuthenticatedHttpContext implements HttpContext {

    @Override
    public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    }

    @Override
    public URL getResource(String name) {
        return null;
    }

    @Override
    public String getMimeType(String name) {
        return null;
    }
}

If we want to go this way, 1) what package should this live in, maybe org.eclipse.smarthome.io.rest or org.eclipse.smarthome.core.auth? 2) how should this look up a registered authentication provider and call it inside handleSecurity? 3) this would mean we need to modify all existing bindings to use/import this new class..... is there a better way?

This approach make me a little uneasy b/c there is no global policy and I would hate to expose services accidentally, but I don't think OSGI will allow any other way.

kaikreuzer commented 8 years ago

1) org.eclipse.smarthome.core.auth sounds good to me as it not only applies to the rest interface. 2) Could AuthenticatedHttpContext simply be a service itself (then the auth provider would simply be a mandatory static dependency)? 3) This is imho ok, but I agree that the risk to miss something (e.g. in extensions) is not nice. It would be great to be able to somehow inject this context into httpService.createDefaultHttpContext() - but this is probably only possible through very dirty hacks.

splatch commented 8 years ago

3) This is imho ok, but I agree that the risk to miss something (e.g. in extensions) is not nice. It would be great to be able to somehow inject this context into httpService.createDefaultHttpContext() - but this is probably only possible through very dirty hacks.

I didn't read eclipsesource jaxrs source code too deep, however there is an example with their own security layer which requires registration of AuthenticationHandler and AuthorizationHandler: security example.

kaikreuzer commented 8 years ago

Correct, but this will only cover the REST API, but not any other servlet that might be registered by an extension.

stefanhettich commented 8 years ago

Hello together, I'm also working on your approach while writing my master thesis at university. At the moment I'm trying to understand parts of the OpenHab/ESH Code and got stuck at the point the *.items files where read.

I noticed that at this point xtext is used to parse these files, my question is how to setup my eclipse ide to make changes to the xtext files (e.g. to add a user role/group) to the items. I already installed xtext and imported the missing projects, but they are full of errors (missing references, etc.) and once I include them in the run configuration OpenHab starts throwing exceptions. How can this be fixed?

Thanks in advance.

maggu2810 commented 8 years ago

@neverend92 I don't think your question is really related to this issue. You ask how to setup the IDE (if I understand your comment correctly). For ESH install the Eclipse IDE as described in the ESH documentation and you should be able to change the xtext files (and see the result). For openHAB IDE use the openHAB community board.

stefanhettich commented 8 years ago

Alright sorry for that, I will ask for help with this problem at the openHAB community board...

But then I want to ask you all if the approach to extend the *.items configuration files by user groups, etc. is good. Or if there is a better way to connect items and access control?

maggu2810 commented 8 years ago

I don't know if there has been already some decisions how fine granular the access control should be defined (e.g. REST API access in general, things, channels, items, ...). I don't think it make sense to start with the *.items configuration as long as I can use the REST API to create another item that links to the same channel...

digitaldan commented 8 years ago

Could AuthenticatedHttpContext simply be a service itself

@kaikreuzer are you thinking it would be a service in an existing bundle, or be its own standalone bundle?

kaikreuzer commented 8 years ago

I think it must be a part of the core, just as it is done in here.

marziman commented 8 years ago

Why do we want to create Security concepts / Models by our own. Lets use a framework? @splatch , @digitaldan and @kaikreuzer What speaks against Apache Shiro (http://shiro.apache.org/) ? We may put shiro into a single bundle which than exports a SecurityManager as an OSGI service (other bindings could import and use it). It also fits well to Karaf... as I remember from my investigations for Authentication, there is a Karaf feature for OSGi integration. Shiro has easy API's for authentication, authorization, cryptography, and session management + can be deployed inside a OSGI container Not sure how thin shiro is, but its worth to check it out..

digitaldan commented 8 years ago

Thank @marziman , I'll take a look at Shiro, have not used it in the past, it would be great not to reinvent the wheel, especially with security.

kaikreuzer commented 8 years ago

@marziman I came across Shiro quite a while ago and thought that this could be interesting. So I agree that we should have a closer look. I so far cannot judge how well it integrates with Pax-Web, Java-servlets and Jersey.

splatch commented 8 years ago

Why do we want to create Security concepts / Models by our own. Lets use a framework?

My main concern on that is bringing external dependency to our more or less dependency less core artifacts. That's why I based on very similar basis as security frameworks so they could be wired in when needed. It was not intented to build everything from scrach but rather adapt existing solution in the way that anyone have freedom of choice.

it would be great not to reinvent the wheel, especially with security.

Currently in Java land there is no security standard other than JAAS. This is the simplest thing we could have, however it brings it's own set of troubles. Anything else than JAAS is in fact - reiventing the wheel. If you will take a look on all security frameworks made in Java - starting from Acegi over Spring Security up to Shiro - they all claim to provide comprehensive security framework. But if Acegi would do it properly in first place I think nobody else would start Shiro. And I'm pretty sure there are other implementations which yet we don't know. This is double edged sword.

marziman commented 8 years ago

@splatch, I think your Security Idea is good and appretiate your concept. But we really should investigate first. Iam not dogmatic and dont want to force it. I just got the feeling that this Framework will be good for our requirements. I had no time to make a prototype or sth. like that to say anything about ext. dependencies, but we may think about NOT putting it into the core and making a standalone SecurityManager bundle. We could bring it later to the core, too. Your concerns are valid, so if we know we have 2 or more Security Frameworks we want to make usable, than we could create a more general OH Interface abstracting this by e.g. your Security concept. But for the time being I cant see that. I would wait for @digitaldan and his feedback. Is that fine for you guys?

digitaldan commented 8 years ago

Well I'm no expert on Java security (nor OSGI), I have used JAAS in the past (years and years ago) and remember fighting it constantly every time a corner case came up. I'm sure Shiro has its own "quirks" too. IMHO authentication is becoming one of the major roadblocks to users adopting OH2, so I think this is becoming more urgent to get done soon. @splatch are you still working on submitting your proposal? I would hope there would also be a simple example implementation of it as well.

kaikreuzer commented 8 years ago

@splatch are you still working on submitting your proposal?

Any news here? I'd also be very interested to get a PR for that soon!

splatch commented 8 years ago

@kaikreuzer It should be fine to merge it, however I didn't have enought of time to attempt implementation of this SPI thus futher changes may be necessary. I think it's safer to submit complete pull request. From other hand I've done an example of smarthome rest services running together with CXF which allowed to support JAAS security out of the box.

kaikreuzer commented 8 years ago

I think it's safer to submit complete pull request.

Fine with that as long as you are still planning to work on this and create such a PR in the not too distant future :-)

gnalbandian commented 7 years ago

Have there been any progress on this matter?

splatch commented 7 years ago

@gnalbandian I pushet a bit more code in my branch, but it is still far from calling it complete. As far I know there is new part in manual on how to get authentication setup with nginx.

kaikreuzer commented 7 years ago

@splatch It would be great if we could again more actively look into this. It is one of the few last missing features that is required before openHAB 2.0 can be released. So I would very much hope that we can come up with at least a basic starting point (to at least use credentials globally, similar to what openHAB 1 offered). Feel free to create an unfinished PR as a starting point for further discussion!

splatch commented 7 years ago

@kaikreuzer I will try to get last step on this sunday and wire in authentication into jaxrs publisher. This should close gap for now.

splatch commented 7 years ago

@kaikreuzer Just to let you know - I pushed to esh-authz branch complete code which provides basic authentication based on dummy AuthenticationProvider implementation (user: test, pwd test123).

I wired it into rest layer, so all resources with javax.annotation.security.RolesAllowed gets automatically protected. This is early stage and I must port authentication backend to something more configurable (such JAAS mentioned earlier in this topic), to let people manage their user base.

kaikreuzer commented 7 years ago

@splatch This sounds (and looks) pretty good! Looking forward to your PR and I will look into its details then!

kaikreuzer commented 7 years ago

@splatch Ping!

splatch commented 7 years ago

I rebased code to latest master and pushed jaas auth code to branch (should work with any login module based on user+password credentials). Didn't have time to test it yet. I will test it over coming days, wrap it into single PR and let others pick it up and continue or bury it.

Sorry it takes so long, my daily work consumes all time I could have and I doubt if it will change until end of November.

splatch commented 7 years ago

As promissed - tested PR: https://github.com/eclipse/smarthome/pull/2359 - still have some IP to clarify (I've used different mail address long time ago in eclipse.org).

kaikreuzer commented 7 years ago

Many thanks! Will try to review and test it very soon!

marziman commented 7 years ago

@splatch thx! @kaikreuzer did you review and test it?

kaikreuzer commented 7 years ago

@marziman Check https://github.com/eclipse/smarthome/pull/2359#pullrequestreview-7199655

madte commented 7 years ago

Hello ESH developers, I am currently working on my master thesis "Towards a secure wireless smart home - design and implementation" at the Freie Universität Berlin. I chose openHAB as base for the protoype I am going to implement during the thesis. One very important aspect regarding a secure smart home is the protection against unauthorized resource access through the enforcement of an access control policy. The idea so far is to add an fine-grained access control mechanism to openHAB, i.e. access rights are bound to items.
Based on the scientific literature about smart home access control I read so far, i think it would desireable to have an Attribute-Based Access Control (ABAC) mechanism. This allows to control access on ressources based on users/roles and attributes that are connected by boolean logic. E.g. User X with role Y can access {r,w,rw} item Z if {boolean expression with attributes}. To give a more concrete usage example in the smart home scenario: User Alice with role guest can unlock the front door if a family member is at home and the time is between 8am and 8pm. Some further thoughts about integrating access control in openHAB: A thing has at least one owner. Owner of a thing can set access rights {no access,r,w,rw} on the thing´s items for other users/roles. Users only see an item in their sitemap if they have access. Also they only can define rules based on items according to their rights on the items. Logs also need to be separated, users only see logged events of items they have access to. While there are still many details missing, I hope to receive feedback on the general concept I briefly explained here. Would there be interest in such a contribution? Additionally, a rough estimation about the feasibility and complexity of integrating such a concept into openHAB/ESH would be helpful, as my knowledge about the used technologies and architecture is not very deep at this stage.

Thanks and best regards, Martin Kessel

kaikreuzer commented 7 years ago

Hi @madte and sorry for my late reply!

What you describe reminds me of a new Eclipse project proposal: https://projects.eclipse.org/proposals/eclipse-keti They are doing an ABAC system, but it seems to me that it won't be easily integratable into the Eclipse SmartHome stack, but would rather have to be deployed as a separate process that proxies requests to the ESH REST API - not really ideal.

Building an ABAC mechanism yourself from scratch imho exceeds the scope of a master thesis. I'd call it the "Porsche" wrt the requirements and implementation options that I outlined above.

Would there be interest in such a contribution?

Any contribution that brings value is welcome. I am just not sure how "academic" this approach is or if users in the end really want to use it - you can easily get into a configuration hell if you do not remember what rights you gave whom for which situation. And it probably has to be introduced deep in the core code, so it cannot be designed to be as an optional bundle that interested people would use while others can leave it away.

Did you already dive into the code and have some rough concepts to share on how you would want to address your topic?

madte commented 7 years ago

Hi kaikreuzer, also have to excuse my slow reply! I wasn´t involved much with Access Control lately as I am currently working on secure session establishment, e.g. pairing/comissioning and communication encryption for that I btw develop a CoAP binding with optional DTLS support which I want to commit to the OH2 project when it´s done.

To your questions:

I am just not sure how "academic" this approach is or if users in the end really want to use it

I think even ABAC is a rather complex AC mechanism, this doesn´t need to lead to a complex setup for the users. After adding a thing, there can be a default configuration of it´s access rights, e.g. full access for familiy members or exclusive access for the user who added it. Further rights management could be handled over a simple GUI, allowing to delegate rights coarse-grained (thing level) and/or fine-grained (item level) to respective users/roles. Setting up more advanced access control rules that depend on attributes could be optional and done in an extra view/GUI. The complete overview of all the access rights of the smart home can be in the same GUI, available to the administrator user.

Did you already dive into the code and have some rough concepts to share on how you would want to address your topic?

Unfortunately my understanding of openHAB 2's inner workings is still very limited at the moment, as i am currently busy with the above mentioned topics. I was reading this article (url) where they try to extend the ESH concept to support users and roles. I have 3 months left for the thesis, i hope to be able to focus on Access Control in OH2 soon. Providing a full solution of Access Control in code also seems infeasible to me in the available time, as there would probably be many changes neccessary. The minimum goal though is to identify what needs to be changed (how) to integrate Access Control in OH2/ESH, e.g. providing at least a basic concept. What I assume neccessary so far is:

The energy management platform OGEMA 2.0 is also based on OSGi and has a security architecture including user management and access control on the REST interface. Without having a deeper understanding yet i guess this could be helpful: OGEMA Security Technical Notes

I am grateful for any comment on this topic, would be great to receive opinions on this from experienced OH2/ESH developers!

Thanks and best regards, Martin Kessel

kaikreuzer commented 7 years ago

I tried to use the results of https://github.com/eclipse/smarthome/pull/2587 for implementing user authentication in openHAB 2 and failed miserably :-(

Let me briefly mention the main issues I came across so far:

Having had a look at Shiro again, I wonder if the approach to define our own APIs in ESH and potentially map them to 3rd party implementation can actually work out (while I would love if it did!). The issue I see is that it is hardly possible to avoid having dependencies in passed parameters, used annotations, etc. - mapping all of this seems to be pretty infeasible and we might end up re-implementing all of the complexity of a security framework ourselves.

@madte Did you already have chance to look deeper into it? I am afraid we are still far away from assigning users to entities such as items and things, but maybe you have a feeling whether a 3rd party framework might be a blocker for such an endeavor or rather helpful.

@maggu2810, @digitaldan & @splatch, Any preference or suggestion how to best proceed?

marziman commented 7 years ago

@kai,

small note: I proposed Shiro long time ago in this topic. There it was said it could introduce "dependencies" and it looks likeno one investigated Shiro usage for OH. Thats pretty strange to me. Since we know found out that our "own" kind of Security approach also creates dependencies and has his cons. So again why we dont first look into enabling the usage of Shiro? You didnt ask for my opinion but I feel like that we just followed one way of possibly solving this. If nobody goes to check out Shiro, I can do it.

BR Mehmet

splatch commented 7 years ago

I've used both shiro and spring security 3.x/4.x. I did use first one in basic web application, I know it is used in Sonatype's Nexus (starting from 3.x also hosted on karaf), second one in web apps and also for past years in OSGi environment. For my client I implemented spring security based authentication mechanism and bridged it to CXF via interceptors. We bridged also karaf JAAS login module for developers and two proprietary security provider implementations (password and shared token) for clients. On top of CXF we also have dedicated interceptors for token handling and token service implementation which keeps session information in cassandra (this was done before spring-session project was launched). All is working for three years with "rich internet application" in front, bunch of REST services on Karaf 2.3. Just last year we started porting it to Spring Security 4.x, Karaf 4.x. It was more or less smooth and been limited to internal changes inside Spring Security itself. For us going with Spring was quite easy because Karaf always supported it, and with little bit of work we managed to get it working with blueprint as well. But I am aware that for custom distributions built around equinox, without Karaf, this might be pure nightmare since Interface21/SpringSource/Pivotal stopped to publish osgi metadata inside their JARs and wrapping is necessary. Keeping in mind that ESH is on Tycho build which requires p2 repos and is quite painfull for managing external dependencies other way than just copying them to lib/ folders like in early 2000's I was far from proposing it.

Current work with abstracting Authentication and AuthenticationProvider was intended to avoid polluting everything with spring or shiro specific stuff. Also knowing quite low (at this moment) security needs bounded to user/password and basic role access and limitations of declarative services used in all places which limits AOP usage this allowed to fulfill gap between any framework needs and smart home requirements. Because mixture of JAX-RS and servlets and different abstractions (such icon providers) hosting data security been applied only at REST level. All other places needs to be bridged this way or another and code will be pretty much the same regardless of usage of Shiro or custom mechanism. You can plug in Shiro's JAX-RS filter inside eclipse-source-jaxrs hosted app and yet another Shiro http filter on top of existing servlets if you will know http context used for registering last ones. However propagating security context information between these places will always require client application to copy some kind of marker and shared session/token/auth information store. This won't be possible without client keeping token/session id or just a cookie.

I can try to provide example http filter implementation which will allow you to secure user interfaces as well, but first I have to digg a little bit more around pax web to source http context used for registering servlets. Good thing is this this part will be the same regardles of selected tool. Sadly I can not exchange spring security implementation I've done in other place to give starting point for reviewing other options.

marziman commented 7 years ago

@splatch do you think we should further investigate Shiro as base Framework with wrapping API around? As you mentioned some experience from other projects..what would be the blocker from your point of view?

splatch commented 7 years ago

There is no blocker from my side. Shiro is fine thing to start with. Back in early 2014 we decided not to use it because development seemed to be slowed down with one patch release every year. Spring offered experimental kerberos integration (which we never used btw) and didn't require too much wrapping. Both frameworks back then have had poor separation of api and core bringing too many dependencies to manage everywhere. We do have basic API wrapping over REST with DTOs transformed into Spring Security structures such UsernamePasswordAuthenticationToken. I aimed similar way for OH but I did first implementation with JAAS+http basic without any session handling. I think it is still possible to do, with open question how much of wrapping will be needed. Hooking in Shiro should not be a problem once all necessray places are bridged. What is left to do is session intercepting and session store interface. AuthenticationProvider can be already adapted directly to Shiro's Subject calls. You can also take a look on Nexus work: https://github.com/sonatype/nexus-public/tree/master/components/nexus-security. Just don't be scared by amount of abstractions applied on top of it. :-) What I propose is masking SecurityContext and ThreadLocal structures keeping auth with simple SecurityContextProvider or something like that which can be mocked during tests.