Cakephp - Using auth with a 3rd party provider - cakephp

I'm in the process of creating a XML-RPC that interacts with Vbulletin from Cakephp. I currently have the functionality to hit the end point, log a user in, and retrieve the data set, as well as the cookies, etc.
Now, the calls come from Cakephp, I have a users table, which I only store, the usersname from vbulletin, the vbulletin users ID, and their avatar. I'd like to implement some type of auth. I'm not entirely sure if this is possible or not. The only reason I have a users table is to store a minimal set of information. When the user logs in on the Cakephp side, it's actually sending a xml-rpc client call to the vbulletin api, and logging the user in using the api.
So, with all of this known, is it possible to restrict access to various views, etc within cake? I'd like to use some of the basic auth components, such as:
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('add');
}
I'm guessing, if this is not possible, I'll have to manually write the session cookies received from Vbulletin in Cake, but how would I restrict access to the various views and methods within the controllers in doing so?
Update: I ended up using the below to accomplish this.
Since I am storing the vbulletin users id in the users table, I was able to:
$user = $this->User->findByVbulletinid($userid);
$user = $user['User'];
$this->Auth->login($user);
Link to Cakephp manual login not initiating session
Update1: We'll, I thought this was working, until I removed the Debug Kit. Now, after I login, I'm automatically logged out, Really odd.
If I want to call $this->Auth->login($loginData), shouldn't I be able to supply $loginData, which in my case, would look like this:
Array
(
[User] => Array
(
[username] => testuser
[password] => hashedpasswordhere
)
)
Basically, the login method in the Users controller, I cannot simply call $this->Auth->login() because I need to first, take the credentials from the form, and log the user in via the API for vbulletin.
Any thoughts here?

You will have to implement a custom Authentication Handler that is connected to the "Vbulletin". Then when you log a user in $this->Auth->allow('add'); should work just fine.
Also consider additional means of logging a user in. what will happen if that external service is down? Your users will not be able to log in at all?

Related

Single Page Application login with Spring and AngularJS

