How can I access the auth_mellon nameId property in my javascript application - saml-2.0

I have implemented mod_auth_mellon in my apache httpd 2.4 webserver. I configured Mellon to authenticate when I try to access my oracle JET application.
So far all is good, when I go to http://example.com, I am redirected to my sso login page and after entering my credentials I am sent back to https://example.com.
My problem is that once I return to my application at https://example.com, I need to be able to access the Mellon-nameid attribute so I can retrieve user privilleges from a database talbe based on email address.
According to all the docs I have read, mod_auth_mellon stores the mellonUser attribute in the apache environment, and/or the response headers.
Also according to what I have read, there is no way in my JET application to access the apache environment variables, and so far I haven't found a way to examine the response headers to get the mellonUser from there either.
Is there an alternate way to access the MellonUser attribute? Can it be stored in teh Mellon cookie, or maybe put on the url as a query parameter?
Also any methods for accessing the headers would be appreciated as well.

Just posting here, even though it's an old thread.
So when you use Apache Mellon, you can supply the nameID in a header value. If you are using apache as a proxy, (I.E you successfully authenticated, now go through the proxy), the web server can access the nameID as an attribute. You can also pass whatever other SAML attributes you want (Assuming you already know how to do this, i'll leave this part out).
Now the problem is, that header value is something the web app (Backend) sees BEHIND the proxy. Javascript is ran client side, in the user's actual browser. So in this scenario it would not be able to see this value unless you tell the backend to send it forward.
As an example, if you setup Apache SAML and then have it proxy to a PHP app, and you have a page that simply dumps the headers:
<?php
foreach (getallheaders() as $name => $value) {
echo "$name: $value\n";
}
?>
OR:
<?php
var_dump($_SERVER);
?>
VIOLA, you can see the nameid and whatever other attributes! However, go to your web console, and poke around, or check out your headers... these will be different because you are getting headers from pre-proxy, while the webapp gets headers from the post-proxy.
So what can you do? In my php example, since PHP will parse first, you can grab the variable from the backend, and echo it into a script that will be ran after this is all done.
<script>
username = "<?php echo $YourHeaderNameID; ?>";
</script>
However, there is some danger to this as well. Client side Javascript and be easily modified. So if your username "johnsmith", and you wanted to change the website username to "joeschmoe", that would be trivial. You should probably have the backend provide whatever user information you require, and then use javascript to style, rearrange, do whatever with.

Related

AppEngine authentication through Node.js

I'm trying to write a VSCode extension where users could log into Google AppEngine with a google account, and I need to get their SACSID cookie to make appengine requests.
So I'm opening a browser window at
https://accounts.google.com/ServiceLogin?service=ah&passive=true&continue=https://appengine.google.com/_ah/conflogin%3Fcontinue%3Dhttp://localhost:3000/
(generated by google.appengine.api.users.create_login_url)
The user logs in and is redirected to my local webserver at
localhost:3000/_ah/conflogin/?state={state}
Now I try to forward the request to my AppEngine app (since it knows how to decode the state parameter), so I do a request to
https://my-app.appspot.com/_ah/conflogin/?state={state}
basically just replacing localhost with the actual app.
but it doesn't work, presumably because the domain is different. I assume this is on purpose, for security.
Is there any way I can make this work ?
Not ideal, but the only solution I've found is to have an endpoint on my GAE instance that does the redirection. Then I can set that as the continue url, when I'm starting the authentication process
https://accounts.google.com/ServiceLogin?service=ah&passive=true&continue=https://appengine.google.com/_ah/conflogin%3Fcontinue%3Dhttps://my-app.appspot.com/redirect?to=http://localhost:3000
I think you should center the attention on the protocols you are using, since it’s known that the cookie name is based on the http protocol (HTTP : ACSID, HTTPS:SACSID), and that’s the security perspective till this point for me.
Having the error you are facing now would be helpful to understand the problem better. Also, how are you performing the call to the API and the code you are using would be helpful too.

Email does not send in Laravel API after writing to database

I have an AngularJS 1.5 application which is working with a Laravel 5.2 API and I'm trying to send emails at different points in the application. So I'm able to send data to Laravel and it gets recorded in the tables I specify but when it gets to sending a confirmation email it gives me this error with an HTTP status code of 500: MethodNotAllowedHttpException
Odd thing is, it works perfectly fine in local development on my laptop. But the same functions on the AWS EC2 instance and it fails when it gets to sending any email. I'm using SendGrid to manage sending emails but I don't think I need to change any settings for that.
For Example:
$emailUser = array();
$emailUser['email'] = $request->email;
$emailUser['first_name'] = $request->first_name;
$emailUser['last_name'] = $request->last_name;
$emailUser['randomStr'] = str_random(36);
$emailUser['remove_dtm'] = Carbon::now()->addWeeks(2);
//Add a password reset set to 2 weeks out for the user to register
DB::table('password_resets')->insert([
'email' => $emailUser['email'],
'token' => $emailUser['randomStr'],
'remove_dtm' => $emailUser['remove_dtm']
]);
Mail::send('email.registered_user', $emailUser, function($message) use ($emailUser)
{ $message->to($emailUser['email'], $emailUser['first_name'] . ' ' . $emailUser['last_name']);
$message->from('WSCUSTOMERPO#waterstoneco.com', 'Waterstone Faucets');
$message->replyTo('WSCUSTOMERPO#waterstoneco.com', 'Waterstone Faucets');
$message->subject("Welcome to the Waterstone Faucets Portal!");
});
When I try to reset a user's password it will create the record in the password_reset table but not send the email on the live site. Again the same function works fine on my laptop. I checked that I'm posting on the Angular side and Laravel API is expecting a post HTTP call when running this function.
What am I missing here?
Thank you greatly for your help!
There are a few things to check here,
1: Are you sure you have your .env file set up to use the correct SMTP server settings to use SendGrid. If you forgot to set this up in your .env you will be using the internal mail function. Instead of using SendGrid, I would suggest keeping it inside of Amazon for more reliability. Switching over to Amazon SES may be a great option for you.
2: If you are using the internal mail system, there is a really good article about mail from Amazon EC2 instances here: http://shlomoswidler.com/2009/07/sending-email-from-ec2.html
Just a reminder for number 1 for others that may have come here looking for help. To set your mail service in Laravel to use an smtp service, open your config/mail.php file and set the driver to use your provider (if provided by laravel). This can be done by edit the file directly or setting the environment variable MAIL_DRIVER in your .env file.

GAE Cloud Endpoints custom API public api key issues

I've exposed a few APIs using go-endpoints. The APIs work fine, but what I'd like to do is restrict usage of the APIs to only a few referers. Since I'm not passing any authentication information, I do not need OAuth (actually, I really do not want to use OAuth as I expect anonymous users to utilize a front-end that uses this API... I just want that front-end and perhaps another one to use my API).
Apparently the way to do this is to make a Public API Key using the Google Developers Console (Project --> APIs and auth --> Credentials --> Create new Key).
I've changed my JavaScript to use this key, by passing it as a param: https://my-app-id.appspot.com/_ah/api/myService/v1/doSomething?key=key_from_developer_console
However, when I make the call, I get a 403 back with this error:
"Access Not Configured. The API () is not enabled for your project. Please use the Google Developers Console to update your configuration."
Well, initially I set the referer to my-app-id.appspot.com/*, which is only place I want my API to be used from. So I figured I'd remove it just to see, but I get the same issue.
There are some old posts here about having to enable Contacts API and Google + API. I tried that, and it didn't work either.
So what gives? There is virtually no documentation from Google on this Public API Key feature. This is really driving me up a wall...
I had this exact same problem yesterday. I decided to generate my own key and added in my own logic to check for the 'key' param from the request. I just added the self-generated key to my env_variables and it works. However, if you try to redeploy after taking this approach, you may still see the access configuration issues..at least I have still.

Can't configure varnish to work with cookies and drupal module

I'm using cookies so that mobile users can visit my site as desktop users. To do this, I give them a cookie - mob_yes.
Then, in a module, i use a drupal hook to see if the cookie is set.
I can see that the cookie IS getting set, but in my module (isset($_COOKIE["mob_yes"])) always returns false when using varnish.
In /etc/varnish/default.vlc I have the following:
if (req.http.Cookie) {
set req.http.Cookie = regsuball(req.http.Cookie, ";(mob_yes)=", "; \1=");
I'm really not sure what's going on here, but I only presume varnish is not unsetting that cookie temporarily? Does anyone have any idea what's going wrong here?
Thanks,
what do you mean by
I can see that the cookie IS getting set
you mean that you can see it in headers in firebug (client side) and then you see it on the server side with tcpdump / varnishlog / application (server side)?
code snippet from vcl is probably part of commonly used way of preserving important cookies by adding a space in front of them, deleting all that dont have ";[space]" combination and removing space at the end.
It is used later on to generate hash for specific url+cookies request.
i think you should check your vcl if its not removing any cookies if user is not logged in - it's a common practice to increase hitrate.
usually in vcl for drupal it's part which checks for DRUPAL_UID

Using a subdomain to identify a client

I'm working on building a Silverlight application whereas we want to be able to have a client hit a url like:
http://{client}.domain.com/
and login, where the {client} part is their business name. so for example, google's would be:
http://google.domain.com/
What I was wondering was if anyone has been able, in silverlight, to be able to use this subdomain model to make decisions on the call to the web server so that you can switch to a specific database to run a query? Unfortunately, it's something that is quite necessary for the project, as we are trying to make it easy for their employees to get their company specific information for our software.
Wouldn't it work to put the service on a specific subdomain itself, such as wcf.example.com, and then setup a cross domain policy file on the service to allow it to access it?
As long as this would work you could just load the silverlight in the proper subdomain and then pass that subdomain to your service and let it do its thing.
Some examples of this below:
Silverlight Cross Domain Services
Silverlight Cross Domain Policy Helpers
On the server side you can check the HTTP 1.1 Host header to see how the user came to your server and do the necessary customization based on that.
I think you cannot do this with Silverlight alone, I know you cannot do this without problems with Javascript, Ajax etc. . That is because a sub domain is - for security reasons - treated otherwise than a sub-page by the browsers.
What about the following idea: Insert a rewrite rule to your web server software. So if http://google.domain.com is called, the web server itself rewrites the URL to something like http://www.domain.com/google/ (or better: http://www.domain.com/customers/google/). Would that help?
Georgi:
That would help if it would be static, but alas, it's going to all be dynamic. My hope was to have 1x deployment for the application, and to use the http://google.domain.com/ idea to switch to the correct database for the user. I recall doing this once when we built an asp.net website, using the domain context to figure out what skin to use, etc.
Ates: Can you explain more about what you are saying... sounds like you are close to what I am trying to come up with. Have you seen such a tutorial for this?
The only other way I have come up with to make this work is to have a metabase that when the user logs in, it will switch them to the appropriate database as required... was just thinking as well that telling Client x to hit:
http://ClientX.domain.com/ would have been sweeter than saying to hit http://www.domain.com/ and login. It seemed as if they were to hit their name, and to show it personalized for them right from the login screen would have been much more appealing for the client base.
#Richard B: No, I can't think of any such tutorial that I've seen before. I'll try to be more verbose.
The server-side approach in more detail:
Direct *.example.com to the same IP in your DNS settings.
The backend app that handles login checks the Host HTTP header (e.g. the "HTTP_HOST" server variable in some platforms). That would contain the exact subdomain.example.com that the client used for reaching your server. Extract the subdomain part and continue...
There can also be a client-side-only approach. I don't know much about Silverlight but I'm assuming that you should be able to interface Silverlight with JavaScript. You could read document.location with JavaScript and pass it to your Silverlight applet, whereon further data fetching etc. logic would rely on the subdomain that was passed in by JavaScript.
#Ates:
That is what we did when we wrote the ASP.Net system... we pushed a slew of *.example.com hosts against the web server, and handled using the HTTP headers. The hold-up comes when dealing with WCF pushing the info between the client and the server... it can only exist in one domain...
So, for example, when you have {client}.example.com and {sandbox}.example.com, the WCF service can't be registered to both. It also cannot be registered to just *.example.com or example.com, so that's where the catch 22 is coming in at. everything else I have the prior knowledge of handling.
I recall a method by which an application can "spoof" another domain name in certain instances. I take it in this case, I would need to do such a configuration? Much to research yet I believe.

Resources