2

searched a lot, and referred to this, but didn't get detailed answer.

I wanted to get LDAP login user name(X-Forwarded-User attribute set by nginx) from http header within React component(client side), tried first approach in link with 'fetch', get empty header; second approach to use window.INITIAL_HEADERS variable, not quite clear how to use it in React component. What's the right way to do it? and how to get other attributes of LDAP login user, eg. email ( there is a LDAP attribute 'email' configured on LDAP server) . Thanks.

relative nginx conf as below

location /noc/ {
        auth_ldap "Enter AD credentials: ";
        auth_ldap_servers server1;
        keepalive_timeout 300s;
        proxy_pass http://ui/noc/;
        proxy_set_header X-Forwarded-User $remote_user;

}

React JS, used React Route in App.js for the component link

//in another file Noc.js for the React component
fetch("/noc/").then(response=>{
  console.log("headers:");
  console.log(response.headers); //empty {}
});
Chrisamd
  • 33
  • 6
  • used React Route for the component link – Chrisamd Mar 18 '19 at 06:26
  • Are you doing cross-domain requests ? – Arnaud Christ Mar 18 '19 at 06:52
  • just LDAP server resides in a different server(server1 configured on Nginx), others(all requests from React) are all in same domain, so same domain I suppose? – Chrisamd Mar 18 '19 at 06:57
  • If your front-end is running on the same host than your API, then yes, you are not in CORS mode. Otherwise you would have to expose your header in the `Access-Control-Expose-Headers` – Arnaud Christ Mar 18 '19 at 07:02
  • there seems no API involved for this as I observed( or maybe need LDAP server config), just Nginx config and client React, when user hit /noc/ , it's authenticated by ldap_server server1, and user is set to header by nginx, then pass on to http://ui/noc/, or am I missing something – Chrisamd Mar 18 '19 at 07:04
  • By API I mean the server endpoint you are calling within your `fetch` request in your React application. – Arnaud Christ Mar 18 '19 at 07:06
  • the path /noc/ is set with React Route, when /noc/ hit by user, it'll trigger 'location' config in Nginx, then bring up a LDAP authentication window ask user to login, if successful, then nginx will set user name in header and pass on to the actual page – Chrisamd Mar 18 '19 at 07:12
  • There is add_header "Access-Control-Expose-Headers" and "Access-Control-Allow-Headers" in Nginx config, I see. then what's next? 'fetch' doesn't work, header still empty as have just tried with `add_header "Access-Control-Expose-Headers" "Authorization, X-Custom-Header, X-Forwarded-User"; ` added to Nginx config. as the header is set by Nginx server just when user login, so looks like another fetch after login will not get same header as before I suppose, and X-Forwarded-User attribute is at server end http header, is it? Thanks – Chrisamd Mar 18 '19 at 07:45

2 Answers2

1

As mentioned here , client React JS cannot get http header set at server side, the solution we used is to use 'rewrite' config of Nginx to redirect request to an URL with remote_user added as a param, then React can parse this param at client side.

location /noc/auth {
  ...
  rewrite ^.* http://$server_name/noc/?user=$remote_user;
}

then in JS

  let params = queryString.parse(this.props.location.search);
  console.log("user:" + params.user);
Chrisamd
  • 33
  • 6
0

want to add more update here, I tried authentication with 2 approaches for our React app. as we use Docker container to run nginx, firstly in order to add nginx auth module(nginx-auth-ldap or nginx-http-shibboleth), need to change Dockerfile to use FROM ubuntu:16.04 to add the module

FROM ubuntu:16.04

RUN apt-get update \
&& apt-get install -y  opensaml2-schemas xmltooling-schemas libshibsp6 apt-transport- 
https \
     libshibsp-plugins shibboleth-sp2-common shibboleth-sp2-utils supervisor procps 
wget git curl \
     build-essential libpcre3 libpcre3-dev libpcrecpp0v5 libssl-dev zlib1g-dev \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /opt

RUN git clone https://github.com/openresty/headers-more-nginx-module.git \
&& git clone https://github.com/nginx-shib/nginx-http-shibboleth \
&& wget http://nginx.org/download/nginx-1.14.2.tar.gz \
&& tar -xzvf nginx-1.14.2.tar.gz \
&& cd nginx-1.14.2 \
&& ./configure --sbin-path=/usr/sbin/nginx \
   --conf-path=/etc/nginx/nginx.conf \
   --pid-path=/run/nginx.pid \
   --error-log-path=/var/log/nginx/error.log \
   --http-log-path=/var/log/nginx/access.log \
   --with-http_ssl_module \
   --with-ipv6 \
   --add-module=/opt/nginx-http-shibboleth \
   --add-module=/opt/headers-more-nginx-module \
&& make \
&& make install

RUN cp /opt/nginx-http-shibboleth/includes/shib_* /etc/nginx

the two approaches tried,

  1. Nginx + LDAP used the config posted earlier and nginx-auth-ldap, it works and got user name from URL param rewritten by nginx

  2. Nginx + shibboleth used nginx-http-shibboleth took me a long time to solve this problem, basically due to inconsistent attribute ID configured on IDP server and client side, tip is to turn on DEBUG of shibd.logger

the working config on client side is, in -idp-metadata.xml

<saml:Attribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" Name="urn:oid:0.9.2342.19200300.100.1.3" FriendlyName="mail" />

and enable "mail" attribute in attribute-map.xml, (refer to this for IDP server config)

<Attribute name="urn:mace:dir:attribute-def:mail" id="mail"/>

<Attribute name="urn:oid:0.9.2342.19200300.100.1.3" id="mail"/>

and in shibboleth2.xml

<Handler type="Session" Location="/Session" showAttributeValues="true"/>

in http server section for nginx.conf, email is set to cookie with "mail" as key, note it's $upstream_http_variable_mail different from module official doc($upstream_http_variable_email)

server {
    listen              443;
    server_name  __MY_DOMAIN_NAME__;

    location = /shibauthorizer {
        internal;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/shibboleth/shibauthorizer.sock;
    }

    location /Shibboleth.sso {
        include fastcgi_params;
        fastcgi_pass unix:/var/run/shibboleth/shibresponder.sock;
    }

    location /shibboleth-sp {
        alias /usr/share/shibboleth/;
    }

    location / {
        shib_request /shibauthorizer;
        shib_request_use_headers on;

        #include shib_clear_headers;
        include shib_fastcgi_params;
        shib_request_set $shib_mail $upstream_http_variable_mail;
        add_header Set-Cookie mail=$shib_mail;

        root   /usr/share/nginx/html;
        #index  index.html index.htm;
        try_files $uri /index.html;
    }

then use 'universal-cookie' in React to read mail from cookie, done!

console.log("cookie mail:" + cookies.get('mail'));
Chrisamd
  • 33
  • 6