D2L user password requirements - desire2learn

Are there any hard password requirements when setting a user's D2L Password via the Valence API?
Through trial & error we've discovered there is an 8-character minimum, which matches the message in the GUI: "Password must be between 8 and 50 characters in length."
Is that the only hard requirement or are there others? (alphanumeric, capitalization, no repeats, etc.)

The site administrator for the back-end Learning Service can specify the form a valid password must take (including allowed characters, length, and so forth) with the DOME variables found in the Auth>Password cluster of settings. The configured validation rules are not exposed through the Learning Framework APIs, so you will need to ask your site administrator if passwords have any rules about their form.
If you attempt an API call to update a user's password, and the password provided has an invalid form, the service will respond with an Invalid Request (400) error, but you likely won't get any further information about what form would be a valid one.
Accordingly, if you're writing a mobile client app, your app should likely tell the user to "contact the LMS system administrator for more information on what makes a valid password" or similar.

Related

Error message "You can't sign in to this app because it doesn't comply with Google's OAuth 2.0 policy for keeping apps secure"

I am developing a web-based application that will allow my trusted staff to edit the titles, descriptions, tags, etc. of my YouTube channel. In attempting to "Opt In" to my own application, I was sent to the callback URI with an error message:
You can't sign in to this app because it doesn't comply with Google's OAuth 2.0 policy for keeping apps secure. You can let the app developer know that this app doesn't comply with one or more Google validation rules.
Some history - when I first attempted to obtain a code to exchange to an authorization token, it actually worked! However, as I was writing the code to harvest the code and exchange it for the authorization token, I repeated the "Opt In" process multiple times. Before I was ever able to perfect my code to exchange the code for an authorization token, I began getting the error message to the effect that the app is insecure and cannot be signed in to.
More history - after reading a Stack Overflow article describing something similar, I deleted the project, created a new project, generated a new Client ID and Client Secret, and then repeated the test with the same failure.
I am the only Test User of the app. I can't find any notification in my console alerting me to nature of the security issue triggering the failures. I have reviewed the OAuth policies at
OAuth 2.0 Policies
and cannot find anything even remotely wrong.
What is wrong and how can I fix it?
I also had the same issue.
For me, it turned out that my redirect_uri is not valid. The redirect_uri that gives error:
http://localhost:8000api/vi/oauth/google
What are wrong in my case:
I should put a / before api.
vi is different from what I registered on GCP. It should be v1
I would suggest you to print out the redirect_uri when your app is performing code exchange, and verify every single characters carefully.
Additionally, check out the documentation of Redirect URI validation rules on Google to see if your redirect_uri comply with all the rules.
You probably changed the port where the project is running or you did not define the address where the project is running in Google Cloud.
Google Cloud → APIs and Services → Credentials → OAuth 2 Client ID → change Authorized JavaScript origin to the port that your app runs on the local or shared host.
The URL may take time to define, so it may not work right away, so you can also create a new credential.
For me the redirect_uri was correct, but as a result of an error, the access code was requested for a different client ID.

How does keycloak determine which signature algorithm to use?

