翻译-pjsip开发者指南(九)认证框架

 Chapter 9:Authentication Framework
PJSIP提供客户端和服务器的认证框架。认证框架支持缺省的http摘要认证,但是其他的认证方案也可以加到框架中。
下面的图表描述了框架的类图。

 9.1 Client Authentication Framework
客户端身份验证框架管理客户端到所下游服务器的身份验证过程。它能以正确的凭证来响应服务器的认证(当有这种凭证提供),缓存认证信息,并且使用缓存的认证信息来初始化之后的请求。
 9.1.1 Client Authentication Framework Reference
认证的API在头文件 <pjsip/sip_auth.h>中声明。下面是认证的数据结构和函数的文档引用。
 

 pjsip_cred_info

这个结构描述了特定范围内的认证。一个客户端在一个对话或者注册期间有多个认证。每一种凭证都包含针对下游代理或服务器的认证信息。
比如,客户端需要一个凭证来验证的外发代理服务器,或者其他的凭证来验证端服务器。
    

    
pjsip_cached_auth

这个结构体保存特定服务器的最终鉴权。这个是必须的因为这样客户端可以用最后的鉴权来初始化下一次的请求。
  

     
pjsip_auth_clt_sess

这个结构体描述了客户端认证会话。客户端在对话或者注册期间通常会保存这个结构体。


 Function Reference
 pj_status_t pjsip_auth_clt_init( pjsip_auth_clt_sess *sess,
pj_pool_t *pool, unsigned options);
初始化认证会话的数据结构,并设置会话使用pool来进行后续的内存分配。参数选项这个版本可以设置为0。

 pj_status_t pjsip_auth_clt_set_credentials( pjsip_auth_clt_sess *s,
int cred_cnt,
const pjsip_cred_info cred[]);
设置会话期间的凭证。使用客户端的认证池来赋值指定的凭证。

pj_status_t pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,
pjsip_tx_data *tdata );
这个函数根据会话缓存的信息为新的发送请求tdata增加所有的认证头。这个请求消息的请求行在调用这个函数前必须是有效的。

 pj_status_t pjsip_auth_clt_reinit_req( pjsip_auth_clt_session *sess,
pjsip_endpoint *endpt,
const pjsip_rx_data *rdata,
pjsip_tx_data *old_request,
pjsip_tx_data **new_request )
调用这个函数在收到失败的认证状态(401.407)后重新初始化请求。这个函数根据 old_request重新创建 new_request,根据rdata响应中的鉴权添加合适的认证和代理认证头。除此之外,这个函数还会在会话中添加相关信息。
如果鉴权缺少证书,这个函数会返回失败。注意这个函数可以重用旧的请求而不是再创建一个新的。


 9.1.2 Examples
Client Transaction Authentication
下面的例子说明了如何用认证信息初始化发出的请求以及处理来自服务器的鉴权。为了简单说明,例子里没有展示错误处理。一个好的应用程序应该有准备处理任何情形下的错误的能力。

 pjsip_auth_client_session auth_sess;
// Initialize client authentication session with some credentials.
void init_auth(pj_pool_t *session_pool)
{
    pjsip_cred_info cred;
    pj_status_t status;
    cred.realm = pj_str(“sip.example.com”);
    cred.scheme = pj_str(“digest”);
    cred.username = pj_str(“alice”);
    cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
    cred.data = pj_str(“secretpassword”);
Page 64
PJSIP Developer’s Guide
    status = pjsip_auth_client_init( &auth_sess, session_pool, 0);
    status = pjsip_auth_set_credentials( &auth_sess, 1, &cred );
}
// Initialize outgoing request with authorization information and
// send the request statefully.
void send_request(pjsip_tx_data *tdata)
{
    pj_status_t status;
    status = pjsip_auth_client_init_req( &auth_sess, tdata );
    status = pjsip_endpt_send_request( endpt, tdata, -1, NULL, &on_complete);
}
// Callback when the transaction completes.
static void on_complete( void *token, pjsip_event *event )
{
    int code;
    pj_assert(event->type == PJSIP_EVENT_TSX_STATE);
    code = event->body.tsx_state.tsx->status_code;
    if (code == 401 || code == 407) {
        pj_status_t status;
        pjsip_tx_data *new_request;
        status = pjsip_auth_client_reinit_req( &auth_sess, endpt,
        event->body.tsx_state.src.rdata,
        tsx->last_tx,
        &new_request);
        if (status == PJ_SUCCESS)
                status = pjsip_endpt_send_request( endpt, new_request, -1, NULL,
                &on_complete);
        else
        PJ_LOG(3,(“app”,”Authentication failed!!!”));
    }
}


 9.2 Server Authorization Framework
