I am working on an academic project where i need to provide SCDF as a SaaS. So different users should be able to connect to their SCDF and access, deploy, and manage their streams and tasks. Of course, other users shouldn't access those private streams and tasks.
From my different readings i found that SCDF has some LDAP capabilities and i even found that a single user mode is used by default. However, from what i understood, the LDAP is used to authenticate servers and not users, and i am not sure if the user content separation exists.
If there is a user management, can you orient me or provide me with some relevant readings and material. Otherwise, can you give me tips on the "best" way to implement such an option.
For multi user management, you can use file based authentication supported in SCDF.
Sample configuration would look like this:
security:
basic:
enabled: true
realm: Spring Cloud Data Flow
dataflow:
security:
authentication:
file:
enabled: true
users:
bob: bobspassword, ROLE_ADMIN
alice: alicepwd, ROLE_VIEW, ROLE_CREATE
Related
I have used spring security in the past and understand that most of the features of keycloak can be achieved by using spring security ( ldap integration etc ).
Apart from easy social media login validation, are there any other unique features in key cloak which cannot be done using spring security?
With spring-security you would have to create Spring authentication server and explicitly configure/code certain things for integration with LDAP, OAuth2/OIDC providers.
Keycloak is already OAuth2/OIDC/SAMPL compliant IAM provider. It provides features like User Federation with options like LDAP, integration with other OIDC provider etc.
Keycloak provides SPI integration points where you can customize the request flow, use OTP, perform two factor authentication, add google CAPTCHA, or even your CAPTCHA. It provides role based authorization too if you need.
It also provides event handling integration points for events like Login, logout, refresh token, etc.
Keycloak Community will keep adding new features or keep supporting it w.r.t. changes in OAuth2, OIDC, SAML. You don't need to worry about updating your code time to time. Along with this, security updates will be there.
There are many more features.
Most importantly, why reinvent the wheel, if you get these many features and good support.
Keycloak allows you:
to use multiple user storage and get users from multiple LDAP/AD or Kerberos or use without any LDAP.
to login once (SSO) and forget about to login from another application with GUI;
to use one authorization server for multiple application by separation them by realms. One thing should be noted: keycloak could be installed on multiple nodes for better reliability; This also could helpful when application become big and once you decide to separate it on multiple.
to add user additional attributes and fields during get user info without coding (trivial example - set phone number) or specific roles (on realm or even client level) or groups and use all this on the top of an AD attributes;
to configure password rules like password expiration, e-mail validation and so on;
to set up 2-factor authorization with SMS or Email.
These things I think could be implemented using Spring Security, but it takes more time than Keycloak installation and configuration. Personally, I am using Keycloak in multiple commercial projects and could claim that Keycloak is good.
What is the benefit of implementing Active Directory based Security to servers like Jenkins?
The only benefit I can think is the admin of the sever does not need to add/remove users because user can login themselves using AD credential.
But In my case I do not want to have the whole company access my server. the server is only used by my team. How can I disable the whole company from login in. (case1)
Besides, I want to grant different permissions to different members in my team. The new members get less permission, the experienced team members get more permissions. I believe this is very common. But using Active Directory based Security looks like they get the same permission because they are in the same groups (case2)
So why should I use Active Directory based Security? Can I resolve the above two cases in a server configured with Active Directory based Security?
Some corporate environments make this a security requirement. In said environments they usually have an internal request system where users can request they have their credentials added to an appropriate group for access to Jenkins. This is better than Jenkins own database and having them email you, the Jenkins administrator.
Once AD Authentication is configured in Jenkins and appropriate groups created in AD you can do a one-time setup of those groups with the Role-Based Strategy plugin in Jenkins and define what those groups have authorization to do.
Plan your groups well and it is a function that you will no longer have to worry about.
Warning: Be very careful when switching over from Jenkins own database user authentication to AD authentication. If you don't get the BindDN details just right you can get locked out.
SCDF Server for Cloudfoundry: 1.2.4.RELEASE
Configuring the security properties for LDAP authentication, and I have the authentication part working, but authorization is proving a little strange.
SCDF's security implementation appears to be looking for some roles like this:
ROLE_CREATE, ROLE_MANAGE, ROLE_VIEW.
But for me, the standard group names require some specific naming convention in AD similar to the following: app_myapplication_authz_CREATE, app_myapplication_authz_MANAGE, and app_myapplication_authz_VIEW
When I debug through the SCDF authentication output, I can see that my authenticated principal's group memberships are being retrieved correctly. They show up in the DEBUG output as: ROLE_APP_MYAPPLICATION_AUTHZ_CREATE, ROLE_APP_MYAPPLICATION_AUTHZ_MANAGE, ROLE_APP_MYAPPLICATION_AUTHZ_VIEW
Now, I include a YML security configuration that looks like this:
spring:
cloud:
dataflow:
security:
authorization:
enabled: true
rules:
- GET /metrics/streams => hasRole('ROLE_APP_MYAPPLICATION_AUTHZ_VIEW')
- POST /apps/** => hasRole('ROLE_APP_MYAPPLICATION_AUTHZ_CREATE')
- etc, etc, etc
And so on, for all the endpoint authorizations.
However, I'm still receiving a message after successful authentication that I don't have the appropriate roles and I need to talk to my administrator.
What am I misconfiguring, or what am I missing in this setup?
Update
I downloaded the source code for the 1.2.1.RELEASE version of the spring cloud dataflow ui from here: GitHub spring-cloud-dataflow-ui
And discovered that in all the .html view files, the role names are hard-coded for ROLE_VIEW, ROLE_CREATE, ROLE_MANAGE. Thus, it looks like my configuration will allow me to customize the authorization on the REST endpoints based on my LDAP group names, but I will not be able to do the same with the actual UI views. I think I have one option here, which would be to build/generate my own custom version of the UI, and bundle that with the spring-cloud-dataflow-server JAR instead of using the OOTB ui.
I'll have to weigh whether I really want to do that.
We don't yet have the direct mapping of LDAP AD Groups <-> SCDF Roles. We haven't had anyone from the community or customers' ask for this integration, though. UAA backed OAuth turns out to be the popular choice in PCF so far.
That said, I created spring-cloud/spring-cloud-dataflow#2084 to track the support for group mapping. It could be trivial to implement it (Group vs. ROLE mapping in YAML and parsing logic in the backend code); I marked it for 1.5, but we may pick it up sooner for the 1.4 release next week.
I'd recommend not venturing into adjusting the UI code directly, though. Too much on the local fork and you'll have to maintain it.
We are running RabbitMQ 3.6.5 in a Windows environment and are using the LDAP plugin. This allows our developers to view the queues and inspect the messages. By default, the RabbitMQ LDAP plugin allows "all users to access all objects in all vhosts" (as documented here). This includes the ability to publish messages directly from the LDAP plugin. What we would like to do is deny this permission to LDAP users, while still allowing them to see the queues.
According to the LDAP plugin page, this is accomplished by inserting Erlang queries into the RabbitMQ configuration. Using the examples on that page, we first tried simply granting read permission with this query (LDAP specifics changed):
{resource_access_query,
{for, [{permission, configure, {in_group, "OU=someGroup,OU=Departments,OU=ABC,DC=ABC,DC=ORG"}},
{permission, read, {constant, true}}
]
}}
When that had no effect, we tried explicitly denying write permissions:
{resource_access_query,
{for, [{resource, queue, {for, [{permission, configure,
{in_group, "OU=someGroup,OU=Departments,OU=ABC,DC=ABC,DC=ORG"}
},
{permission, write, {constant, false}},
{permission, read, {constant, true}}
]}},
]}}
Unfortunately that had no effect either. In both cases, LDAP users were still able to publish messages in the LDAP plugin.
Does anybody know what we are missing?
The RabbitMQ team monitors this mailing list and only sometimes answers questions on StackOverflow.
You need to read the RabbitMQ Access Control guide as well, specifically this section. Messages are published to Exchanges in RabbitMQ, not Queues, via the basic.publish AMQP 0.9.1 method. In your case deny write permission to the exchange resource and grant read permission to the queue resource.
Once you have configured the LDAP plugin correctly, I strongly recommend enabling the auth cache plugin. Otherwise, LDAP queries will be made when every message is published or read, as well as all other operations requiring authorization.
I have a Rails app acting as an OAuth 2.0 provider (using the oauth2-provider gem). It stores all the information related to users (accounts, personal information, and roles). There are 2 client apps that both authenticate through this app. The client apps can use the client_credentials grant type to find users by email and do other things that don't require an authorization code. Users can also log in to the client apps using the password grant type.
Now the issue we're facing is that the users' roles are defined globally on the resource host. So if a user is given an admin role on the resource host, that user is admin on both clients. My question is: what should we do to have more fine-grained access control? I.e. a user can be an editor for app1 but not for app2.
I guess the easy way to do this would be to change the role names like so: app1-admin, app2-admin, app1-editor, app2-editor, etc. The bigger question is: are we implementing this whole system correctly; that is, should we be storing so much info on the resource host, or should we denormalize the data onto the client apps?
A denormalized architecture would look like this: all user data on the resource host, localized user data on each client host. So user#example.com would have his personal info on the resource host and have his editor role stored on client app1. If he never uses it, app2 could be completely oblivious of his existence.
The drawback to the denormalized model is that there would be a lot of duplication of data (account ids, roles) and code (User and Role models on each client, separate management interfaces, etc.).
Are there any drawbacks to keeping the data separate? The client apps are both highly trusted--we made them both--but we are likely to add additional client apps, which are not under our control, in the future.
The most proper way to use oAuth and other similar external Authorization methods as I see it, is for strictly Authentication purposes. All the business/authorization logic should be handled on your server part at all times, and you should always keep a central record of the user, linking to the external info per external type of auth service.
Having a multilevel/multipart set of access, is also a must, if you want your setup to be scalable and future-proof. This is a standard design that is separate from any authorization logic and always in direct relation to business rules.
Stackoverflow does something like this, asking you to create an actual account on the site after you login using an external method.
Update: If the sites are really similar you can subset this design to an object per application that keeps the application specific access rules. This object has to also inherit from a global object that has global rules (thus you can for example impose a ban application-wide or enterprise-wide).
I would go for objects that contain acess settings, and roles that can be related to instances of both application level settings and global settings only for automating/compacting the assignment of access.
Actually you can use this design even if they are not too similar. This will help you avoid redundant settings and meaningless (business-wise) roles. You can identify a role purely by the job title/purpose, and then impose your restrictions by linking to an appropriate acess settings setup.