I'm writing an application that uses keycloak as its user authentication service. I have normal users, who log in to keycloak from the frontend (web browsers), and service users, who log in from the backend (PHP on IIS). However, when I log in from the backend, keycloak uses HS256 as its signature algorithm for the access token, and thus rejects it for further communication because RS256 is set in the realm and client settings. To get around this issue, I would like to "pretend to be the frontend" to get RS256 signed access tokens for my service users.
For security reasons, I cannot give the HS256 key to the application server, as it's symmetrical and too many people can access the server's code.
I am currently debugging the issue using the same user/pw/client id/grant type both on the frontend and the backend, so that cannot be the issue.
So far I have tried these with no luck:
copying the user agent
copying every single HTTP header (Host, Accept, Content-Type, User-Agent, Accept-Encoding, Connection, even Content-Length is the same as the form data is the same)
double checking if the keycloak login is successful or not - it is, it's just that it uses the wrong signature algorithm
So how does keycloak determine which algorithm to sign tokens with? If it's different from version to version, where should I look in keycloak's code for the answer?
EDIT: clarification of the flow of login and reasons why backend handles it.
If a user logs in, this is what happens:
client --[login data]--> keycloak server
keycloak server --[access and refresh token with direct token granting]--> client
client --[access token]--> app server
(app server validates access token)
app server --[data]--> client
But in some occasions the fifth step's data is the list of users that exist in my realm. The problem with this is that keycloak requires one to have the view-users role to list users, which only exists in the master realm, so I cannot use the logged in user's token to retrieve it.
For this case, I created a special service user in the master realm that has the view-users role, and gets the data like this:
client --[asks for list of users]--> app server
app server --[login data of service user]--> keycloak server
keycloak server --[access token with direct granting]-->app server
app server --[access token]--> keycloak server's get user list API endpoint
(app server filters detailed user data to just a list of usernames)
app server --[list of users]--> client
This makes the the list of usernames effectively public, but all other data remains hidden from the clients - and for security/privacy reasons, I want to keep it this way, so I can't just put the service user's login data in a JS variable on the frontend.
In the latter list, step 4 is the one that fails, as step 3 returns a HS256 signed access token. In the former list, step 2 correctly returns an RS256 signed access token.
Thank you for the clarification. If I may, I will answer your question maybe differently than expected. While you focus on the token signature algorithm, I think there are either mistakes within your OAuth2 flows regarding their usage, or you are facing some misunderstanding.
The fact that both the backend and frontend use "Direct Access Granting" which refers to the OAuth2 flow Resources Owner Credentials Grant is either a false claim or is a mistake in your architecture.
As stated by Keycloak's own documentation (but also slightly differently in official OAuth.2 references):
Resource Owner Password Credentials Grant (Direct Access Grants) ... is used by REST clients that want to obtain a token on behalf of a
user. It is one HTTP POST request that contains the credentials of the
user as well as the id of the client and the client’s secret (if it is
a confidential client). The user’s credentials are sent within form
parameters. The HTTP response contains identity, access, and refresh
tokens.
As far as I can see the application(s) and use case(s) you've described do NOT need this flow.
My proposal
Instead what I'd have seen in your case for flow (1) is Authorization Code flow ...
assuming that "Client" refers to normal users in Browser (redirected to Keycloak auth. from your front app)
and assuming you do not actually need the id and access tokens back in your client, unless you have a valid reasonable reason. As the flows allowing that are considered legacy/deprecated and no more recommended. In this case, we would be speaking of Implicit Flow (and Password Grant flow is also discouraged now).
So I think that the presented exchange (first sequence with points 1 to 5 in your post) is invalid at some point.
For the second flow (backend -> list users), I'd propose two modifications:
Allow users to poll the front end application for the list of users and in turn the front-end will ask the backend to return it. The backend having a service account to a client with view-roles will be able to get the required data:
Client (logged) --> Request list.users to FRONTEND app --> Get list.users from BACKEND app
(<--> Keycloak Server)
<----------------------------------------- Return data.
Use Client Credentials Grant (flow) for Backend <> Keycloak exchanges for this use case. The app will have a service account to which you can assign specific scopes+roles. It will not work on-behalf of any user (even though you could retrieve the original requester another way!) but will do its work in a perfectly safe manner and kept simple. You can even define a specific Client for these exchanges that would be bearer-only.
After all if you go that way you don't have to worry about tokens signature or anything like that. This is handled automatically according to the scheme, flow and parties involved. I believe that by incorrectly making use of the flows you end up having to deal with tricky token issues. According to me that is the root cause and it will be more helpful than focusing on the signature problem. What do you think?
Did I miss something or am I completely wrong...?
You tell me.

Is there an OpenID Connect grant type or mechanism for an app to poll for the auth-code when redirect_uri doesn't apply?

