如何使用kubernetes Ingress执行自定义身份验证 [英] How to perform custom authentication with kubernetes Ingress

查看:666
本文介绍了如何使用kubernetes Ingress执行自定义身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在kubernetes中部署了很少的服务,并使用NGINX入口访问外部.(将EC2实例用于所有集群设置).能够通过与入口绑定的主机访问服务.现在,我不是在直接访问svc,而是在访问服务之前尝试添加身份验证.并重定向到登录页面,用户输入凭据并应重定向到要求的页面.到目前为止,我尝试过以下代码片段.请指导找到解决方法.

I have deployed few services in kubernetes and using NGINX ingress to access outside.(Using EC2 instance for all cluster setup). Able to access service through host tied with ingress. Now instead of accessing the svc directly I am trying to add authentication and before accessing the service. And redirecting to login page , user enters credentials and should redirect to the asked page. The following code snipet I I tried so far. Please guide to find solution.

my-ingress.yml

my-ingress.yml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  namespace: mynamespace  
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/affinity: cookie
    nginx.ingress.kubernetes.io/session-cookie-name: JSESSIONID
    nginx.ingress.kubernetes.io/ssl-passthrough: "false"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    kubernetes.io/ingress.class: "nginx"
    kubernetes.io/ingress.allow-http: "false"
    nginx.ingress.kubernetes.io/auth-signin: "https://auth.mysite.domain/api/auth/login"  #will show login page
    nginx.ingress.kubernetes.io/auth-url: "https://auth.mysite.domain/api/auth/token/validate"
    nginx.ingress.kubernetes.io/auth-response-headers: "authorization"    
    
spec:
  tls:
  - hosts: 
    - mysite.domain
    #secretName: ${TLS_TOKEN_NAME}
  rules:
  - host: a.mysite.domain
    http:
      paths:
        - path: /
          backend:
            serviceName: myservice1
            servicePort: 9090 
 

因此,它首先会调用"/token/validate"(/令牌/验证)并获得未经授权的权限,然后进行身份验证/登录"和登录页面将显示 在输入凭证之后,去"/令牌/验证".并再次登录页面.实际上应该重定向到被调用的页面.

so first it will call "/token/validate" and will get unauthorized then got to "auth/login" and login page will show after entering credentials going to "/token/validate" and again login page. Actually should redirect to the called page.

如何实现这一目标?[如果成功通过身份验证,是否可以在被称为ling中添加标头,我认为可以解决,但不确定如何做到]

How to achieve this?[If after successful auth if we can add header in called ling I think can solve but not sure how]

后端:Java Spring

backend: Java Spring

@RequestMapping("login")  
public String login() {  
    return "login.html";  
} 

login.html

login.html

    <form action="validate-user" method="post" enctype="application/x-www-form-urlencoded">  
        <label for="username">Username</label>  
        <input type="text" id="username" value="admin" name="username" autofocus="autofocus" />  <br>
        <label for="password">Password</label>  
        <input type="password" id="password" value="password" name="password" />  <br>
        
        <input id="submit" type="submit" value="Log in" />  
    </form> 

后端:Java Spring

backend: Java Spring

@PostMapping("validate-user")
@ResponseBody
public ResponseEntity<?> validateUser(HttpServletRequest request, HttpServletResponse response) throws Exception {
                ...
                
    HttpStatus httpStatus=HttpStatus.FOUND;
    //calling authentication api and validating
        
    //else
    httpStatus=HttpStatus.UNAUTHORIZED;
    HttpHeaders responseHeaders= new HttpHeaders();
    responseHeaders.set("Authoriztion", token);
                
    //responseHeaders.setLocation(new URI("https://a.mysite.domain")); ALSO TRIED BUT NOT WORKED
    return new ResponseEntity<>(responseHeaders,httpStatus);        
        
        }

UPDATE1::如果我使用带有自定义标头"Authorization"的URL:"bearer token",则我正在使用自己的自定义auth api.从邮递员那里可以,但是响应是可以的,但是从浏览器中是不可能的,所以仅从上游svc(成功登录后),标头应该包含在重定向页面中我们该怎么办?
我有任何遗漏吗?

