RavenDB attachments with authentication - ravendb

I am running RavenDB server build 2174 with the following lines added to the Raven.Server.exe.config file:
<add key="Raven/Authorization/Windows/RequiredGroups" value="localhost\Administrators"/>
<add key="Raven/AnonymousAccess" value="None"/>
I have also setup an ApiKey that my application uses to interact with the RavenDB server and database. The ApiKey has been given Admin rights (checked the admin checkbox) for the database that I am working with.
With the configuration given above, I am trying to load attachments from the RavenDB database using the DatabaseCommands.GetAttachment() method. Whenever I do this, I get a 401 (Unauthorized) response. I have been able to get it working by using the With() method on the DatabaseCommands object to pass in authentication using a login and password combination from the Administrators group. Here is the line of code that does this
SiteDocumentStore.DatabaseCommands
.With(new NetworkCredential("login", "password", "domain"))
.GetAttachment(attachment_key);
So my question is, how can I use the GetAttachment() method without having to use the With() and pass in login credentials? The DocumentStore already has the ApiKey and it using it for all the other commands without the need to do anything special. In fact the PutAttachment() method works without having to use the With() method, so why can't the GetAttachment()? Is this an oversight or a bug? Or is there something that I'm just no getting?

You are NOT using the Api Key when you are using login/pass, and it should automatically authenticate with the right Api Key for you.
We just identified a bug in using Api Keys in certain circustances, please wait for the next build (2176), which should resolve it.

Related

GetAccessTokenForUserAsync throws an exception