If you have an on-device application (e.g. desktop program, mobile device app) you can use OpenID Connect with some caveats:
Using Resource Owner Credentials (grant_type: password) is the simplest, but might not be possible if the authentication server operator won't let you use that grant-type because of trust reasons (i.e. they don't want you collecting the user's username+password yourself) - or if they have a dynamic or custom authentication UI that would be hard to replicate in a native app.
With the interactive flows (implicit, hybrid) the authentication sever's authentication page is shown in an in-app web-view. Most users will have no idea that the application can snoop on the authentication page and capture their username and password, especially on mobile devices - but this way the application code can easily capture the authorization code and/or access token, and automatically dismiss the web-view without any additional user interaction. (I'm surprised I haven't heard of more cases of users' details being captured by malicious apps this way.)
...so the advice is to always open the authentication page using the system's web-browser, but on the Windows desktop there is no good, standard way for the system web-browser to return the server response to the application code, though there are a number of approaches currently in use:
The authentication success page instructs the user to copy and paste a blob of text (containing the authorization code or access_token response) back into the desktop application.
Show the page in an app-hosted web-view, as per the notes above.
If the authentication process always only needs a username and password (for example) the application could still capture the user's username and password with its own UI and then make its own HTTP requests to make it seem like a user's web-browser session, and get the authorization code and/or access_token that way.
On Windows only:
Have a small utility program authHelper.exe that when invoked forwards its command-line arguments to a named-pipe in the user's session.
The main client-application will register authHelper.exe as a temporary URI scheme handler in the per-user HKCU\Software\Classes key, e.g. my-application: such that the contents of any my-application: URI are passed as arguments into authHelper.exe.
The URI passed to the system web-browser to open the authentication page has the redirect_uri parameter set to my-application:, so after the user authenticates in the browser, the browser will request the custom URI scheme which is handled by Windows, which invokes authHelper.exe "access_token=..." which then sends the data down the named-pipe to the running application.
If the user doesn't have permission to write to their own HKCU\Software\Classes key, or if they're using a version of Windows that doesn't support custom URI scheme handlers with EXE registrations then this doesn't work.
Windows UWP applications can also use the Web Authentication Broker.
I was wondering if a different approach could be used: why can't the application simply poll the authentication server for the status of the authentication attempt? Or does this approach already exist, and if so, what is the name of the flow or grant?
Here's the flow I'm proposing:
When the user wants to authenticate, the application opens the system web-browser as before, but with another parameter for a one-time-use opaque ID provided by the application.
As soon as the system browser is open, the application makes requests every 500ms or so (i.e. a polling loop) to the authentication server using its own HTTP client that asks for the status of the active authentication attempt associated with the same opaque ID as before.
The initial few responses from the authentication server to the application will presumably be status: pending, but eventually after the user successfully authenticates within a timeout window then the application's poll request would indicate a successful attempt and also contains the access_token or authorization code as is applicable. If the user failed to authenticate (e.g. 3 incorrect attempts) or left the window open long enough causing a timeout then the poll response would indicate failure.
Does this already exist and does it have a name? Are there any potential security risks or vulnerabilities with this approach?
It exists and has a name, "OAuth 2.0 Device Flow for Browserless and Input Constrained Devices", but is not yet fully standardized, see: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-device-flow
Google also implemented this flow avant-la-lettre in a vendor-specific way:
https://developers.google.com/identity/protocols/OAuth2ForDevices

Using 2-legged OAuth with Gmail IMAP

