阿帕奇,SSL客户端证书,LDAP授权 [英] Apache, SSL Client certificate, LDAP authorizations
问题描述
高那里,
我贴在serverfault.com这个问题,但我没有答案,所以我想在这里...
是否有可能使身份验证与客户端证书和授权与mod_auth_ldap完成(需要LDAP组)混合了mod_ssl和mod_auth_ldap?如果是这样,你可以给我一些指针?在此先感谢
High there, I posted this question on serverfault.com, but I had no answer, so I'm trying here... Is it possible to mix mod_ssl and mod_auth_ldap so that the authentication is done with the client certificate and authorizations with mod_auth_ldap (Require ldap-group)? If so, can you give me some pointer? Thanks in advance
推荐答案
确定,对于那些有兴趣,阿帕奇需要一个AuthType选项presence和用户名的一些模块进行验证。
OK, for those interested, apache requires the presence of an AuthType directive and the validation of the username by some module.
所以我写了接受任何进行AuthType并接受任何用户名。在很短的模块
So I have written a very short module that accepts AuthType Any and accepts any username.
配置看起来像:
<Location /slaptest>
Allow from all
SSLVerifyClient require
SSLVerifyDepth 1
SSLUserName SSL_CLIENT_S_DN_CN
AuthType Any
AuthAnyAuthoritative on
AuthLDAPURL "ldaps://vldap-rectech/ou=XXX,ou=YYY,o=ZZZ?cn"
AuthzLDAPAuthoritative on
AuthLDAPBindDN "cn=UUU,ou=Users,ou=XXX,ou=YYY,o=ZZZ"
AuthLDAPBindPassword "******"
AuthLDAPGroupAttributeIsDN on
AuthLDAPGroupAttribute member
AuthLDAPRemoteUserIsDN off
Require valid-user
Require ldap-group cn=ADMIN,ou=Groups,ou=XXX,ou=YYY,o=ZZZ
</Location>
更新:
模块的code为如下。它定义了以下指令:
The code of the module is listed below. It defines the following directives:
AuthAnyAuthoritative开/关
AuthAnyAuthoritative on/off
AuthAnyCheckBasic开/关
AuthAnyCheckBasic on/off
如果AuthAnyCheckBasic是,该模块将检查从证书中获得的用户名相匹配的在Authorization头。
If AuthAnyCheckBasic is on, the module will check that the username obtained from the certificate matches the on in the Authorization header.
#include "apr_strings.h"
#include "apr_md5.h" /* for apr_password_validate */
#include "apr_lib.h" /* for apr_isspace */
#include "apr_base64.h" /* for apr_base64_decode et al */
#define APR_WANT_STRFUNC /* for strcasecmp */
#include "apr_want.h"
#include "ap_config.h"
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"
#include "ap_provider.h"
#include "mod_auth.h"
typedef struct {
int authoritative;
int checkBasic;
} auth_any_config_rec;
static void *create_auth_any_dir_config(apr_pool_t *p, char *d)
{
auth_any_config_rec *conf = apr_pcalloc(p, sizeof(*conf));
/* Any failures are fatal. */
conf->authoritative = 1;
conf->checkBasic = 0;
return conf;
}
static const command_rec auth_any_cmds[] =
{
AP_INIT_FLAG("AuthAnyAuthoritative", ap_set_flag_slot,
(void *)APR_OFFSETOF(auth_any_config_rec, authoritative),
OR_AUTHCFG,
"Set to 'Off' to allow access control to be passed along to "
"lower modules if the UserID is not known to this module"),
AP_INIT_FLAG("AuthAnyCheckBasic", ap_set_flag_slot,
(void *)APR_OFFSETOF(auth_any_config_rec, checkBasic),
OR_AUTHCFG,
"Set to 'On' to compare the username with the one in the "
"Authorization header"),
{NULL}
};
module AP_MODULE_DECLARE_DATA auth_any_module;
static void note_basic_auth_failure(request_rec *r)
{
apr_table_setn(r->err_headers_out,
(PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"
: "WWW-Authenticate",
apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r),
"\"", NULL));
}
/* Determine user ID, and check if it really is that user, for HTTP
* basic authentication...
*/
static int authenticate_any_user(request_rec *r)
{
auth_any_config_rec *conf = ap_get_module_config(r->per_dir_config,
&auth_any_module);
/* Are we configured to be Basic auth? */
const char *current_auth = ap_auth_type(r);
if (!current_auth || strcasecmp(current_auth, "Any")) {
return DECLINED;
}
if (!r->user) {
return conf->authoritative ? HTTP_UNAUTHORIZED : DECLINED;
}
if (conf->checkBasic) {
/* Get the appropriate header */
const char *auth_line = apr_table_get(r->headers_in,
(PROXYREQ_PROXY == r->proxyreq)
? "Proxy-Authorization"
: "Authorization");
if (!auth_line) {
note_basic_auth_failure(r);
return HTTP_UNAUTHORIZED;
}
if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) {
/* Client tried to authenticate using wrong auth scheme */
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"client used wrong authentication scheme: %s", r->uri);
note_basic_auth_failure(r);
return HTTP_UNAUTHORIZED;
}
/* Skip leading spaces. */
while (apr_isspace(*auth_line)) {
auth_line++;
}
char *decoded_line = apr_palloc(r->pool, apr_base64_decode_len(auth_line) + 1);
int length = apr_base64_decode(decoded_line, auth_line);
/* Null-terminate the string. */
decoded_line[length] = '\0';
const char *user = ap_getword_nulls(r->pool, (const char**)&decoded_line, ':');
if (strcasecmp(user, r->user)) {
return HTTP_UNAUTHORIZED;
}
}
r->ap_auth_type = "Any";
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"Accepting user: %s", r->user);
return OK;
}
static void register_hooks(apr_pool_t *p)
{
ap_hook_check_user_id(authenticate_any_user,NULL,NULL,APR_HOOK_MIDDLE);
}
module AP_MODULE_DECLARE_DATA auth_any_module =
{
STANDARD20_MODULE_STUFF,
create_auth_any_dir_config, /* dir config creater */
NULL, /* dir merger --- default is to override */
NULL, /* server config */
NULL, /* merge server config */
auth_any_cmds, /* command apr_table_t */
register_hooks /* register hooks */
};
这篇关于阿帕奇,SSL客户端证书,LDAP授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!