I'am creating application which can be used by unknown and logged in users. Only difference is that logged in user can use some additional functions like saving its content in database.
All communication is based on ajax calls, so what I need is to deny access to some controller functions (end points) in backend for unknown users and on the client side I need to know that it is in logged in state to set this extra functions active. Only one page, login form should be in dialog. I'm little bit confused, because standard Spring Security aproach doesn't fit this case. I was reading this tutorial but I cant't fully understand it.
First: What Principal object does? They send credentials to this endpoint on submit with login() function but where is handled password check? What if I have my users in database?
Second Is it possible to write this configuration in XML style? I guess that it can be done with <intercept-url/> in spring-security.xml file.
Principal Object
The Principal Object is used to be able to get basic information about a user that is attempting to login when using automatic server authentication (i.e. LDAP). However, you will only be able to get a username from the principal object. With a server JBoss/WildFly, for example, you can link the server to Active Directory to allow Microsoft Windows to authenticate users.
Simple Solution
First, Spring Security will add additional complexity to your application where it doesn't sound like you are trying to do that. Instead, use a simple Servlet Filter. If you are using LDAP on a JBoss/WildFly sever, you can make a POST to j_security_check and the server will send the request to the filter if correct credentials are provided. Inside the filter, you may use the getName() function of the Principal object to get the username so that you may store it in the user's session. However, if you are not using LDAP, you may make a simple POST to a Java Servlet or Spring Controller (with an #RequestMapping) to attempt to login the user and store the user's information in the session.
At this point, you can filter out what URLs you will allow users to see. For example, the URL that contains /administrator/some/other/stuff.jsp could be restricted if the URL contains the word "administrator" in the first directory of the URL.

Cakephp2 : Using multiple authentication manager

I took back the maintenance of a cakephp app, however I have never been a cake developer and I just encountered my first problem.
Currently users are logging in by using a simple form, it is something really simple and it looks like this:
$this->Auth->authenticate = array('Form' => array('userModel'=> .....
Whenever I try to access a protected page, I am getting redirected to the page which implements this login form, this is totally fine and I don't have any problem with that.
However, I have different clients that requires different "authentication format" (if I may say), some wants an Ldap authentication, others an openId authentication, others a CAS authentication...
I managed to create a working authentication for every "system" by extending the BaseAuthenticate and implementing my logic to connect to the app.
Let's take the example with OpenId (which is a little explained in the cakephp book and that I base myself on : http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html). I have created my OpenIdAuthenticate in app/controller/component/auth, implemented the method,...
As in the book, I have chosen the openId as the "main authentication" is my appController :
$this->Auth->authenticate = array(
AuthComponent::ALL => array('userModel' => 'Member'),
'OpenId',
'Form'
);
For the CAS I have the same with Cas instead of OpenId and whenever i try to access a protected page I am redirect to my cas server, where I log myself and I am logged in the cake application (so no problem).
I have also created another method in my user controller in case of the external authentication is broken (if we have any problem, it will probably be useful still to be able to log ourselves for maintenance).
To do so I created an adminLogin method (+ the ctp view file) where I "forced" the original Form authentication by doing as it was written before:
public function adminLogin() {
$this->Auth->authenticate = array('Form' => array('userModel'=> .....
if ($this->request->is('post')) {
//rest of the logic
}
}
Whenever I query the uri /users/adminLogin, I am using the classic authentication system and have access to all the protected pages by bypassing the external authentication.
First question: Is it recommended to do something like that? The only goal is to have access to the content of the app as long as our database is up (in case of).
Now comes the part I still haven't found the solution. As I said, I have different clients with different needs and I don't want to have the classic version hosted for client X, the OpenId for the Y and the Ldap for the Z. I would like the same application everywhere and it will be up to the client to use whichever system he wants to use.
This means, I want to be able to change the authentication method dynamically. What i would like to do is to create a page (only available for the administrator obviously) where it will be able to choose between all the supported system and to configure the system.
For example, I choose Ldap, I will have to give the ip,port,reading suer and pwd, DN, filter,etc.... If I choose cas, the url,port,...(you understood).
And when I press the submit button, my authentication system has changed (except for the adminLogin page).
This is where I would like you to help me find a way to do so. I tried to create a global variable when I click on submit using
Configure::write('SystemUsed','LDAP');
And in my appController in the beforeFilter(), I tried to do :
if (Configure::read('SystemUsed') == 'LDAP') {
$this->Auth->authenticate(...);
else if (Configure::read('SystemUsed') == 'OpenId') {
$this->Auth->authenticate(...);
}
etc. But it is not working, the variable is becoming null after the submit and it doesn't look like a clean way to do it.
Can anyone help me, please?

cakephp auth session regeneration

We are using Cakephp framework version 2.0.6
The site is "supposed" to allow an anonymous user to "add to cart."
We are using the session id (using cake's native session class) to store the anonymous user's information in a db table.
When the user goes to checkout, then we want to ask "are you a current member? If so, click yes to login or no to create an account."
ISSUE:
Regardless of what they choose, the user either then has to login, or create a new user/pass (and then login) which is causing cakephp to regenerate a session ID. This is making it impossible in the new session to grab what that user added to the cart when they were anonymous just 5 minutes prior. In other words, the anonymous user's session id changes between when they are anonymous and after they login/create-user, making it impossible to identify their cart post-login.
Is there a way to prevent cakephp from regenerating a session in this scenario, or a better way to accomplish what we are trying to do while still keeping our order flow (ie: anonymous being allow to add to cart, before login/create)?
It is this reason that shopping carts are more often than not stored in Cookies. That way you can easily retrieve the saved information post-authentication.
If you insist on using Sessions to store this data, consider setting your Security.level setting to 'low'. That should prevent CakePHP from regenerating the session ID.

Creating a login like Basecamp in CakePHP

I am trying to create a basecamp like login where users can login to see their companies projects using the url:
http://abc.com/companyname/
I dont know how to create a 2 level auth... (one at the company level and another at the user level)
I am new to cakePHP and I dont know how to modify the in built Auth component for my requirement.. Any help would be grateful...
I would use the Auth component for the login. I wouldn't mess with the ACL and stuff as that's pretty confusing I find.
I would approach this by adding a user_level, access_level, or permissions column in your users table. Then in here you can store a numerical value or similar.
Then in the User model, when they login using Auth you can store that value in the Auth user session object. So you can get at it using $this->Auth('User.access_level') in your controllers.
Now the Auth component by default has an isAuthorized() function in the app_controller. This function is called to see if someone has logged in. You can modify this to check that access_level and take action appropriately. I used this technique so that users can't get into the /cms routing unless they are admin = 1.
There is more information on this in the docs, http://book.cakephp.org/view/172/Authentication and you can find out more about isAuthorized() here, http://api.cakephp.org/class/auth-component#method-AuthComponentisAuthorized
Do make sure that you setup all your Auth component variables in your app_controller. Also make sure that your auth type is set to controller, and that you're allow() and deny() are configured properly.
The one big catch with all this, is that if you using a beforeFilter() in your controllers, you will need to make sure to do parent::beforeFilter() to ensure that the stuff in the app_controller is run beforehand :)
Honestly, I think that you should check out the ACL component. The book tutorial is very good if you follow it through. The major caveat is that it does not provide a mechanism for row-level access control (e.g. can user X edit this particular entry). However, it does provide a basis for doing user/group level access control, which you can then extend yourself to create the row level access you require.
In short, the ACL component supports cascading permissions (e.g. subgroups can have finely-grained access control, but otherwise inherit permissions from the parent group). That can make life a lot easier, if you need both robustness as well as granularity.
You might also check out the bakery, as there are additional auth components written by the community that may serve what you need. Highly recommended, as Auth/ACL stuff is difficult to do well, and always a major concern with web apps.

how to improve cakephp auth component to use user type?

i use auth componnet in my cakephp project
I add type field into users Mysql table
that enum type: admin, client
i need auth component to redirect admin's to CP page, and client to their profile page and only can access one conttroller..
ofcourse without using ACL or any others related
I'd recommend taking advantage of the isAuthorized() function that you can add in the controller, or the model. Set the AuthComponent::authorize = {'controller'|'model'} to choose which you want to use.
Then you write an isAuthorized() function in the model|controller that returns t/f on auth/not auth for each action. You can do some row-level checking as well, if you'd like.
Now, if instead you just wanted to redirect an admin to their correct pages on login/etc, you can add code to the beforeFilter() method (either in a specific controller, or in app_controller.php). In that, just check to see if the admin value set by the app is the same as the user's admin value (which will be stored by AuthComponent in the Session data, accessible by $this->Auth->User()). Then route appropriately to the admin/non admin areas.
isAuthorized() is the best choice.
i would recommend to separate the users from their groups in the database, so User habtm Group... but It is not a problem if user belongs to one and only one group
I do not recommend ACL for non record-level-based permissions system
Just something to pay attention to, but unless something has changed recently CakePHP does not support ENUM column types.
Your best bet is a Group model ( groups mysql table ) and a group_id field on the users table.
Then you can $hasOne = array( 'Group' ); in your User model.
From there you can follow any one of a HUGE number of group access control tutorials for the Auth Component via an easy google search for "CakePHP Auth User Group"

Resources