提交 83e89ac0c828386ea8d526f38a7fd0e72e1996c5

作者 qianyingz
1 个父辈 b3bd899e

支持用户传入重定向地址

@@ -14,7 +14,6 @@ import configure @@ -14,7 +14,6 @@ import configure
14 from app.decorators.auth_decorator import auth_decorator 14 from app.decorators.auth_decorator import auth_decorator
15 import time 15 import time
16 from app.models import SM3, AESHelper 16 from app.models import SM3, AESHelper
17 -from PIL import Image  
18 17
19 18
20 def current_user(): 19 def current_user():
@@ -48,14 +47,15 @@ class DataManager(BlueprintApi): @@ -48,14 +47,15 @@ class DataManager(BlueprintApi):
48 except OAuth2Error as error: 47 except OAuth2Error as error:
49 return jsonify(dict(error.get_body())) 48 return jsonify(dict(error.get_body()))
50 if not user: 49 if not user:
51 - #生成验证码 50 + # 生成验证码
52 51
53 - return render_template("auth/authorize.html", user=user, grant=grant) 52 + return render_template("auth/authorize.html",
  53 + user=user,
  54 + grant=grant)
54 error = "" 55 error = ""
55 if not user: 56 if not user:
56 # 验证码校验 57 # 验证码校验
57 -  
58 - 58 +
59 if not "username" in request.form or not request.form.get("username"): 59 if not "username" in request.form or not request.form.get("username"):
60 error = "用户名不可为空" 60 error = "用户名不可为空"
61 elif not "password" in request.form or not request.form.get("password"): 61 elif not "password" in request.form or not request.form.get("password"):
@@ -71,13 +71,14 @@ class DataManager(BlueprintApi): @@ -71,13 +71,14 @@ class DataManager(BlueprintApi):
71 if user: 71 if user:
72 session["id"] = user.id 72 session["id"] = user.id
73 grant_user = user 73 grant_user = user
74 - return authorization.create_authorization_response(grant_user=grant_user) 74 + return authorization.create_authorization_response(request=request, grant_user=grant_user)
75 75
76 try: 76 try:
77 grant = authorization.validate_consent_request(end_user=user) 77 grant = authorization.validate_consent_request(end_user=user)
78 except OAuth2Error as error: 78 except OAuth2Error as error:
79 return jsonify(dict(error.get_body())) 79 return jsonify(dict(error.get_body()))
80 - return render_template("auth/authorize.html", user=user, grant=grant, error=error) 80 + # return render_template("auth/authorize.html", user=user, grant=grant, error=error)
  81 + return authorization.create_authorization_response(grant_user=None)
81 82
82 @staticmethod 83 @staticmethod
83 @bp.route("/token", methods=["POST"]) 84 @bp.route("/token", methods=["POST"])
@@ -40,6 +40,13 @@ class OAuth2Client(db.Model, OAuth2ClientMixin): @@ -40,6 +40,13 @@ class OAuth2Client(db.Model, OAuth2ClientMixin):
40 Integer, ForeignKey('dmap_user.id', ondelete='CASCADE')) 40 Integer, ForeignKey('dmap_user.id', ondelete='CASCADE'))
41 user = relationship('User') 41 user = relationship('User')
42 42
  43 + def get_default_redirect_uri(self):
  44 + if self.redirect_uris:
  45 + return self.redirect_uris[0]
  46 +
  47 + def check_redirect_uri(self, redirect_uri):
  48 + return redirect_uri in self.redirect_uris
  49 +
43 50
44 class OAuth2AuthorizationCode(db.Model, OAuth2AuthorizationCodeMixin): 51 class OAuth2AuthorizationCode(db.Model, OAuth2AuthorizationCodeMixin):
45 __tablename__ = 'dmap_oauth2_code' 52 __tablename__ = 'dmap_oauth2_code'
@@ -57,4 +64,4 @@ class OAuth2Token(db.Model, OAuth2TokenMixin): @@ -57,4 +64,4 @@ class OAuth2Token(db.Model, OAuth2TokenMixin):
57 user_id = Column( 64 user_id = Column(
58 Integer, ForeignKey('dmap_user.id', ondelete='CASCADE')) 65 Integer, ForeignKey('dmap_user.id', ondelete='CASCADE'))
59 # name = Column(Text) 66 # name = Column(Text)
60 - user = relationship('User')  
  67 + user = relationship('User')
  1 +from authlib.oauth2.rfc6749 import grants