UPDATE1: I am using my own custom auth api, if I am hitting the url with custom header "Authorization":"bearer token" from postman then response is ok, but from from browser not possible, So from upstream svc only(after successfull login) the header should include in redirect page that how can we do?
ANY ANNOTATION AM I MISSING?

UPDATE2:在成功通过身份验证后进行重定向时,我将令牌作为查询字符串(如responseHeaders.setLocation(new URI("https://a.mysite.domain/?access_token="+token))传递,并在重定向其后进行验证.成功验证后,转到下游svc [expected].但是,当该svc路由时,说a.mysite.domain/route1,则查询字符串消失了,并且auth svc无法再次获得令牌,因此再次401.它应该像a.mysite.domain/route1/?access_token=token.有什么办法可以做到吗?如果每个路由都具有相同的查询字符串,那么它将起作用.[这是我的PLAN-B ...但仍然优先传递标题是标头]

UPDATE2: While redirecting after successful auth I am passing token as query string like responseHeaders.setLocation(new URI("https://a.mysite.domain/?access_token="+token) and after redirecting its going to validate. After successful validation going to downstream svc[expected]. But when that svc is routing say a.mysite.domain/route1 then query string is gone and auth svc not able to get token hence 401 again. It should be like a.mysite.domain/route1/?access_token=token. Any way is there to do that? If every route will have same query string then will work.[This is my PLAN-B...but still passwing token is header is my priority]

UPDATE3:我尝试使用以下注释:

UPDATE3: I tried with annotations like:

nginx.ingress.kubernetes.io/auth-signin: 'https://auth.example.com/api/auth-service-ui/login'
nginx.ingress.kubernetes.io/auth-response-headers: 'UserID, Authorization, authorization'
nginx.ingress.kubernetes.io/auth-snippet: |
      auth_request_set $token $upstream_http_authorization;
      proxy_set_header Foo-Header1 $token; //not showing as request header AND this value only need LOOKS $token val is missed
      proxy_set_header Foo-Header headerfoo1; //showing as request header OK
      more_set_input_headers  'Authorization: $token';//not showing as request header AND this value only need LOOKS $token val is missed

nginx.ingress.kubernetes.io/configuration-snippet: |
      auth_request_set $token1 $upstream_http_authorization;
      add_header  authorization2 QQQAAQ1; //showing as response header OK no use
      add_header  authorization $token; //showing as response header OK how to send as request header on next call
      more_set_input_headers  'Authorization11: uuu1';//showing as request header in next call
      more_set_input_headers  'Authorization: $token1';//not showing as request header and need this val ONLY

**我错过了什么注释?

**What annotation I missed?

UPDATE4 PLAN-C:现在尝试将jwt令牌存储在cookie中.

UPDATE4 PLAN-C: Now trying to store jwt token in cookies.

 nginx.ingress.kubernetes.io/configuration-snippet: |
      auth_request_set $token5 $upstream_http_authorization;    
      add_header Set-Cookie "JWT_TOKEN=$token5";

在每个请求中都设置了相同的cookie,但是在浏览器中每次都存储它.即多个相同的Cookie.如何只设置一次?

In every request the same cookie is set but in browser its storing everytime. ie multiple cookies of same. How to set only once?

推荐答案

以下内容对我有用

输入您的价值观yaml:

put in your values yaml:

nginx.ingress.kubernetes.io/auth-url: "url service here"

然后,对于该URL,您必须实现一个GET服务,如果授权成功,则该服务将退回200;在其他情况下,则退回401.

then for this url you must implement a GET service that returs 200 if authorization was success or 401 in other case.

我是在烧瓶中实现的,具有基本授权,但是您可以随意使用

I implemented in flask, with Basic Authorization, but you can use whatever you want

 def auth():
  request_path = request.headers.get("X-Auth-Request-Redirect")
  authorization_header = request.headers.get('Authorization')
          
  if ServiceImp.auth(authorization_header,request_path):
   return Response(
                response="authorized",
                status=200, 
                mimetype="application/json"
   )
  else:
   resp = Response()
   resp.headers['WWW-Authenticate'] = 'Basic'
   return resp, 401

这篇关于如何使用kubernetes Ingress执行自定义身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