研究了一下如何通过REST API来进行文件下载,通过用户认证来进行保护,并且保护文件的地址不给用户看到。
首先要搭建一个Keycloak的服务,可以到官网下载并安装,然后运行bin目录下的standalone.sh,启动服务。打开localhost:8080,作为Admin登录,新建一个Realm Test,然后在这个Realm下面新增一个Client Test,client protocol选择openid-connect,在Root URL以及Valid Redirect URI里面增加http://localhost:5000/*, http://127.0.0.1:5000/*,access type选择credential,保存之后再次打开,设置client id,以及在credentials里面选择Regenerate Secret,记录下这个Secret
之后就可以编写一个Flask程序download.py,如以下代码:
from flask import Flask, make_response, send_from_directory
from flask_oidc import OpenIDConnect
app = Flask(__name__)
app.config.update({
'SECRET_KEY': 'SomethingNotEntirelySecret',
'TESTING': True,
'DEBUG': True,
'OIDC_CLIENT_SECRETS': 'client_secrets.json',
'OIDC_ID_TOKEN_COOKIE_SECURE': False,
'OIDC_REQUIRE_VERIFIED_EMAIL': False,
'OIDC_USER_INFO_ENABLED': True,
'OIDC_OPENID_REALM': 'flask-demo',
'OIDC_SCOPES': ['openid', 'email', 'profile'],
'OIDC_INTROSPECTION_AUTH_METHOD': 'client_secret_post'
})
oidc = OpenIDConnect(app)
@app.route('/report/<name>')
@oidc.require_login
def report(name):
file_name = name + '.zip'
response = make_response(send_from_directory('./',file_name,as_attachment=True))
response.headers["Content-Type"] = 'zip'
response.headers["Content-Disposition"] = "attachment; filename={}".format(file_name.encode().decode('latin-1'))
return response
@app.route('/logout')
def logout():
"""Performs local logout by removing the session cookie."""
oidc.logout()
return 'Hi, you have been logged out! <a href="/">Return</a>'
在程序的同一个目录下新建一个client_secrets.json文件,设置Keycloak的相关信息:
{
"web": {
"issuer": "http://localhost:8080/auth/realms/test",
"auth_uri": "http://localhost:8080/auth/realms/test/protocol/openid-connect/auth",
"client_id": "test",
"client_secret": "XXXXXXXX",
"redirect_uris": [
"http://localhost:5000/"
],
"userinfo_uri": "http://localhost:8080/auth/realms/test/protocol/openid-connect/userinfo",
"token_uri": "http://localhost:8080/auth/realms/test/protocol/openid-connect/token",
"token_introspection_uri": "http://localhost:8080/auth/realms/test/protocol/openid-connect/token/introspect",
"logout_uri": "http://localhost:8080/auth/realms/test/protocol/openid-connect/logout"
}
}
在这个目录下我们新建一个report1.zip文件作为测试。
之后启动Flask,访问http://127.0.0.1:5000/report/report1.zip,浏览器会重定向到Keycloak的用户登录页面,成功登录之后就可以自动下载文件。