Currently Artemis the has ActiveMQSecurityManager4. It gives a lot of control when using the following method:
/**
* Determine whether the given user is valid and whether they have
* the correct role for the given destination address.
*
* This method is called instead of
* {#link ActiveMQSecurityManager#validateUserAndRole(String, String, Set, CheckType)}.
*
* #param user the user
* #param password the user's password
* #param roles the user's roles
* #param checkType which permission to validate
* #param address the address for which to perform authorization
* #param remotingConnection the user's connection
* #param securityDomain the name of the JAAS security domain to use (can be null)
* #return the name of the validated user or null if the user isn't validated
*/
String validateUserAndRole(String user,
String password,
Set<Role> roles,
CheckType checkType,
String address,
RemotingConnection remotingConnection,
String securityDomain);
When a client connects and tries to create a subscription is there a way to know what is his ClientID/Subscription Name? (CheckType=CREATE_DURABLE_QUEUE over address="org.activemq.premium.news" )
I want to have control who is allowed to subscribe a given address (TOPIC) and guarantee that a subscription belongs to the initial (authenticated) subscriber.
EDIT 1:
The caller method has the queue (clientID+subs name) but I don't think It can be extended.
/**
* The ActiveMQ Artemis SecurityStore implementation
*/
public class SecurityStoreImpl implements SecurityStore, HierarchicalRepositoryChangeListener {
...
#Override
public void check(final SimpleString address,
final SimpleString queue, //exactly what I was looking for
final CheckType checkType,
final SecurityAuth session) throws Exception {
...
EDIT 2:
Scenario
I have Bob (user:bob, pass: bob) and Alice (user:Alice, pass:Alice) and each one will create their connection to the broker to subscribe let's say address="org.activemq.premium.news". So far I can block one of them from reaching the address, which is not bad. Now I want both to subscribe (each one will have a queue) but I want to make sure the Bob's subscription is named "bob" and Alice's subscription is named "alice". I don't want that if Alice subscribes first it uses "bob" as subscription name. Also not sure if the spec guaranties that after the initial subscription from Bob, if he is not connected Alice cannot use his subscription name to consume his messages - i.e. subscription queue is bound to that user.
I think what you want to do was already addressed via ARTEMIS-592. You just need to concatenate the address and queue name with a . character in your related security-setting in broker.xml. Be sure to put the users which should be isolated in different groups.
To be clear, you don't need to implement a security manager or plugin or anything like that. You should be able to take care of everything you need just with configuration.
My initial requirement is now possible due to https://issues.apache.org/jira/browse/ARTEMIS-2886 changes.
Related
I have a concept question when it comes to roles. Im not very familiar with database design or access control. Let's say i have 4 collections.
Users
Companies
Equipment
Locations
A user can register.
A user will be added to a company.
User gets access to all equipment and locations with the company ID.
What would be a good way to verify that a registered user belongs to a company? I'm thinking manual verification, as not everybody in the company should have access. But any clever thoughts are appreciated.
Collections equipment and locations holds documents belonging to different companies. These collections can get pretty big. Is it wise to have an "Equipment collection" for each company?
Should i create a group for each company and add user to the correct group?
What is the best way to link collections/documents to user/company?
Any other thoughts?
Thank you.
Have you tried using : https://github.com/alanning/meteor-roles
I have used that to verify roles in meteor. There would be an entry in "Companies" Collection thus you can have a Company ID. With the usage of meteor roles , I think it would be easy to do your task. In Example.
User Collection would have :
_id:
Name:
Role : [ //owner , employee ]
Company ID:
it is up to you if you would make roles and company ids an array to handle multiple companies for a single user record thus making it alot more flexible in the long run.
Next would be make a helper in your user collection to easily track the roles. IE.
isAdmin(companyId) {
if(isValidRolesData(this.roles,'default-group'))
return this.roles['default-group'].indexOf(`${companyId}-admin`) > -1;
},
/**
* Check if a user is Staff
*
* #param {any} facilityid
* #returns
*/
isStaff(companyId) {
if(isValidRolesData(this.roles,'default-group'))
return this.roles['default-group'].indexOf(`${companyId}-staff`) > -1;
},
/**
* Check if a user is Receptionist
*
* #param {any} facilityid
* #returns
*/
isReceptionist(companyId) {
if(isValidRolesData(this.roles,'default-group'))
return this.roles['default-group'].indexOf(`${companyId}-receptionist`) > -1;
},
With that kind of flow I guess you can achieve the exact thing you needed :)
So i'm trying to set up my first extension with Typo3 and i'm struggling very much. I want to set up an extension which handles reclamations from customers.
After submitting the input values i'll store the new customer in the database and directly after this step i'll get it back from the database to see which uid he has, to store the uid from the customer in the reclamation.
So i wan't to override the current $customer-variable with
$customer = $this->customerRepository->findByName($name);
The returned result is not really an object of customer even var_dump is saying it is an customer-object. I can't call the function
$customer->getUid()
to get the current uid of this new customer. But i need the uid of the customer in my reclamation-object - how do i do that?
Next problem: every query i ll do to the db like
->findAll(), findByIdentifier($identifier)
is null.
I don't know why. It seems that he can't find the storagePid, but i've set up my TypoScript correctly.
I can only get a query when i add
$query->getQuerySettings()->setRespectStoragePage(FALSE);
any ideas where the dog is buried in this case?
Thank you very much and sorry for my bad english :P
Your initial question is hard to answer without more details. What is the relation between a customer and reclamations? If a customer can have multiple reclamations, it would be good to have an 1:n relation between customer and reclamations. In that case, you can just do $customer->addReclamation($reclamation) and don't need to take care about user UIDs.
As for your repository call, the problem is that your call gets you a QueryResult containing all matching objects. If name is really a unique property, you can do
$customer = $this->customerRepository->findOneByName($name);
This looks for all customers with name equals $name (which should be only one) and returns the first one, so you get back a Customer object.
But this is not really necessary, too: If you persist all changes after adding the customer, you can get its UID:
$this->customerRepository->add($customer);
$this->persistenceManager->persistAll();
// Returns the customer uid
$customerUid = $customer->getUid();
The persistenceManager can be injected like this:
/**
* #var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
* #inject
*/
protected $persistenceManager;
I use Doctrine and MongoDB ODM modules at my zf2 application. ZfcUser is used for authorization.
Is there a way to use two collections, say users and clients to authenticate via zfcuser+doctrine? I am curious, if there is a way to combine two mongo collections into one to use combined for authentication?
You do not need to merge the users into one collection as you can have multiple 'authentication adapters' (see ZfcUser\Authentication\Adapter\Db for an example)
These are defined within global config file: zfcuser.global.php
Each of my adapters are run in order of priority until one returns a successful authentication result.
For example; I have the following configuration for Users and Candidates entities.
/**
* Authentication Adapters
*
* Specify the adapters that will be used to try and authenticate the user
*
* Default value: array containing 'ZfcUser\Authentication\Adapter\Db' with priority 100
* Accepted values: array containing services that implement 'ZfcUser\Authentication\Adapter\ChainableAdapter'
*/
'auth_adapters' => array(
50 => 'JobboardCandidate\Authentication\Adapter\CandidateDatabaseAdapter',
75 => 'JobboardUser\Authentication\Adapter\UserDatabaseAdapter',
//100 => 'ZfcUser\Authentication\Adapter\Db', [this is the default]
),
As I understand from your question you want to get one collection with two different document types so that you can use this collection for authentication.
If you use doctrine Inheritance mapping you can have two different classes and resolve them in one collection.
In this case your Client class would extend your User class. If you would use the findAll method in your UserRepository you would get both the clients and the users in one Collection
This will help you achieve what you want:
<?php
namespace MyProject\Model;
/**
* #Document
* #InheritanceType("SINGLE_COLLECTION")
* #DiscriminatorField(name="discriminator", type="string")
* #DiscriminatorMap({"user" = "User", "client" = "Client"})
*/
class User
{
// ...
}
/**
* #Document
*/
class Client extends User
{
// ...
}
And then
$userRepository->findAll();
Read more on inheritance mapping here in the Doctrine documentation
Let /users/{id} be a resource url in RESTful service.
Basic authentication is enabled and only authenticated users are allowed to access the url.
Example Scenario:
User_1 & User_2 are authenticated users with userId 1 & 2.
Since both are authenticated, both of them are having access to,
/users/1
/users/2
But the expectation is User_1 should have access to /users/1 and not to /users/2 or other userId.
Question:
How to do resource level authorization in RESTful services?
Note: I am implementing RESTful using Jax-RS (with Apache CXF implementation), helpful if you could explain with Jax-RS.
-Barath
Edit:
As Donal mentioned, I am not looking for role based authorization rather resource level authorization.
To give an example, lets say /users/{id}/photos/{photoId} be another resource url. User_1 should be given access to the photos belong to him only. If photoId of 2 belonging to user_2, then we should give http_404 error code for user_1 when a request /users/1/photos/2 is requested.[Since User_1 is also authenticated user he can invoke /users/2/photos/2, so we must identify the user id based on authentication parameters than via resource url]
Only solution I can think of is, include the unique id which determines the authorization in each query like,
Instead of SELECT * FROM PHOTO_TBL WHERE PHOTO_ID=2;
use SELECT * FROM PHOTO_TBL, USER_TBL WHERE PHOTO_ID=2 AND USER_ID=1 AND USER_ID=PHOTO_ID;
with this resources are delivering data that belongs to specific user. [There should be a mechanism to prevent the modification of the unique id in client side which is used to decide on authorization(userId in this case), since all requests are STATELESS request]
Caveat: Each and every query should be intelligent enough to understand the security concerns and include extra join. This is a bad design to tie up security logic to every business function.
I am yet to look into Spring security and how it can be used in this use case.
I would recommend not having the user id in the url (as if it's being 'limited' by a Basic Auth header then you may as well just have it 'specified' by the Basic auth header). This will reduce the risk of introducing a Direct Object Reference Vulnerability - https://www.owasp.org/index.php/Top_10_2010-A4-Insecure_Direct_Object_References)
In this case you could have one of the following urls:
/users/CURRENT
/me
As photos is a sub resource then you could just create the photos with a "sequence number" within the user. In a sql database this would mean having a "compound key" across both user and photo columns.
/users/CURRENT/photo/{user_photo_seq}
/me/photo/{user_photo_seq}
Your SQL would then look something like:
SELECT * FROM PHOTO_TBL WHERE USER_ID=<BasicAuthUsername> AND PHOTO_ID=<path param value>;
A good explanation of "Basic Auth Headers":
http://en.wikipedia.org/wiki/Basic_access_authentication
JAX-RS specifies sub-resource where instead of handling request in a method, processing is delegated to other object - sub-resource.
Using sub-resources it's enought to take care of the root resource and nested ones will be secured as well.
In the example you can see UserResource and all it's sub-resources available only to authorized user.
#Path("/user/{userId}")
public class UserResource {
private final String userId;
public UserResource(#PathParam("userId") String userId, #Context SecurityContext securityContext) {
this.userId = userId;
boolean authorized = /* authorization code */;
if (!authorized) { throw new WebApplicationException(Status.UNAUTHORIZED); }
}
#Path("photo")
public PhotoResource getPhotoResource() {
return new PhotoResource(userId);
}
}
public class PhotoResource {
private final String userId;
public PhotoResource(String userId) {
this.userId = userId;
}
#GET
public Response listAll() { /* ... */ }
#GET
#Path("{photoId}")
public Response present() { /* ... */ }
}
I have the following scenario in zend framework:
Data
Table of students
Table of classes, which contain many students each.
Table of assignments, each of which is assigned to a class and given a password
I want students to be able to access an assignment given that assignment's id and shared password, but for the application to note which student signed in to the assignment. Zend_Auth however expects one table to contain both the username and the password, but in my situation the username is in the students table, and the password is in the assignments table.
Can anyone suggest a good way of handling the student login where they can all share one password. A way to authenticate with just a username and no password would work, as then I could do the password check in a separate conditional.
I think your best bet would really be to just write your own adapter. Something like this would most likely work:
class MyAuthAdapter implements Zend_Auth_Adapter_Interface
{
protected $_username;
protected $_password;
protected $_assignment_id;
/**
* Sets username, password, and assignemnt ID for authentication
*
* #return void
*/
public function __construct($username,$password,$assignment_id)
{
$this->_username = $username;
$this->_password = $password;
$this->_assignment_id = $assignment_id;
}
/**
* Performs an authentication attempt
*
* #throws Zend_Auth_Adapter_Exception If authentication cannot
* be performed
* #return Zend_Auth_Result
*/
public function authenticate()
{
// logic here to check everything out and erturn a new Zend_Auth_Result
}
}
Shared passwords are a really bad idea. If you share the password, then another student need only learn an id -- typically not a highly secured piece of information -- to access the resource as the other student. A better solution would be to use a role to control access to assignments and put the students who need access to the assignment in the role. This way each student can still have access to the assignment and retain their own id/password pair. See the Zend documentation for information on roles and how to use them.