I am trying to use OAuth to do a 2 legged authorization to the Gmail IMAP server, as documented
in https://developers.google.com/gmail/oauth_protocol. I am having trouble, getting "invalid credentials" in response to the AUTHENTICATE XOAUTH command.
Obviously there are many potential points of error in my code, but I believe I have the SHA1 generation, URL encoding, Base64 encoding, all done correctly. My specific question right now is regarding how to identify my application as being allowed to use 2LO. This documentation
(https://developers.google.com/accounts/docs/OAuth#GoogleAppsOAuth) says that third party software vendors must register their application with Google to use 2LO, and that domain administrators must grant access to those vendors. However, I have experimented with a commercial application that does this, and I am not required at any point to grant access to it, just supply it with my domain's consumer key and secret. It works fine. (Nevertheless, I have gone into the Google Apps console and checked "enable this consumer key" and "allow access to all APIs").
In the IMAP XOAUTH protocol, where would I tell it what my application is? The only place I see would be the "XOauth_requestor_id" parameter. Is that it? What do I put there? I have tried the email address and various other values that I get from the Google API control panel, but nothing works.
Any help or examples (of all the input data and resulting base64-encoded output) you can provide would be appreciated.

Handling login functionality for native app connecting to web service

After extensive research, I have not been able to find a clear answer to my question. Firstly, can anyone tell me the basic logic of handling "login functionality" for a native iphone app connecting to a web service? For instance, the facebook app ask for a username and password immediately after launch, and from there you have full access to your account in all successive views of the app. Each time you post something etc, you do not have to re-login... Can someone please explain this process to me? Is it done through cookies or sessions? is Keychain involved?
I have a semi-working app right now but I'm almost positive I could be doing it better and more securely. Here is what I'm doing:
1) Set up a local server with a database of users (username and password columns and other tables etc.) using mysql. Wrote a simple web-service that takes in POST data and queries the database to check that the username exists... and if it does, that the passwords are equal. Using sha1 hashing. Echo true or false accordingly.
2) My app has an initial login screen with a 2 textfields (1 for username and 1 for password) and a button that calls the login method. My login method does the following:
init an *NSURL with a string (the url of my web service: #"http://webservice.com/login.php")
init an *ASIFormDataRequst with that url
set the post value with the password and email text in the text fields
set the delegate to itself
call startAsycronous on the request
implemented the requestFininshed method to retrieve the "true" or "false" echo-ed from the webservice
depending on the response, move forward to the next view, else, make an alert telling the user to retry
So, my questions are:
1) Is this secure for sending passwords? (via ASIHTTPRequest and the POST method?)
2) In the succeeding views, the user should be able to interact with their account (like posting messages and status's and pictures on the Facebook) How do I persist the user's logged in status so that every time the user interacts with the database, I can ensure that the user is still logged in and that it's the same user? For instance, the only way I can think of doing this is if I store a cookie on the users device with the username and password, and then every successive interaction with the web service / database, it does an authentication with the cookie values (username and password).
There has got to be a better way of doing this? Maybe sessions or cookies? or by using keychain??
Thanks for the help guys, and sorry for the long question!
Here are my thoughts based on what I know:
1) Is this secure for sending passwords? (via ASIHTTPRequest and the POST method?)
You need to make sure you are sending this information via https (SSL) and not a plain Http. The reason is, you don't have control over where the user wireless access point is. For all you know, the user could connect to open access point that is belong to a particular hacker. Having it transmitted will enable him to sniff the packet and get the required information to access the WebService even though the password is hashed. Having it send via https would ensure that the packet is encrypted with strong key. Even if a hacker manage to sniff the packet out, it will take him a long time before he/she is able to decrypt the message.
In the succeeding views, the user should be able to interact with their account (like posting > messages and status's and pictures on the Facebook) How do I persist the user's logged in status > so that every time the user interacts with the database, I can ensure that the user is still logged in
and that it's the same user?
One commonly employed method to do this is to get the session token after the user logged in. That is, you create a random generated ID that you return upon successful login. You would then map this token with the user id in the backend and it is associated with a session time out. You refresh this time out every time the user connects to a webservice and time it out after certain period to avoid breach of security. You would then persist the session token in your device and then used that for subsequent call. As long the session is alive then the user is logged in. As the token is associated with a specific user, you also ensure the identity of the caller.
To prevent someone else using other people token is the reason why you need SSL to secure the channel and prevent sniffing. Assuming that you have secured your connection channels, the only way to get the token is
to verify the identity via login
The phone is stolen by hackers who could take the token by inspecting the local storage.
The mapping is necessary so you could validate the token is a real token that has been associated with the user via login activity. Furthermore,for number 2, you can offer remote wipe out feature that basically kills the mapping and making that token invalid.
Another very important part of this token is the token cannot be guessable and have to be random cryptographically (see Randomness Recommendations for Security). If the token is only based on pseudo randomness, a clever hacker might be able to guess its algorithm and can guess its next/previous token and has a possibility of obtaining any valid token in the table.
There are many algorithm to generate this token. For example, Java Programming Language provides a SecureRandom class in order to provide cryptographically randomness and .NET has similar secure RandomGenerator class.
If you want to look at the algorithm OATH has proposed Time-Based One-Time Password Algorithm (TOTP) which is an extension of HOTP. Most of the languages/platforms would have the cryptographically strong random generator that you could leverage immediately though without you having to write it yourself.
Depending on your service implementation/platform, you might want to ask SO for a suitable class/module for cryptographically random generator such as the one asked here "How do you generate cryptographically secure random numbers with php"

Resources