我应该在 CakePHP 应用程序中将 CAS 会话检查代码放在哪里?
我在一所大学的一个部门工作,该部门使用 CAS 提供单点登录身份验证,并且我编写一个需要使用此 CAS 服务的 CakePHP 应用程序。 我需要编写以下代码:
- 检查 CAS 服务器以查看用户是否已登录 如果
- 已登录,则从服务器中提取一些凭据
- 根据内部 ACL 检查凭据,因为可以访问应用程序的人员集是可以登录CAS服务的集合。
- 为管理员用户提供某种机制,要么通过在 CAS 系统外部创建特殊的管理员用户(会带来所有令人头疼的问题),要么通过提升某些 CAS 用户(会带来不同的令人头疼的问题)。
作为 CakePHP 的相对新手,我经常为将“不属于”的代码粘贴在哪里而苦苦挣扎。 我能想到的最好的办法是,这段代码应该放在 App Controller 的 beforeFilter 方法中,但我想知道,这是最好的地方吗? 另外,堆栈中的位置是否太低而无法利用管理路由?
最后,我知道 CakePHP 提供了 Auth 和 ACL 组件,但是当我研究使用它们时,它们似乎不适合与外部身份验证服务交互。 我错了吗?其中任何一个都适合我需要做的事情吗?
谢谢!
I work for a department of a university that uses CAS to provide single-sign-on authentication, and am writing a CakePHP application that needs to use this CAS service. I need to write code that:
- Checks with the CAS server to see if the user is logged in
- Pulls some credentials from the server if so
- Checks the credentials against an internal ACL, as the set of people who can access the application is a subset of the set that can log into the CAS service.
- Provides some mechanism for admin users, either by creating special admin users outside the CAS system (with all the headaches that would entail) or by promoting certain CAS users (with the different headaches that would entail).
As a relative newcomer to CakePHP, I frequently struggle with where to stick code that "doesn't belong". The best I can figure is that this code ought to go in the beforeFilter method of the App Controller, but I wonder, is this the best place for it? Also, is it too low in the stack to take advantage of admin routing?
Lastly, I know that CakePHP provides both Auth and ACL components, but when I looked into using them they did not appear amenable to interfacing with outside authentication services. Am I wrong, and would either of these be a good fit for what I need to do?
Thanks!
如果您查看 Cake 的核心组件,您会发现您的 CAS 要求符合组件通常用于的事物类型(即身份验证/会话)。
我建议创建一个
CasAuthComponent
。 有一些关于扩展AuthComponent的信息
,在我之前的回答中,如果您希望在现有核心AuthComponent
之上进行构建,这可能会很有用。组件(本质上是可重用的控制器代码)可以与模型交互,使用其他组件(例如会话)并控制用户流(例如重定向)
请注意,核心
AuthComponent
实际上从模型检索信息(默认情况下是 User 模型),所以你可以做类似的事情。您创建的
CasAuthComponent
可以$use
一个外部用户模型(可能是CasUser
),它负责数据的 CRUD 操作(主要是检索用户) 。您可以更进一步,将 CAS 交互抽象到该模型使用的数据源中,但如果您不打算在其他模型中重用代码,那么这并不是绝对必要的。
最终结果可以打包成一个插件:
CasAuthComponent
(app/plugins/cas/controllers/components/cas_auth.php
)CasUser
(<代码>app/plugins/cas/models/cas_user.php)CasSource
(app/plugins/cas/models/datasources/cas_source.php
) [可选]并通过将以下内容放入您的 app_controller 中来在您的应用程序中使用:
如果您希望能够从 Cake 管理用户,您还可以在您的插件中包含控制器和视图,它们允许用户与
进行交互CasUser
模型(即$this->CasUser->save()
)。If you take a look at the Cake's core components you can see that your CAS requirement fits with the type of things components are typically used for (ie. auth/session).
I would recommend creating a
CasAuthComponent
. There is some information on extendingAuthComponent
, in a previous answer of mine, which may prove useful if you wish to build on top of the existing coreAuthComponent
.A component (essentially reusable controller code) can interact with models, use other components (such as Session) and control user flow (redirects for example)
Note that, the core
AuthComponent
actually retrieves information from a model (the User model by default), so you could do something similar.The
CasAuthComponent
you create could$use
an external user model (CasUser
maybe) which is responsible for CRUD operations on the data (retrieving users mainly).You could take this one step further and abstract CAS interactions into a datasource used by this model, but it isn't strictly neccessary if you don't plan on reusing the code in other models.
The end result could be packaged into a plugin:
CasAuthComponent
(app/plugins/cas/controllers/components/cas_auth.php
)CasUser
(app/plugins/cas/models/cas_user.php
)CasSource
(app/plugins/cas/models/datasources/cas_source.php
) [optional]And used in your application by putting the following in your app_controller:
If you wish to be able to administer the users from Cake, you can also include a controller and views in your plugin, which allow the user to interact with the
CasUser
model (ie.$this->CasUser->save()
).