I'm trying to call a Web API from a Web App, passing a token for identifying the user.
I'm following the docs here:
https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-web-app-call-api-acquire-token?tabs=aspnetcore
However, when I call the GetAccessTokenForUserAsync method, I always get an error AADSTS65001, stating that The user or administrator has not consented to use the application with ID '....' named '...'.
I really don't understand this error. What kind of consent are we looking for here? The application ID mentioned in the error message is the client app, and I double checked that the scopes accessed from the client app in the API are already consented.
What am I missing? I thought it should be quite straightforward - take the token received by the web app, send it to the web API, and let it authenticate it.
Is there any simple way of doing that?
Thanks!
So for future reference, the problem was that the scopes specified in the GetAccessTokenForUserAsync method were not prefixed with the API URL prefix (usually in the form of api://346363-35262ffe-23cwf3-ve523632t), and therefore Azure AD assumed I was trying to access my own app, which did not have such scopes.
After I changed the code to include the prefix in the scope, ie. _tokenAcquisition.GetAccessTokenForUserAsync(new[] { $"api://346363-35262ffe-23cwf3-ve523632t/Employees.Read" }) it worked like a charm.

Create User via API in Azure AD

GOAL: Create users in Azure Active Directory using our Global Admin account from an API.
PROBLEM: Every single way I try, I get "unauthorized".
WHAT I'VE TRIED:
I've been focusing mostly on this: https://graph.microsoft.com/v1.0/invitations
I've tried as outlined here
the "Authorization Bearer {token}" is problematic -- I can't seem to properly retrieve tokens, using any of the built URLs recommended (ie, combining ClientID & TenantID in the URL.)
I've tried the relevant portions of this, including creating the app, setting permissions on the app, trying both Web API and Native. I'm able to get a code back, but using it always comes back with Unauthorized.
As an aside, I am using Nintex to run this web service, as it is part of my workflow. Typically, web services don't give me issues. So, this sucks.
I'm missing something, here. Any thoughts or direction?
UPDATE: Removed the word "method" - bad choice of phrasing.
If you want to use Microsoft Graph explorer to create user as the global admin, you could use POST https://graph.microsoft.com/v1.0/users, and the required permission is:
Permissions
For the details, you could read Create user.
Global admin runs as a user by default. To grant access to Active Directory, you need to elevate permissions in the portal.
I'm not convinced you have the permissions to create the user, and that's why I think you're getting the error.
Also, try and avoid using Global Admin. Create a Service Principal and provide more granular permissions.

passing credential in HttpWebRequest In UrabanCode Deploy

I am using HttpwebRequest to pull list of all Components from Urban-code Deploy to my application. I have used my own credential in the code(C#) to access it. It is working fine. Now, i have to use the Service account that my company has, in order to pass the credential. I tried using DefaultCredential and defaultNetworkcredential but getting same error--Unauthorized access. Any help!!! Thank u!!!
You got an answer on the UrbanCode forum here: https://developer.ibm.com/answers/questions/372586/authentication-using-service-account-without-admin/?smartspace=urbancode
You just need a user account in the system with permissions to access the data. Accessing data via REST API requires the same permissions as through the UI. There's no way to bypass that.

Intermittent "Authorization Required" exception when logging into servicem8 API from FileMaker

I have a FileMaker application which pulls Jobs (and clients etc) from servicem8 using the API. As its a private application I just use username/password in the GET_URL. It usually works, but now and then will not login correctly, and I get the message:
- "Authorisation Required"
Restarting FileMaker and/or pasting the URL directly into a browser then trying again seems to resolve the problem.
The only other consistent behaviour seems to be that once it fails once, it will not work again until I restart as above.
Anyone found similar issues or have any ideas?
For Private applications servicem8 uses HTTP Basic Authentication. You can try to reset cached request by calling the same url from FileMaker with a different, but incorrect username and password and then repeating the original request with correct credentials.
servicem8 documentation uses curl for authentication examples and I think this will work better. To implement curl you will need a plugin, like BaseElements or MBS, although on a mac curl could be called through AppleScript.
Try using
BE_Curl_Set_Option ( "CURLOPT_HTTPAUTH" ; 1 )
From This BaseElements help article, we can be sure that Basic clearly isn't the default method:
BE_Curl_Set_Option ( "CURLOPT_HTTPAUTH" ; 1 ) forces Basic auth for
some sites that won't work with the defaults.
ServiceM8 will work consistently with basic auth for private applications as you say, but there are other authentications that will only work when other valid session data is present, which can be misleading when it works at times and not others.

How do I get Basic Authentication, GlassFish, REST, and a single page application to all work together with my own login form?

I'm using Glassfish 4 as a server with an AngularJS app as a client. Glassfish is exposing a REST API via JAX-RS (Jersey). I'm using Basic Authentication over an HTTPS connection. I have my own login form and am setting the Authorization header in my REST requests via JavaScript. My issue is that if I use normal web.xml based permissions (<auth-constraint> inside <security-constraint>), the responses come back with 401 with a WWW-Authenticate header (if the credentials are bad). This forces the browser to do the Basic Authentication dialog instead of my own and it appears there is no viable cross browser work around available on the browser side to stop it. So I need to somehow suppress the 401/WWW-Authenticate response.
I stopped using the web.xml based permissions, because it seems it is the Servlet level that is doing the 401 stuff. I was able to get Jersey authentication working with a filter and turning on the "RolesAllowedDynamicFeature" feature (in a matter similar to Glassfish #RolesAllowed with custom SecurityContext). That seems to work great and returns 403 for bad credentials (and thus no browser dialog). However, when I call my EJB's, they do not see the custom security context and the user I have set, so I get permission exceptions. If it matters: the EJB's are in a jar, the Jersey stuff is in a war, and both of them and bundled together in an ear. From what I can gather the only way to have the EJB's properly process credentials is to use the web.xml stuff.
I seemed to have painted myself into a corner and do not see how to make this work. Perhaps I can back out and return to using web.xml based permissions and somehow filter the servlet responses to not return 401/WWW-Authenticate? If so I could not find out how to do that. Or is there some way I can set EJB's security context? Or something else entirely? I wouldn't think using AngularJS with GlassFish and a REST API and Basic Authentication would be very unique, how does anyone do this?
Since posting this question I have found info on implementing a Servlet filter and using that to try to change the 401 response to a different status code. However, the filter never gains control if you have <auth-constraint> in your web.xml and the request is not authorized, so that did not help me. I still could not prevent the 401 responses.
But now I think I finally found the answer. I removed the <auth-constraint> tag from web.xml. I changed the Servlet filter to now extract the AUTHENTICATION_HEADER on its own and decode it (via javax.xml.bind.DatatypeConverter). Next I call HttpServletRequest.login (on the request object) with the decoded username and password. I catch the ServletException if the username/password combination is bad and use HttpServletResponse.sendError to send SC_FORBIDDEN. If I have a good login I call doFilter to continue on with processing of the request, and call HttpServletRequest.logout when it returns.
If I do this in combination with RolesAllowedDynamicFeature and annotations on the Jersey routines everything seems to work including calls to EJB's with their own security annotations.
Side note: before settling on HttpServletRequest.login I had tried to use HttpServletRequest.authenticate followed by checking the returned boolean, but when you gain control in that case the response has already been committed to be 401 and you cannot change it. I even tried passing a HttpServletResponseWrapper to authenticate to stop the commit from happening, but authenticate seems to get the response object through some other means, it seems to ignore the one you pass it (I even tried passed null and it didn't even notice).