服务器认证框架提供了两种服务器认证机制:
  #无会话服务器认证为认证的客户端提供了通用API。 这个API在每个请求的基础上提供了全局的服务器认证,通常用于代理认证服务器当它调用不是有状态时。
  #服务器认证会话,提供了特定对话或者注册会话中的全局服务器认证机制。需要为服务器的对话或者注册会话建立服务器认证会话的实例。一个服务器认证会话要有一个初始设置的凭证,这个凭证在对话/注册会话期间一直被客户端使用。
 9.2.1 Server Authorization Reference
Data Types Reference
 typedef pj_status_t pjsip_auth_lookup_cred( pj_pool_t *pool,
const pj_str_t *realm,
 const pj_str_t *acc_name,
pjsip_cred_info *cred_info );

在指定的realm中查找acc_name的凭证信息的要注册到认证服务器的类型。当成功查找到凭证信息,函数用凭证填充cred_info并返回PJ_SUCCESS。否则就返回以下的 错误码:
  # PJSIP_EAUTHACCNOTFOUND :在指定的realm中未找到账号
  # PJSIP_EAUTHACCDISABLED:账号找到了但是不可用

 Functions Reference
 pj_status_t pjsip_auth_srv_init( pj_pool_t *pool,
pjsip_auth_srv *auth_srv,
const pj_str_t *realm,
pjsip_auth_lookup_cred *lookup_func,
unsigned options );
初始化服务器认证会话数据结构以服务于指定的realm,并使用lookup_func函数查找凭证信息options参数是下面值的位掩码组合:
 # PJSIP_AUTH_SRV_IS_PROXY:指明服务器认证客户端为一个代理服务器(而不是作为UAS),也就是说使用 Proxy-Authenticate代替 WWW-Authenticate。


 pj_status_t pjsip_auth_srv_verify( pjsip_auth_srv *auth_srv,
pjsip_rx_data *rdata,
int *status_code );
请求认证服务区验证rdata请求中的认证信息。如果status_code不是NULL,将适当的填充响应状态(401/407等)。
如果请求中的认证信息可被接受,函数将返回PJ_SUCCESS,或者当认证失败的时候,返回下面的错误:
# PJSIP_EAUTHNOAUTH:请求中未指明认证头
# PJSIP_EINVALIDAUTHSCHEME:无效或不支持的认证方案(当前只支持摘要)
# PJSIP_EAUTHACCNOTFOUND or PJSIP_EAUTHACCDISABLED:查找函数返回的错误码
# PJSIP_EAUTHINVALIDDIGEST:无效的摘要
#其他表示系统错误的非零值


 pj_status_t pjsip_auth_srv_challenge( pjsip_auth_srv *auth_srv,
const pj_str_t *qop,
const pj_str_t *nonce,
const pj_str_t *opaque,
pj_bool_t stale,
pjsip_tx_data *tdata);
在发出的响应tdata中增加认证质询头。如果指定了qop,将该值放到质询中,应用也可以指定nonce和qpaque,或者可以让这些值为NULL,以随机字母填充。


 9.3 Extending Authentication Framework
认证框架可以扩充来支持非http摘要的认证框架 (PGP)
TODO。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章