授权
授权可以是显式的,也可以是隐式的。前者要求用户通过被重定向到授权端点来主动授权客户端。在那里,他/她通常是通过一个表单呈现的,并被要求接受或拒绝对某些范围的访问。这些作用域可以被认为是绑定到特定权限和资源类别的访问控制列表,例如对其状态提要的写访问权限或对其配置文件的读访问权限。至关重要的是,在向用户提供的授权表中,必须非常清楚授予对特定范围的访问权限的含义。这取决于提供商是否允许用户同意所有、少数范围或不同意任何范围。在这里保持灵活性对用户来说是一个很大的好处,但代价是增加了提供商和客户端的复杂性。
当授权在OAuth流之前发生时,例如用户向客户端提供他/她的密码和用户名,或者如果用户、客户端和提供商之间存在非常高的信任级别而不需要显式授权,则会发生隐式授权。
显式授权的示例是授权码授权和隐式授权。
隐式授权的示例是资源所有者密码凭据授予和客户端凭据授予。
- Pre Authorization Request
OAuth以其授权页面而闻名,在该页面中,用户接受或拒绝对某个客户端和一组作用域的访问。在向用户提供此类表单之前,您需要确保客户端在重定向到此页面时提供的凭据有效。
# Initial setup from your_validator import your_validator server = WebApplicationServer(your_validator) # Validate request uri = 'https://example.com/authorize?client_id=foo&state=xyz headers, body, http_method = {}, '', 'GET' from oauthlib.oauth2 import FatalClientError from your_framework import redirect try: scopes, credentials = server.validate_authorization_request( uri, http_method, body, headers) # scopes will hold default scopes for client, i.e. ['https://example.com/userProfile', 'https://example.com/pictures'] # credentials is a dictionary of { 'client_id': 'foo', 'redirect_uri': 'https://foo.com/welcome_back', 'response_type': 'code', 'state': 'randomstring', } # these credentials will be needed in the post authorization view and # should be persisted between. None of them are secret but take care # to ensure their integrity if embedding them in the form or cookies. from your_datastore import persist_credentials persist_credentials(credentials) # Present user with a nice form where client (id foo) request access to # his default scopes (omitted from request), after which you will # redirect to his default redirect uri (omitted from request). except FatalClientError as e: # this is your custom error page from your_view_helpers import error_to_response return error_to_response(e)
- Post Authorization Request
通常,这是您处理提交的表单的地方。而不是使用
validate_authorization_request
我们使用create_authorization_response
其在授权码授予的情况下在客户端提供的重定向URI中嵌入授权码。# Initial setup from your_validator import your_validator server = WebApplicationServer(your_validator) # Validate request uri = 'https://example.com/post_authorize?client_id=foo headers, body, http_method = {}, '', 'GET' # Fetch the credentials saved in the pre authorization phase from your_datastore import fetch_credentials credentials = fetch_credentials() # Fetch authorized scopes from the request from your_framework import request scopes = request.POST.get('scopes') from oauthlib.oauth2 import FatalClientError, OAuth2Error from your_framework import http_response http_response(body, status=status, headers=headers) try: headers, body, status = server.create_authorization_response( uri, http_method, body, headers, scopes, credentials) # headers = {'Location': 'https://foo.com/welcome_back?code=somerandomstring&state=xyz'}, this might change to include suggested headers related # to cache best practices etc. # body = '', this might be set in future custom grant types # status = 302, suggested HTTP status code return http_response(body, status=status, headers=headers) except FatalClientError as e: # this is your custom error page from your_view_helpers import error_to_response return error_to_response(e) except OAuth2Error as e: # Less grave errors will be reported back to client client_redirect_uri = credentials.get('redirect_uri') redirect(e.in_uri(client_redirect_uri))
- class oauthlib.oauth2.AuthorizationEndpoint(default_response_type, default_token_type, response_types)[源代码]
授权端点-由客户端用于通过用户-代理重定向从资源所有者获取授权。
授权端点用于与资源所有者交互并获得授权授权。授权服务器必须首先验证资源所有者的身份。授权服务器验证资源所有者的方式(例如用户名和密码登录、会话Cookie)超出了本规范的范围。
端点URI可以包括格式化(PER)的“应用程序/x-www-form-urlencode Appendix B )查询组件,添加其他查询参数时必须保留该组件。终结点URI不得包含片段组件::
https://example.com/path?query=component # OK https://example.com/path?query=component#fragment # Not OK
由于对授权端点的请求会导致用户身份验证和明文凭据的传输(在HTTP响应中),授权服务器在向授权端点发送请求时必须要求使用第1.6节中所述的TLS:
# We will deny any request which URI schema is not with https
授权服务器必须支持使用HTTP“GET”方法 [RFC2616] 对于授权端点,还可以支持使用“POST”方法:
# HTTP method is currently not enforced
发送的没有值的参数必须被视为已从请求中省略。授权服务器必须忽略无法识别的请求参数。请求和响应参数不得包含多次::
# Enforced through the design of oauthlib.common.Request