精华内容
参与话题
问答
  • Authentication概述

    2017-12-11 23:34:05
    Authentication 是指身份验证的过程——即证明一个用户实际上是不是他们所说的他们是谁。也就是说通过提交用户的身份和凭证给Shiro,以判断它们是否和应用程序预期的相匹配。 n基本概念 1:Principals(身份):...

    http://sishuok.com/forum/posts/list/7455.html

    Authentication 是指身份验证的过程——即证明一个用户实际上是不是他们所说的他们是谁。也就是说通过提交用户的身份和凭证给Shiro,以判断它们是否和应用程序预期的相匹配。

    n基本概念

    1:Principals(身份):是Subject 的‘identifying attributes(标识属性)’。比如我们登录提交的用户名。

    2:Credentials(凭证):通常是只被Subject 知道的秘密值,它用来作为一种起支持作用的证据,此证据事实上包含着所谓的身份证明。比如我们登录提供的密码

     

    n认证的基本步骤

    1. 收集Subjects 提交的Principals(身份)和Credentials(凭证);

    2. 提交Principals(身份)和Credentials(凭证)进行身份验证;

    3. 如果提交成功,则允许访问,否则重新进行身份验证或者阻止访问。

     

    认证样例

    n使用用户名/密码的样例

    UsernamePasswordToken token = new UsernamePasswordToken(username, password);

    token.setRememberMe(true);

      样例使用UsernamePasswordToken 来支持最常见的用户名/密码的身份验证方法。这是Shiro的org.apache.shiro.authc.AuthenticationToken 的接口,是Shiro 代表提交的Principals(身份)和Credentials(凭证)的身份验证系统所使用的基本接口的一个实现。

    n提交用户名/密码进行认证

    Subject currentUser = SecurityUtils.getSubject();

    currentUser.login(token);

    n处理认证成功和失败

      如果认证成功,会没有返回,也没有例外,通过。

      如果认证失败,会拋出例外,你可以在程序中捕获并处理,如下示例:

     

    try {

      currentUser.login(token);

    } catch ( UnknownAccountException uae ) { …

    } catch ( IncorrectCredentialsException ice ) { …

    } catch (LockedAccountException lae ) { …

    } catch (ExcessiveAttemptsException eae ) { …

    } … catch your own …

    nlogout(注销)

      currentUser.logout();

      当你调用logout,任何现有的Session 都将会失效,而且任何身份都将会失去关联(例如,在Web 应用程序中,RememberMe cookie 也将被删除)。在Subject 注销后,该Subject的实例被再次认为是匿名的,当然,除了Web 应用程序。

      注意:由于在Web 应用程序记住身份往往是依靠Cookies,然而Cookies 只能在Response 被committed 之前被删除,所以强烈建议在调用subject.logout()后立即将终端用户重定向到一个新的视图或页面。

      这样能够保证任何与安全相关的Cookies 都能像预期的一样被删除。这是HTTP cookies 的功能限制,而不是Shiro的。

     

    RememberedAuthenticated

    nRemembered(记住我)

      一个记住我的Subject 不是匿名的,是有一个已知的身份ID(也就是subject.getPrincipals()是非空的)。但是这个被记住的身份ID 是在之前的session 中被认证的。如果subject.isRemembered()返回true,则Subject 被认为是被记住的。

     

    nAuthenticated(已认证)

      一个已认证的Subject 是指在当前Session 中被成功地验证过了(也就是说,login方法被调用并且没有抛出异常)。如果subject.isAuthenticated()返回true 则认为Subject 已通过验证。

     

    n注意他们是互斥的

      Remembered 和Authenticated 是互斥的——若其中一个为真则另一个为假,反之亦然

     

    认证顺序

     

    nStep 1:应用程序代码调用Subject.login 方法,传递创建好的包含终端用户的Principals(身份)和Credentials(凭证)的AuthenticationToken 实例。
    nStep 2:Subject实例,通常是DelegatingSubject(或子类)委托应用程序的SecurityManager通过调用securityManager.login(token)开始真正的验证。
    nStep3:SubjectManager 接收token 以及简单地委托给内部的Authenticator 实例通过调用authenticator.authenticate(token)。这通常是一个ModularRealmAuthenticator 实例,支持在身份验证中协调一个或多个Realm 实例。
    n
    nStep 4:如果应用程序中配置了一个以上的Realm,ModularRealmAuthenticator 实例将利用配置好的AuthenticationStrategy 来启动Multi-Realm 认证尝试。在Realms 被身份验证调用之前,期间和以后,AuthenticationStrategy 被调用使其能够对每个Realm 的结果作出反应。
    n
    nStep 5:每个配置的Realm 用来帮助看它是否支持提交的AuthenticationToken。如果支持,那么支持Realm 的getAuthenticationInfo 方法将会伴随着提交的token 被调用。getAuthenticationInfo 方法有效地代表一个特定Realm 的单一的身份验证尝试。
    初识自定义 Realm
    n这里先来个例子,认识一下:

    public class MyRealm extends AuthorizingRealm{

      protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

      String userName = (String) getAvailablePrincipal(principals);

      //通过用户名去获得用户的所有资源,并把资源存入info中

      SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

      Set<String> s = new HashSet<String>();

      s.add("p1");  s.add("p2"); info.setStringPermissions(s);

      Set<String> r = new HashSet<String>();

      r.add("r1"); r.add("r2"); info.setRoles(r);

      return info;}

      protected AuthenticationInfo doGetAuthenticationInfo(

      AuthenticationToken token) throws AuthenticationException {

      //token中储存着输入的用户名和密码

      UsernamePasswordToken upToken = (UsernamePasswordToken)token;

      String username = upToken.getUsername();

      String password = String.valueOf(upToken.getPassword());

      //通常是与数据库中用户名和密码进行比对,这里就省略了

      //比对成功则返回info,比对失败则抛出对应信息的异常AuthenticationException

      SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password .toCharArray(),getName());

      return info;  }}

     

     

    配置多个Realm

    n上面的例子可以作为第一个Realm
    n再复制一份,定义为MyRealm2,在返回user前添加抛出一个例外,表示认真没有通过,如下:

    if(username.equals("javass")){

      throw new AuthenticationException("MyRealm2 认证失败");

    }

    SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password .toCharArray(),getName());

    n在配置文件里面添加Realm的定义

    myRealm1=cn.javass.hello.MyRealm

    myRealm2=cn.javass.hello.MyRealm2

     

    由于有多个realm,一般就需要配置AuthenticationStrategy了,而AuthenticationStrategy是跟Authenticator(认证器)相关的。

     

     

    n配置Authenticator和AuthenticationStrategy

    authenticator = org.apache.shiro.authc.pam.ModularRealmAuthenticator

    authcStrategy = org.apache.shiro.authc.pam.AllSuccessfulStrategy

    authenticator.authenticationStrategy = $authcStrategy

    authenticator.realms=$myRealm2,$myRealm1

    n当然,你可以扩展并实现自己的Authenticator,一般没有必要
    n最后把Authenticator设置给securityManager

      securityManager.authenticator = $authenticator

    n关于AuthenticationStrategy的配置,有三种:

    AtLeastOneSuccessfulStrategy :如果一个(或更多)Realm 验证成功,则整体的尝试被认为是成功的。如果没有一个验证成功,则整体尝试失败。

    FirstSuccessfulStrategy 只有第一个成功地验证的Realm 返回的信息将被使用。所有进一步的Realm 将被忽略。如果没有一个验证成功,则整体尝试失败

    AllSucessfulStrategy 为了整体的尝试成功,所有配置的Realm 必须验证成功。如果没有一个验证成功,则整体尝试失败。

     

    ModularRealmAuthenticator 默认的是AtLeastOneSuccessfulStrategy

     

     

    n自定义自己的AuthenticationStrategy,通常是扩展自AbstractAuthenticationStrategy,示例如下:

    public class MyAuthenticationStrategy extends AbstractAuthenticationStrategy{

      public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException {

      if(realm.getName().equals("myRealm2")){

      if(singleRealmInfo==null || singleRealmInfo.getPrincipals()==null){

      throw new AuthenticationException("主战认证未通过");

      }

      }

    return super.afterAttempt(realm, token, singleRealmInfo, aggregateInfo, t);

      }

    }

    至于具体覆盖扩展什么方法,需要根据你具体的策略来定。

     

     

    多个Realm的验证顺序

    n概述

      非常重要的一点是:ModularRealmAuthenticator 将与Realm 实例以迭代的顺序进行交互。

      在SecurityManager 中已经配置好了ModularRealmAuthenticator 对Realm实例的访问。当执行一个认证尝试时,它将会遍历该集合,并对每一个支持提交AuthenticationToken 的Realm 调用Realm 的getAuthenticationInfo 方法

    n隐式排列

      当你配置多个realm的时候,处理的顺序默认就是你配置的顺序。

      这种情况通常就是只定义了realm,而没有配置securityManager的realms

    n显示排列

      也就是显示的配置securityManager.realms,那么执行的顺序就是你配置该值的realm的顺序。

      通常更推荐显示排列。

     


    私塾在线原创,转载请注明http://sishuok.com/forum/blogPost/list/0/7455.html


    展开全文
  • 认证 (authentication) 和授权 (authorization) 的区别

    万次阅读 多人点赞 2017-06-06 11:08:47
    以前一直分不清 authentication 和 authorization,其实很简单,举个例子来说: 你要登机,你需要出示你的身份证和机票,身份证是为了证明你张三确实是你张三,这就是 authentication;而机票是为了证明你张三...
    以前一直分不清 authentication 和 authorization,其实很简单,举个例子来说:

    你要登机,你需要出示你的身份证和机票,身份证是为了证明你张三确实是你张三,这就是 authentication;而机票是为了证明你张三确实买了票可以上飞机,这就是 authorization。


    在 computer science 领域再举个例子:

    你要登陆论坛,输入用户名张三,密码1234,密码正确,证明你张三确实是张三,这就是 authentication;再一check用户张三是个版主,所以有权限加精删别人帖,这就是 authorization。
    展开全文
  • Authentication

    千次阅读 2018-12-18 12:39:00
    认证 (Authentication) 身份验证需要可插拔。—— Jacob Kaplan-Moss, “REST worst practices” 身份验证是将传入请求与一组标识凭据 (例如请求来自的用户或其签名的令牌) 相关联的机制。然后,权限和限制策略可以...

    认证 (Authentication)

    身份验证需要可插拔。—— Jacob Kaplan-Moss, “REST worst practices”

    身份验证是将传入请求与一组标识凭据 (例如请求来自的用户或其签名的令牌) 相关联的机制。然后,权限限制策略可以使用这些凭据来确定是否应允许该请求。

    REST framework 提供了一些开箱即用的身份验证方案,并且还允许您实现自定义方案。

    身份验证始终在视图的最开始运行,在权限和限制检查发生之前以及允许任何其他代码继续执行之前。

    request.user 属性通常被设置为 contrib.auth 包的 User 类的实例。

    request.auth 属性用于任何其他身份验证信息,例如,它可用于表示请求已签名的身份验证令牌。


    注意:不要忘记,身份验证本身不会允许或不允许传入的请求,它只识别发出请求的凭证。

    有关如何为 API 设置权限策略的信息,请参阅权限文档


    如何确定身份验证 (How authentication is determined)

    身份验证方案始终定义为类列表。REST framework 将尝试对列表中的每个类进行身份验证,并使用成功进行身份验证的第一个类的返回值设置 request.userrequest.auth

    如果没有类进行身份验证,request.user 将被设置为 django.contrib.auth.models.AnonymousUser 的实例,request.auth 将被设置为 None

    可以使用 UNAUTHENTICATED_USERUNAUTHENTICATED_TOKEN 的设置修改未经身份认证的请求的 request.userrequest.auth 的值。

    设置身份验证方案 (Setting the authentication scheme)

    可以使用 DEFAULT_AUTHENTICATION_CLASSES 设置全局的默认身份验证方案。比如:

    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.BasicAuthentication',
            'rest_framework.authentication.SessionAuthentication',
        )
    }
    

    您还可以使用基于 APIView 类的视图在每个视图或每个视图集的基础上设置身份验证方案。

    from rest_framework.authentication import SessionAuthentication, BasicAuthentication
    from rest_framework.permissions import IsAuthenticated
    from rest_framework.response import Response
    from rest_framework.views import APIView
    
    class ExampleView(APIView):
        authentication_classes = (SessionAuthentication, BasicAuthentication)
        permission_classes = (IsAuthenticated,)
    
        def get(self, request, format=None):
            content = {
                'user': unicode(request.user),  # `django.contrib.auth.User` instance.
                'auth': unicode(request.auth),  # None
            }
            return Response(content)
    

    或者,如果您使用基于函数的视图的 @api_view 装饰器。

    @api_view(['GET'])
    @authentication_classes((SessionAuthentication, BasicAuthentication))
    @permission_classes((IsAuthenticated,))
    def example_view(request, format=None):
        content = {
            'user': unicode(request.user),  # `django.contrib.auth.User` instance.
            'auth': unicode(request.auth),  # None
        }
        return Response(content)
    

    未经授权和禁止响应 (Unauthorized and Forbidden responses)

    当未经验证的请求被拒绝许可时,有两种不同的错误代码可能是适当的。

    HTTP 401 响应必须始终包含 WWW-Authenticate 标头,指示客户端如何进行身份验证。HTTP 403 响应不包括 WWW-Authenticate 标头。

    使用的响应类型取决于身份验证方案。尽管可以使用多种认证方案,但是仅可以使用一种方案来确定响应的类型。在确定响应类型时使用视图上设置的第一个身份验证类。

    注意,当请求可以成功进行身份验证时,但仍然被拒绝执行该请求的许可,不管认证方案如何,总是使用 403 Permission Denied 响应。

    Apache mod_wsgi 具体配置 (Apache mod_wsgi specific configuration)

    请注意,如果使用 mod_wsgi 部署到 Apache,授权标头默认不会传递给 WSGI 应用程序,因为它假定由 Apache 处理身份验证,而不是在应用程序级别处理。

    如果您正在部署到 Apache,并使用任何基于非会话的身份验证,则需要明确配置 mod_wsgi 以将所需的标头传递给应用程序。这可以通过在适当的上下文中指定 WSGIPassAuthorization 指令并将其设置为 'On' 来完成。

    # 这可以在服务器配置、虚拟主机、目录或 .htaccess 中执行
    WSGIPassAuthorization On
    

    API 参考 (API Reference)

    BasicAuthentication

    此身份验证方案使用 HTTP 基本身份验证,对用户的用户名和密码进行签名。基本身份验证通常仅适用于测试。

    如果成功通过身份验证,BasicAuthentication 提供以下凭据。

    • request.user 将是 Django User 实例。
    • request.auth 将是 None

    拒绝许可的未经身份验证的响应将导致带有相应的 WWW-Authenticate 标头的 HTTP 401 Unauthorized 响应。例如:

    WWW-Authenticate: Basic realm="api"
    

    注意:如果您在产品中使用 BasicAuthentication,您必须确保您的 API 仅在 https 上可用。您还应确保您的 API 客户端始终在登录时重新请求用户名和密码,并且不会存储这些详细信息到持久存储器中。

    TokenAuthentication

    此身份验证方案使用简单的基于令牌的 HTTP 身份验证方案。令牌认证适用于客户端-服务器设置,例如本地桌面和移动客户端。

    要使用 TokenAuthentication 方案,您需要配置身份验证类以包含 TokenAuthentication,并在 INSTALLED_APPS 设置中另外包含 rest_framework.authtoken

    INSTALLED_APPS = (
        ...
        'rest_framework.authtoken'
    )
    

    注意:确保在更改设置后运行 manage.py migraterest_framework.authtoken 应用程序提供 Django 数据库迁移。


    您还需要为用户创建令牌。

    from rest_framework.authtoken.models import Token
    
    token = Token.objects.create(user=...)
    print token.key
    

    要使客户端进行身份验证,令牌密钥应包含在 Authorization HTTP 标头中。密钥应以字符串文字“Token”为前缀,空格分隔两个字符串。例如:

    Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
    

    注意:如果想要在标头中使用不同的关键字,例如 Bearer,只需将 TokenAuthentication 子类化并设置 keyword 类变量。

    如果成功通过身份验证,TokenAuthentication 提供以下凭据。

    • request.user 将是 Django User 实例。
    • request.auth 将是 rest_framework.authtoken.models.Token 实例。

    拒绝许可的未经身份验证的响应将导致带有相应的 WWW-Authenticate 标头的 HTTP 401 Unauthorized 响应。例如:

    WWW-Authenticate: Token
    

    curl 命令行工具可用于测试令牌认证 API。例如:

    curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'
    

    注意:如果您在产品中使用 TokenAuthentication,您必须确保您的 API 仅在 https 上可用。


    生成令牌 (Generating Tokens)

    通过使用信号 (By using signals)

    如果您想要每个用户都拥有一个自动生成的令牌,您只需捕获用户的 post_save 信号即可。

    from django.conf import settings
    from django.db.models.signals import post_save
    from django.dispatch import receiver
    from rest_framework.authtoken.models import Token
    
    @receiver(post_save, sender=settings.AUTH_USER_MODEL)
    def create_auth_token(sender, instance=None, created=False, **kwargs):
        if created:
            Token.objects.create(user=instance)
    

    请注意,您需要确保将此代码段放在已安装的 models.py 模块中,或者在启动时由 Django 导入的其他位置。

    如果您已经创建了一些用户,则可以为所有现有用户生成令牌,如下所示:

    from django.contrib.auth.models import User
    from rest_framework.authtoken.models import Token
    
    for user in User.objects.all():
        Token.objects.get_or_create(user=user)
    
    通过暴露 api 端点 (By exposing an api endpoint)

    当使用 TokenAuthentication 时,你可能希望为客户端提供一种获取给定用户名和密码的令牌的机制。REST framework 提供了一个内置的视图来提供此行为。要使用它,请将 obtain_auth_token 视图添加到你的 URLconf:

    from rest_framework.authtoken import views
    urlpatterns += [
        url(r'^api-token-auth/', views.obtain_auth_token)
    ]
    

    请注意,模式的 URL 部分可以是您要使用的任何内容。

    当使用表单数据或 JSON 将有效的 usernamepassword 字段 POST 到视图时,obtain_auth_token 视图将返回 JSON 响应:

    { 'token' : '9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b' }
    

    请注意,默认的 obtain_auth_token 视图显式使用 JSON 请求和响应,而不是使用 settings 中默认的渲染器和解析器类。

    默认情况下,没有应用于 obtain_auth_token 视图的权限或限制。如果您希望应用限制,则需要重写视图类,并使用 throttle_classes 属性将它们包括在内。

    如果需要自定义版本的 obtain_auth_token 视图,可以通过子类化 ObtainAuthToken 类,并在 url conf 中使用它来实现。

    例如,您可以返回令牌值之外的其他用户信息:

    from rest_framework.authtoken.views import ObtainAuthToken
    from rest_framework.authtoken.models import Token
    from rest_framework.response import Response
    
    class CustomAuthToken(ObtainAuthToken):
    
        def post(self, request, *args, **kwargs):
            serializer = self.serializer_class(data=request.data,
                                               context={'request': request})
            serializer.is_valid(raise_exception=True)
            user = serializer.validated_data['user']
            token, created = Token.objects.get_or_create(user=user)
            return Response({
                'token': token.key,
                'user_id': user.pk,
                'email': user.email
            })
    

    在你的 urls.py 中:

    urlpatterns += [
        url(r'^api-token-auth/', CustomAuthToken.as_view())
    ]
    
    With Django admin

    还可以通过管理界面手动创建令牌。如果您使用的是大型用户基础,我们建议您修补 TokenAdmin 类以根据需要对其进行自定义,更具体地说,将 user 字段声明为raw_field

    your_app/admin.py

    from rest_framework.authtoken.admin import TokenAdmin
    
    TokenAdmin.raw_id_fields = ('user',)
    

    使用 Django manage.py 命令 (Using Django manage.py command)

    从版本3.6.4开始,可以使用以下命令生成用户令牌:

    ./manage.py drf_create_token <username>
    

    此命令将返回给定用户的 API 令牌,如果它不存在则创建它:

    Generated token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b for user user1
    

    如果您想要重新生成令牌 (例如如果它已被破坏或泄露),您可以传递一个额外的参数:

    ./manage.py drf_create_token -r <username>
    

    SessionAuthentication

    此身份验证方案使用 Django 的默认会话后端进行身份验证。会话身份验证适用于与您的网站在同一会话上下文中运行的 AJAX 客户端。

    如果成功通过身份验证,则 SessionAuthentication 提供以下凭据。

    • request.user 是 Django User 实例。
    • request.authNone

    未经许可的未经身份验证的响应将导致 HTTP 403 Forbidden 响应。

    如果您正在使用带有 SessionAuthentication 的 AJAX 样式的 API,则需要确保为任何“不安全” HTTP 方法调用 (例如 PUTPATCHPOSTDELETE 请求) 包含有效的 CSRF 令牌。有关更多详细信息,请参阅 Django CSRF 文档

    警告:创建登录页面时,始终使用 Django 的标准登录视图。这将确保您的登录视图得到适当保护。

    REST framework 中的 CSRF 验证与标准 Django 的工作方式略有不同,因为需要同时支持基于会话和非会话的身份验证。这意味着只有经过身份验证的请求才需要 CSRF 令牌,并且可以在没有 CSRF 令牌的情况下发送匿名请求。此行为不适用于登录视图,登录视图应始终应用 CSRF 验证。

    RemoteUserAuthentication

    此身份验证方案允许您将身份验证委托给 Web 服务器,该服务器设置 REMOTE_USER 环境变量。

    要使用它,你必须在你的 AUTHENTICATION_BACKENDS 设置中有 django.contrib.auth.backends.RemoteUserBackend (或者子类)。默认情况下,RemoteUserBackend 为尚不存在的用户名创建 User 对象。要更改此行为和其他行为,请参阅 Django 文档

    如果成功通过身份验证,RemoteUserAuthentication 提供以下凭据:

    • request.user 是 Django User 实例。
    • request.authNone

    有关配置身份验证方法的信息,请参阅 Web 服务器的文档,例如:

    自定义身份验证 (Custom authentication)

    要实现自定义的身份验证方案,要继承 BaseAuthentication 类并且重写 .authenticate(self, request) 方法。如果认证成功,该方法应返回 (user, auth) 的二元元组,否则返回 None

    在某些情况下,您可能想要从 .authenticate() 方法引发 AuthenticationFailed 异常,而不是返回 None

    通常,您应采取的方法是:

    • 如果未尝试验证,返回 None。还将检查任何其他正在使用的身份验证方案。
    • 如果尝试验证失败,则引发 AuthenticationFailed 异常。无论是否进行任何权限检查,都将立即返回错误响应,并且不会检查任何其他身份验证方案。

    您还可以重写 .authenticate_header(self, request) 方法。如果实现,则应返回将用作 HTTP 401 Unauthorized 响应中的 WWW-Authenticate 标头的值的字符串。

    如果 .authenticate_header() 方法未被重写,则身份验证方案将在未经验证的请求被拒绝访问时返回 HTTP 403 Forbidden 响应。


    注意:当您的自定义身份验证器被请求对象的 .user.auth 属性调用时,您可能会看到 AttributeError 作为 WrappedAttributeError 被重新引发。这对于防止原始异常被外部属性访问所抑制是必要的。Python 不会识别来自您的自定义身份验证器的 AttributeError,而是会假设请求对象没有 .user.auth 属性。这些错误应由您的验证器修复或以其他方式处理。


    举个栗子

    以下示例将对在自定义请求标头中名为 ‘X_USERNAME’ 的用户名指定的用户的任何传入请求进行身份验证。

    from django.contrib.auth.models import User
    from rest_framework import authentication
    from rest_framework import exceptions
    
    class ExampleAuthentication(authentication.BaseAuthentication):
        def authenticate(self, request):
            username = request.META.get('X_USERNAME')
            if not username:
                return None
    
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                raise exceptions.AuthenticationFailed('No such user')
    
            return (user, None)
    

    第三方包 (Third party packages)

    以下是可用的第三方包。

    Django OAuth Toolkit

    Django OAuth Toolkit 包提供了 OAuth 2.0 支持,并且兼容 Python 2.7 和 Python 3.3+。这个包使用优秀的 OAuthLib,由 Evonove 维护。该软件包有很完善的文档,并得到很好的支持,目前是我们推荐使用的 OAuth 2.0 支持软件包。

    安装和配置 (Installation & configuration)

    使用 pip 安装。

    pip install django-oauth-toolkit
    

    把这个包添加到你的 INSTALLED_APPS 中,并修改您的 REST framework 设置。

    INSTALLED_APPS = (
        ...
        'oauth2_provider',
    )
    
    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
        )
    }
    

    有关更多详细信息,请参阅 Django REST框架 - 入门文档。

    Django REST framework OAuth

    Django REST framework OAuth 包为 REST framework 提供 OAuth1 和 OAuth2 支持。

    此软件包以前直接包含在 REST framework 包中,但现在作为第三方包支持和维护。

    安装和配置 (Installation & configuration)

    使用 pip 安装软件包。

    pip install djangorestframework-oauth
    

    有关配置和使用的详细信息,请参阅 Django REST framework OAuth 文档的身份验证权限

    Digest Authentication

    HTTP 摘要认证是一种广泛实施的方案,旨在取代 HTTP 基本认证,并提供简单的加密认证机制。Juan Riaza 维护着 djangorestframework-digestauth 包,它为 REST framework 提供 HTTP 摘要认证支持。

    Django OAuth2 Consumer

    Rediker SoftwareDjango OAuth2 Consumer 是另一个为 REST framework 提供 OAuth 2.0 支持的软件包。该软件包包含令牌的令牌范围权限,允许对你的 API 进行更细粒度的访问。

    JSON Web Token Authentication

    JSON Web Token 是一个相当新的标准,可用于基于令牌的身份验证。与内置 TokenAuthentication 方案不同,JWT Authentication 不需要使用数据库来验证令牌。Blimp 维护着 djangorestframework-jwt 软件包,它提供了 JWT Authentication 类,以及客户端获取给定用户名和密码的 JWT 的机制。JWT 身份验证的另一个包是 djangorestframe -simplejwt,它提供了不同的特性以及可插入的令牌黑名单应用程序。

    Hawk HTTP Authentication

    HawkREST 库以 Mohawk 库为基础,允许您在 API 中处理 Hawk 签名的请求和响应。Hawk 让双方使用共享密钥签名的消息彼此安全地进行通信。它基于 HTTP MAC 访问认证(基于 OAuth 1.0 的部分)。

    HTTP Signature Authentication

    HTTP 签名(目前为 IETF 草案)提供了一种实现 HTTP 消息的源认证和消息完整性的方法。与 Amazon 的 HTTP 签名方案类似,许多服务使用它,它允许无状态的每个请求的身份验证。Elvio Toccalino 维护 djangorestframework-httpsignature 包,提供了一个易于使用的 HTTP 签名身份验证机制。

    Djoser

    Djoser 库提供了一组视图来处理诸如注册,登录,注销,密码重置和帐户激活等基本操作。该包使用自定义用户模型,并使用基于令牌的身份验证。这是一个可以使用 REST 实现的 Django 身份验证系统。

    django-rest-auth

    Django-rest-auth 库提供了一组 REST API 端点,用于注册,身份验证(包括社交媒体身份验证),密码重置,检索和更新用户详细信息等。通过拥有这些 API 端点,您的客户端应用程序(如 AngularJS、iOS、Android 等)可以通过 REST API 独立地与 Django 后端站点通信,用于用户管理。

    django-rest-framework-social-oauth2

    Django-rest-framework-social-oauth2 库提供了一种将社交插件(facebook、twitter、google 等)集成到您的身份验证系统和简单的 oauth2 设置的简单方法。使用这个库,您将能够基于外部令牌(例如 facebook 访问令牌)对用户进行身份验证,将这些令牌转换为“内部” oauth2 令牌,并使用和生成 oauth2 令牌来验证您的用户。

    django-rest-knox

    Django-rest-knox 库提供模型和视图,以比内置 TokenAuthentication 方案更安全和可扩展的方式处理基于令牌的身份验证 - 考虑到单页应用程序和移动客户端。它为每个客户端提供令牌,并在提供一些其他身份验证(通常是基本身份验证)时生成它们,以删除令牌(提供服务器强制注销),并删除所有令牌(注销用户登录的所有客户端)的视图。

    drfpasswordless

    drfpasswordless 为 Django REST Framework 自己的 TokenAuthentication 方案添加了(Medium,Square Cash灵感)无密码支持。用户登录并使用发送到联系人点(如电子邮件地址或手机号码)的令牌进行注册。

    展开全文
  • Authentication身份认证方式分为两种:Windows、Forms;Windows认证方式适用于局域网。Forms认证方式既可适用于局域网,也可用于互联网。 在标准ASP.NET认证方式中 1.如何判断当前请求是一个已登录用户发起的? ...

    Authentication身份认证方式分为两种:Windows、Forms;Windows认证方式适用于局域网。Forms认证方式既可适用于局域网,也可用于互联网。

    在标准ASP.NET认证方式中

    1. 如何判断当前请求是一个已登录用户发起的?

       如果Request.IsAuthenticated为true,则表示是一个已登录用户。

    2. 如何获取当前登录用户的登录名?如何获取当前用户的其他信息?

       如果是一个已登录用户,访问HttpContext.User.Identity.Name可获取登录名(都是实例属性)。

    ASP.NET身份认证过程

    在ASP.NET中,整个身份认证的过程其实可分为二个阶段:认证与授权。
    1. 认证阶段:识别当前请求的用户是不是一个可识别(的已登录)用户。
    2. 授权阶段:是否允许当前请求访问指定的资源。

    这二个阶段在ASP.NET管线中用AuthenticateRequest和AuthorizeRequest事件来表示。
    在认证阶段,ASP.NET会检查当前请求,根据web.config设置的认证方式,尝试构造HttpContext.User对象供我们在后续的处理中使用。 在授权阶段,会检查当前请求所访问的资源是否允许访问,因为有些受保护的页面资源可能要求特定的用户或者用户组才能访问。 所以,即使是一个已登录用户,也有可能会不能访问某些页面。 当发现用户不能访问某个页面资源时,ASP.NET会将请求重定向到登录页面。

    受保护的页面与登录页面我们都可以在web.config中指定,具体方法可参考后文。

    在ASP.NET中,Forms认证是由FormsAuthenticationModule实现的,URL的授权检查是由UrlAuthorizationModule实现的。

    Authentication身份认证

    1. web.config中配置认证方式

        <authentication mode="Forms" >
          <forms name="cookieName" loginUrl="~/Account/Login" timeout="2880" ></forms>
        </authentication> 

    2. 在登录时,将登录信息写入cookie

                        string userData = JsonConvert.SerializeObject(model);//model为用户的基本信息(如角色、权限等)写入cookie,可用于授权检查
                        //写入注册信息
                        DateTime expiration = DateTime.Now.Add(FormsAuthentication.Timeout);
                        FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
                            model.Email,
                            DateTime.Now,
                            expiration,
                            true,
                            userData,
                            FormsAuthentication.FormsCookiePath    
                            );
    
                        HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,
                            FormsAuthentication.Encrypt(ticket))
                        {
                            HttpOnly = true,
                            Expires = expiration
                        };
    
                        HttpContext.Response.Cookies.Remove(cookie.Name);
                        HttpContext.Response.Cookies.Add(cookie);

    3. 身份认证过滤器,并在global中进行配置

    public class AuthenticationFilter : ActionFilterAttribute
        {
            /// <summary>
            /// 身份认证过滤,用户权限判断
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                bool isAnoy = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) ||
                    filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true);
    
                var identity = filterContext.HttpContext.User.Identity;
                if (!isAnoy && !identity.IsAuthenticated)
                {
                    if (filterContext.HttpContext.Request.IsAjaxRequest())
                    {
                        var result = new
                        {
                            flag = false,
                            data = string.Empty,
                            msg = "请登录"
                        };
                        filterContext.Result = new JsonResult
                        {
                            Data = result,
                            JsonRequestBehavior = JsonRequestBehavior.AllowGet
                        };
                    }
                    else
                    {
                        filterContext.Result = new RedirectToRouteResult(new System.Web.Routing.RouteValueDictionary(new
                        {
                            //需要跳转的Controller
                            controller = "Account",
                            //需要跳转的Action
                            action = "Login",
                            //返回的字段说明
                            returnUrl = filterContext.HttpContext.Request.Url,
                            returnMessage = "请登录!"
                        }));
                    }
                }
            }
    
    
    
        }
        public class FilterConfig
        {
            public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                filters.Add(new HandleErrorAttribute());
                filters.Add(new AuthenticationFilter());
            }
        }

    4. 自定义的IPrincipa和IIdentity实现用户角色验证,获取更详细的用户信息或是更详细的权限验证

     public class CustomPrincipal : IPrincipal
        {
            #region Identity Properties  
    
            public int UserId { get; set; }
            public string LoginName { get; set; }
            public string RealName { get; set; }
            public string Email { get; set; }
            public string[] Roles { get; set; }
            #endregion
    
            public IIdentity Identity
            {
                get; private set;
            }
    
            public bool IsInRole(string role)
            {
                if (Roles.Any(r => role.Contains(r)))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
    
            public CustomPrincipal(string username)
            {
                Identity = new GenericIdentity(username);
            }
    
        }

    在global中实现Application_PostAuthenticateRequest

     protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
            {
                //读取cookie并替换HttpContext.User对象
                HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];// Request.Cookies["cookieName"];
                if (authCookie != null)
                {
                    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    
                    CustomPrincipal principal = new CustomPrincipal(authTicket.Name);
                    //可将需要在整个程序读取的用户数据放在principal中
                    //var userDto = JsonConvert.DeserializeObject<UserDto>(authTicket.UserData);
                    //principal.UserId = userDto.Id;
                    //principal.LoginName = userDto.LoginName;
                    //principal.RealName = userDto.RealName;
                    //principal.Roles = serializeModel.RoleName.ToArray<string>();
    
                    HttpContext.Current.User = principal;
                }
            }

     

    这些是最近用到的,有更多认识,再来补充

     

    转载于:https://www.cnblogs.com/pashanhu/p/9657695.html

    展开全文
  • 认证Authentication

    2018-06-28 14:32:36
    认证Authentication可以在配置文件中配置全局默认的认证方案REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.BasicAuthentication', # 基本认证 'rest_framework....
  • HTTP Authentication(HTTP认证)

    千次阅读 2018-09-20 15:51:17
    HTTP协议规范中有两种认证方式,一种是Basic认证,另外一种是Digest认证,这两种方式都属于无状态认证方式,所谓无状态即服务端都不会在会话中记录相关信息,客户端每次访问都需要将用户名... BASIC基本认证 概述 ...
  • authentication failure解决办法

    千次阅读 2019-06-24 21:22:38
    1.在命令行下敲:sudo passwd root 2.输入原来的密码 3.输入新密码 4.确认新密码
  • 以前一直分不清 authentication 和 authorization,其实很简单,举个例子来说: 你要登机,你需要出示你的身份证和机票,身份证是为了证明你张三确实是你张三,这就是 authentication;而机票是为了证明你张三确实买...
  • Authentication vs. authorization It is easy to confuse authentication with another element of the security plan: authorization. While authentication verifies the user’s identity, authorization ...
  • 以前一直分不清 authentication 和 authorization,其实很简单: 举个例子来说: 你要登机,你需要出示你的身份证和机票,身份证是为了证明你张三确实是你张三,这就是 authentication;而机票是为了证明你张三...
  • su: Authentication failure问题

    万次阅读 多人点赞 2018-05-04 14:15:44
    su命令不能切换root,提示su: Authentication failure,只要你sudo passwd root过一次之后,下次再su的时候只要输入密码就可以成功登录了。
  • AuthenticationException异常详解

    万次阅读 2017-10-12 12:27:29
    AuthenticationException异常详解
  • 这个异常是在登录的时候出现错误时抛出的异常,比如账户锁定,证书失效等,先来看下AuthenticationException常用的的子类: UsernameNotFoundException 用户找不到 BadCredentialsException 坏的凭据 Accou
  • Full authentication is required to access this resource Unauthorized
  • 目标 第1部分:查看路由配置 第2部分:将PPP配置为封装方法 第3部分:配置PPP身份验证 ...在本练习中,您将练习在串行链路上配置PPP封装。您还将配置PPP PAP身份验证和PPP CHAP身份验证。...在查看路由器配置时,请...
  • 出现标题中的报错信息 如果你有一台阿里云服务器可以自己搭建代理服务器 squid代理服务器的搭建:安装配置Squid代理服务器​​​​​​​ 可以设置代理服务器,这台代理服务器能访问到github自然就能连上 ...
  • 这个异常是在登录的时候出现错误时抛出的异常,比如账户锁定,证书失效等,先来看下AuthenticationException常用的的子类: UsernameNotFoundException 用户找不到 BadCredentialsException 坏的凭据 ...
  • 关于PLSQL连接远程库时报错:ORA-28040:No matching authentication protocol 解决方案 问题:ORA-28040: No matching authentication protocol 说明:在配置远程连接数据库时出现ORA-28040: No matching ...
  • 今天在电脑上安装了Mysql 8.0.11,然后又屁颠屁颠地安装了Navicat for MySQL,打开Navicat准备链接数据库的时候出现了如下提示: 上网搜索解决方案,网上说出现这种情况的原因是:mysql8 之前的版本中加密规则是...
  • 课程分享: 课程分享:Docker+Kubernetes(k8s)微服务容器化实践 课程分享:Kubernetes(k8s)生产级实践...异常情况: /health 只有status信息,没有其他 地址:http://localhost:8088/health { "status" : "U...

空空如也

1 2 3 4 5 ... 20
收藏数 304,737
精华内容 121,894
关键字:

authentication