1 from os import access, remove 2 from os import access, remove
2 from time import time 3 from time import time
3 from authlib.integrations.flask_oauth2 import ( 4 from authlib.integrations.flask_oauth2 import (
@@ -29,10 +30,11 @@ DUMMY_JWT_CONFIG = { @@ -29,10 +30,11 @@ DUMMY_JWT_CONFIG = {
29 'exp': 7200, 30 'exp': 7200,
30 } 31 }
31 32
  33 +
32 class myCodeIDToken(CodeIDToken): 34 class myCodeIDToken(CodeIDToken):
33 def validate(self, now, leeway): 35 def validate(self, now, leeway):
34 return super().validate(now=now, leeway=leeway) 36 return super().validate(now=now, leeway=leeway)
35 - 37 +
36 def validate_exp(self, now, leeway): 38 def validate_exp(self, now, leeway):
37 return super().validate_exp(now, leeway) 39 return super().validate_exp(now, leeway)
38 40
@@ -68,7 +70,34 @@ def create_authorization_code(client, grant_user, request): @@ -68,7 +70,34 @@ def create_authorization_code(client, grant_user, request):
68 return code 70 return code
69 71
70 72
71 -class AuthorizationCodeGrant(_AuthorizationCodeGrant): 73 +class AuthorizationCodeGrant(grants.AuthorizationCodeGrant):
  74 +
  75 + def save_authorization_code(self, code, request):
  76 + client = request.client
  77 + auth_code = OAuth2AuthorizationCode(
  78 + code=code,
  79 + client_id=client.client_id,
  80 + redirect_uri=request.redirect_uri,
  81 + scope=request.scope,
  82 + user_id=request.user.id,
  83 + )
  84 + db.session.add(auth_code)
  85 + db.session.commit()
  86 + return auth_code
  87 +
  88 + def query_authorization_code(self, code, client):
  89 + item = OAuth2AuthorizationCode.query.filter_by(
  90 + code=code, client_id=client.client_id).first()
  91 + if item and not item.is_expired():
  92 + return item
  93 +
  94 + def delete_authorization_code(self, authorization_code):
  95 + db.session.delete(authorization_code)
  96 + db.session.commit()
  97 +
  98 + def authenticate_user(self, authorization_code):
  99 + return User.query.get(authorization_code.user_id)
  100 +
72 def create_authorization_code(self, client, grant_user, request): 101 def create_authorization_code(self, client, grant_user, request):
73 return create_authorization_code(client, grant_user, request) 102 return create_authorization_code(client, grant_user, request)
74 103
@@ -120,15 +149,14 @@ class HybridGrant(_OpenIDHybridGrant): @@ -120,15 +149,14 @@ class HybridGrant(_OpenIDHybridGrant):
120 149
121 def generate_user_info(self, user, scope): 150 def generate_user_info(self, user, scope):
122 return generate_user_info(user, scope) 151 return generate_user_info(user, scope)
123 -  
124 -from authlib.oauth2.rfc6749 import grants 152 +
125 153
126 class PasswordGrant(grants.ResourceOwnerPasswordCredentialsGrant): 154 class PasswordGrant(grants.ResourceOwnerPasswordCredentialsGrant):
127 def authenticate_user(self, username, password): 155 def authenticate_user(self, username, password):
128 user = User.query.filter_by(username=username).first() 156 user = User.query.filter_by(username=username).first()
129 if user.check_password(password): 157 if user.check_password(password):
130 return user 158 return user
131 - 159 +
132 TOKEN_ENDPOINT_AUTH_METHODS = [ 160 TOKEN_ENDPOINT_AUTH_METHODS = [
133 'client_secret_basic', 'client_secret_post' 161 'client_secret_basic', 'client_secret_post'
134 ] 162 ]
@@ -24,7 +24,7 @@ entry_data_thread = 3 @@ -24,7 +24,7 @@ entry_data_thread = 3
24 scan_module = ["app.modules"] # API所在的模块 24 scan_module = ["app.modules"] # API所在的模块
25 SECRET_KEY = b'_5#y2L"F4Q8z\n\xec]/' 25 SECRET_KEY = b'_5#y2L"F4Q8z\n\xec]/'
26 # 权限 26 # 权限
27 -PermissionActive = True 27 +PermissionActive = False
28 UserPermission = ['admin'] 28 UserPermission = ['admin']
29 MonitorPermission = ['admin'] 29 MonitorPermission = ['admin']
30 DataPermission = ['admin', 'dataman'] 30 DataPermission = ['admin', 'dataman']
1 101映射域名 1 101映射域名
2 dmap.apps.chinadci.com 2 dmap.apps.chinadci.com
  3 +# 鉴权
  4 +Authlib
  5 +## 1 授权服务器
  6 +为授权、颁发令牌、刷新令牌和撤销令牌提供多个端点。当资源拥有者(用户)获得授权时,授权服务器会向客户端颁发访问令牌。
  7 +### 资源拥有者:用户
  8 +### 客户端:客户端是一个代表资源拥有者并在授权情况下请求受保护资源的应用
  9 + * client_id是唯一标识
  10 + * client_secret是密码
  11 + * 客户端令牌端点认证方法
  12 +### 令牌
  13 +使用令牌访问用户资源,令牌发布时带有有效期,有访问范围等等。它至少包括:
  14 +* access_token
  15 +* refresh_token
  16 +*...
  17 +### 服务器
  18 +authlib使用工具AuthorizationServer管理请求和响应
  19 +
  20 +
3 21
4 # Web安全 22 # Web安全
5 ## 1 接口权限控制 23 ## 1 接口权限控制
注册登录 后发表评论