Code Monkey home page Code Monkey logo

oa4mp's Introduction

OAuth for MyProxy

DOI Javadocs NSF-1127210

Open Authorization for Many People (OA4MP) is an robust OAuth client/server implementation from the NCSA that provides authorization and delegation software for science gateways. Initially deployed in 2011, it is a mature, stable and extremely extensible system that is widely used.

Prerequisites

Docs

https://oa4mp.org

License

Please see the NCSA license for details

Building from sources

Getting the sources

You may check out the source from GitHub. This is cloned into $NCSA_DEV_INPUT. At the end of the cloning, you should have $NCSA_DEV_INPUT/oa4mp. A typical sequence would be

$>export NCSA_DEV_INPUT=/path/to/ncsa/git
$>cd $NCSA_DEV_INPUT
$>git clone (whatever you want)
$>cd oa4mp

How to compile, deploy etc.

There are a couple of ways todo this. You can

  1. compile and install OA4MP locally using just maven
  2. do the entire build with artifacts which may then be released (typically on GitHub)
  3. compile and install with maven, then deploy to Sonatype to be used as depedencies by other projects

Required environment variables

There are a few environment variables you should define before doing anything. These are used everywhere.

  • NCSA_DEV_INPUT - the root for the sources
  • NCSA_DEV_OUTPUT - where any created artifacts go
  • JAVA_HOME - this is required by maven or it won't know where to find the javadoc tools

Building by the numbers

Updating the release version

Do a global replace of the SNAPSHOT tag with the version you are creating. E.g. replace 5.3-SNAPSHOT with 5.3.5. Note this must be global in all files since this is used extensively in the documentation. If you are updating teh website, you do not need to update anything in $NCSA_DEV_INPUT/oa4mp/docs which will be replaced shortly.

Option 1

From the checked out directory $NCSA_DEV_INPUT/oa4mp issue

mvn clean install

which will download a ton of stuff and build OA4MP. This may, depending on your version of Maven, have the occasional warning like "illegal reflective operation" which is benign. What that means is that one of the dependencies squirreled away is not quite up to date. Ignore these. As long as the build completes, you are fine

Option 2

From the checked out directory $NCSA_DEV_INPUT/oa4mp issue

./build.sh

which will run Maven (see note in Option 1 for possible warnings) then create deploayment artifacts. Note that the output from the maven build will be put into the file maven.log and should be consulted if there is an error. The artifact will reside in $NCSA_DEV_OUTPUT/client for things related to the OA4MP client and $NCSA_DEV_OUTPUT/server for server related items. Typical list of each follows.

Client artifacts

Name Description
client2.war The client war to be deployed under Tomcat
client-X.sql The SQL creation script for database X, e.g. MySQL, Derby, Postgres

Server artifacts

Name Description
clc script to run the CLC (command line client)
clc.jar runnable jar for the Command Line Client
cli script to run the CLI (command line interface, the chief admin tool for OA4MP)
cli.jar runnable jar for the CLI
jwt.jar runnable jar for JSON web keys
jwt-scripts.tar scripts for the JSON web keys utility
oa4mp-X.sql SQL creation scripts for database X, e.g., mysql, derby, etc.
oa4mp-X.template sample subject and message templates for email notifications under OA4MP
oauth2.war the deployable war for Tomcat. This is actually OA4MP.
oidc-cm-scripts.tar command line utilities and sample scripts for using the client management API

You may or may not want to commit these to GitHub. If so, you must have commit privileges. You should create a release in GitHub and upload these files.

Option 3

In this case, you must be registered at Sonatype as an administrator for OA4MP and have uploaded your public keys for signing maven artifacts. The basic steps are

  1. Enable gpg signing in the top-level pom, as well as in the oa4mp server and client poms.
  2. Run mvn clean install first.
  3. Run mvn deploy after install has completed

The reason we do not run mvn clean install deploy or some such is that the creation of the various jars is actually complex and it is best done in a separate stage, since the automatic resolution maven uses tends to have multiple jars created then deploy complains.

Building and deploying the website

You can also update the website. You must be able to commit to Github to do this. The basic way this works is that you

  1. Do a global replace of the SNAPSHOT tag with the version you are creating. E.g. replace 5.3-SNAPSHOT with 5.3.5. Note this must be global in all files since this is used extensively in the documentation. You do not need to update anything in $NCSA_DEV_INPUT/oa4mp/docs which will be replaced shortly.
  2. run the build.sh script to create all of the basic documentation
  3. run $NCSA_DEV_INPUT/oa4mp-website/make-website.sh which creates the entire website and stick it in $NCSA_DEV_INPUT/oa4mp/docs
  4. commit everything to Git
  5. in GitHub, go to the settings page for the project and go to the Pages. You can set the version for Pages to whatever you just committed

The update is (relatively) live in the sense that it will take a few minutes. If yo go to the main landing page for OA4MP you should see the new version on the page.

oa4mp's People

Contributors

jjg-123 avatar jbasney avatar bbockelm avatar georgianaelena avatar ysvenkat avatar dependabot[bot] avatar

Stargazers

Haoming Meng avatar Till Riedel avatar Noble_d_Amour avatar Bryan Hess avatar Mingxuan Lin avatar  avatar  avatar

Watchers

Terry Fleury avatar  avatar  avatar James Cloos avatar  avatar Kenton McHenry avatar  avatar Jong Lee avatar Bryan Hess avatar  avatar  avatar  avatar

oa4mp's Issues

Support HTTP Basic authentication for Clients

https://tools.ietf.org/html/rfc6749#section-2.3.1

The authorization server MUST support the HTTP Basic
authentication scheme for authenticating clients that were issued a
client password.

http://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication

This section defines a set of Client Authentication methods that are used by Clients to authenticate to the Authorization Server when using the Token Endpoint. During Client Registration, the RP (Client) MAY register a Client Authentication method. If no method is registered, the default method is client_secret_basic.

client_secret_basic
Clients that have received a client_secret value from the Authorization Server authenticate with the Authorization Server in accordance with Section 2.3.1 of OAuth 2.0 [RFC6749] using the HTTP Basic authentication scheme.

Dynamic Client registration has incorrect HTTP status code

On creation, RFC 7591 states the server responds with an HTTP 201 (Created). OA4MP is currently returning HTTP 200 (OK). At least in the client library I'm using, the corresponding client is rejected as it's the incorrect status.

Log file has NPE

I currently have this logging configuration:

        <logging
                logFileName="/opt/scitokens-server/log/scitokens-server.log"
                logName="scitokens-server"
                logSize="100000"
                logFileCount="2"
                debug="trace"/>

in server-config.xml (note: I actually prefer logging to stdout; see #105).

However, when any interaction with an OAuth2 client is attempted, a NPE is thrown for each log message. Here's the top of the exception, everything after the standard Tomcat frames:

Jun 12, 2023 8:16:34 PM edu.uiuc.ncsa.security.core.util.MyLoggingFacade error
SEVERE: could not load configuration
java.lang.NullPointerException
        at edu.uiuc.ncsa.security.core.util.LoggingConfigLoader.<init>(LoggingConfigLoader.java:84)
        at edu.uiuc.ncsa.security.core.util.LoggingConfigLoader.<init>(LoggingConfigLoader.java:112)
        at edu.uiuc.ncsa.oa4mp.delegation.common.servlet.DBConfigLoader.<init>(DBConfigLoader.java:30)
        at edu.uiuc.ncsa.myproxy.oa4mp.client.loader.AbstractClientLoader.<init>(AbstractClientLoader.java:46)
        at edu.uiuc.ncsa.oa4mp.oauth2.client.OA2ClientLoader.<init>(OA2ClientLoader.java:41)
        at edu.uiuc.ncsa.myproxy.oauth2.tools.OA2CommandLineClient.getLoader(OA2CommandLineClient.java:43)
        at edu.uiuc.ncsa.security.util.cli.ConfigurableCommandsImpl.getEnvironment(ConfigurableCommandsImpl.java:196)
        at edu.uiuc.ncsa.myproxy.oauth2.tools.OA2CLCCommands.<init>(OA2CLCCommands.java:108)
        at edu.uiuc.ncsa.oa2.servlet.ProxyUtils.getCLC(ProxyUtils.java:200)
        at edu.uiuc.ncsa.oa2.servlet.ProxyUtils.doRFC8628AT(ProxyUtils.java:246)
        at edu.uiuc.ncsa.oa2.servlet.OA2ATServlet.doRFC8628(OA2ATServlet.java:1675)
        at edu.uiuc.ncsa.oa2.servlet.OA2ATServlet.executeByGrant(OA2ATServlet.java:159)
        at edu.uiuc.ncsa.oa2.servlet.OA2ATServlet.doIt(OA2ATServlet.java:898)
        at edu.uiuc.ncsa.security.servlet.AbstractServlet.doPost(AbstractServlet.java:210)
        ...

Can we (a) have guidance on how to best configure the logging? and (b) improve the exception for whatever is causing the above error?

Compliance -- "extra claims" in ID Token

For the oidcc-scope-email test. They give a warning that we are returning the email in the IDT (ID Token) when response_type=code.

They assert that response_type=id_token requires the email be returned in the IDT otherwise it is only returned from the UserInfo endpoint. The reason they give is that there are OIDC servers that do not return ATs, hence there is no way to get the full IDT for them.

This is not illegal. We do this since a lot of services return the same user claims in the UserInfo info endpoint and many of our clients expect this.

Support dynamic client registration for oidc-agent

Currently OA4MP supports dynamic client registration with a protected registration endpoint, and OA4MP does not have the option to make the registration endpoint public. To better support oidc-agent:

  1. Add an OA4MP configuration option for making the registration endpoint public so that calling oidc-gen and providing the issuer url when prompted results in a successful registration.
  2. For OA4MP servers that need to keep the registration endpoint protected, confirm that it works using the oidc-gen --at option.

Delete clients that have never been used

OA4MP should use the new last_accessed and create timestamp to automatically remove clients. This is especially important for the lightweight issuer that allows dynamic client registrations. A common case is someone makes a client then does not use it owing to any of various factors. Typically this should be a thread that checks every 4 - 6 hours (configurable).

Change client default scope loading

Currently the default is to load every scope for a client, then remove what is explicitly denied. This was done originally to make deploying the client (intended as a very simple sample) a snap. Evolution has made the client central to any number of operations such as proxying and this is now counter-intuitive and annoying.

The expected behavior is that only listing a scope explicitly adds it to the client's request list. Optionally it may be disabled (mostly so you don't have to go to the trouble of removing it from the configuration for, say, debugging purposes).

INI parser cannot handle `\`

My LDAP password is of the form prefix\Rpost (that is, some prefix characters, a \ character, a R, and then some more characters).

I have an INI file parsed by QDL that looks like the following:

# cat /opt/secrets/cilogon_ldap_password.ini 
[prod]
server := 'ldap.example.com';
port := '636';
name := 'uid=readonly,ou=system,dc=example,dc=com';
password := 'prefix\\Rpost';
search_base := 'dc=example,dc=com';

When parsed as the above in a QDL script with the following line:

  ini. := file_read('/opt/secrets/cilogon_ldap_password.ini', 2).'prod';

Then the password posted is equivalent to: prefix\\Rpost; this causes the LDAP server to reject the credential as the LDAP server receives a password with two \ characters instead of one \. I verified from the trace output the password sent to the LDAP server is like this:

  "password": "prefix\\\\Rpost",

OTOH, if I do not escape, having a line like in the INI file:

password := 'prefix\Rpost';

then the INI file has a syntax error according to the parser:

Error reading file '/opt/secrets/cilogon_ldap_password.ini'unkown type

Note, if I put the password directly in the QDL file:

  ldap_cfg.password           := 'prefix\\Rpost';

with the \\ in order to escape things, all is well. The LDAP server receives a password with a single \ character.

So, it seems there's a problem with the INI parser -- one \ in the file is too few, two \ is too many.

This is with OA4MP 5.2.9.0 plus posted QDL jars.

Allow for synonym to org.cilogon.userinfo scope

Just in the name of keeping the projects straight, org.oa4mp:userinfo should be an alias to the cilogon user info scope. CILogon only supports the latter and ignores the former, but as OA4MP gets used as a standalone system, it should have its own names for things.

Improve scripting capabilities

Currently the scripting that is available on a server is rather primitive. It started as merely the ability to tweak a claim here or there but evolved in to something much more complex. This was bad, because it's function changed over time into a full blown policy language. Since it was never intended for such a thing, it was becoming very unmanageable and fragile. The most usual case now is to have a large rat's nest of conditions based on IDPs, user affiliations, groups from possibly multiple LDAP or HTTP header sources etc with the final result of tweak or asserting a claim. Extending the current system was simply asking for trouble since it was never intended to do something so heavyweight. Also, the entry points for the scripting were mostly ad hoc, rather than simply being at strategic points of the OAuth flow.

A completely new policy language humorously referred to as the quick and dirty language or QDL ("quiddle" meaning a trifle or something small) has come in to existence. This is now properly incorporated in to each phase of the server's operation and allows for very complex logical operations.

Update Google authorization endpoint

Context

Issue

It seems that CILogon is using an old Google endpoint, which is http://google.com/accounts/o8/id as I didn't find any references of this endpoint in the Google docs.

I'm not familiar with the codebase, but the url above seems to be used a few times https://github.com/ncsa/OA4MP/search?q=http%3A%2F%2Fgoogle.com%2Faccounts%2Fo8%2Fid&type=code

proxy mode should not bypass OAuth consent page

When configured in proxy mode, OA4MP should still display a consent page to show the OAuth scopes being requested, before sending the user's browser to the external OIDC Provider for authentication (which will have its own consent page containing the requested OIDC scopes).

Tomcat 10 support

I'm running into some issues with https://github.com/ncsa/OA4MP/releases/download/v4.3/client-4.3.tar under apache-tomcat-10.0.0-M1.

First one was java.lang.NoClassDefFoundError: javax/servlet/ServletContextListener.
Adding javax.servlet-api-3.1.0.jar to lib seemed to fix that.

Second one was java.lang.ClassCastException: edu.uiuc.ncsa.security.servlet.MyTomcatFilter cannot be cast to jakarta.servlet.Filter.

I'm going to try switching to apache-tomcat-7 for now.

Global debug flag in QDL scripts

Actually, this can be done much more elegantly with using QDL's built in debugger() command. Plan is to set debug with levels in the files on TEST then have change the level so they shut off on PROD. This keeps the code virtually identical which is quite important since the deploys are automated and even whitespace differences can through the whole thing for a loop.

https://jira.ncsa.illinois.edu/browse/CIL-1721

Remove requirement for / before identifiers in CLI

There are two ways to refer to an object in the CLI

  1. use the identifier, prefixed by a /,
  2. ls the current items and use the index (an integer) from the listing, e.g. 0, 11

Number 2 is good for smaller stores (like VOs), but there is really no reason to have an escape character for an identifier. Therefore make the escape character optional.

Compliance - CM error must always be JSON

In the Client Management API some errors (such as it bombs almost immediately when starting the exchange since it does not have credentials) will not produce an error in JSON format. This should be rectified.

Remove sign-artifacts from defaultGoal in pom.xml

The https://travis-ci.org/ncsa/OA4MP build fails with

gpg: no default secret key: secret key not available
gpg: signing failed: secret key not available
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-gpg-plugin:1.6:sign (sign-artifacts) on project myproxy: Exit code: 2 

I think it's because sign-artifacts is in defaultGoal in https://github.com/ncsa/OA4MP/blob/master/pom.xml.

To fix this error, please make sign-artifacts a separate build step, so the default build doesn't require a GPG setup.

oa4mp-cli: update scopes

We need the ability to edit a client's approved scopes using oa4mp-cli. Currently "use clients" followed by "update [id]" doesn't allow edit of scopes.

Broken Links in Documentation

Found many broken links in the documentation. Rather then record an incomplete list of the ones I hit I just ran my link checker, which found 400 errors.

Note, the link checker is far from perfect so you will find some false negatives and duplicates if the break is in the commonly used element.

oa4mp-doc=link-test.log

Document client management query

The client management endpoint supports a non-standard but useful feature. Issuing a GET with no client id returns a list of all clients ids and their names. This should be documented someplace.

openid should be the only default scope

http://grid.ncsa.illinois.edu/myproxy/oauth/common/configuration/scopes.xhtml says that all the following scopes are requested by default: openid+email+profile+org.cilogon.userinfo+edu.uiuc.ncsa.myproxy.getcert

However, from a privacy and data minimization standpoint, only the openid scope should be requested by default.

Also, a vanilla OA4MP server will reject a request for the org.cilogon.userinfo scope, since that's CILogon-specific, so a vanilla OA4MP client shouldn't be requesting it by default.

Logging to stdout mostly stops after some period (1-2 days?)

I have a test issuer which is run at trace-level logging and is logging to stdout. This is preferred for me as the stdout is forwarded to kubectl logs.

However, after some amount of time (unclear if it is time-based or size-based; perhaps after some log rotation is triggered?), the flow to stdout stops. This is the only message:

OA4MP command line client state stored on Mon Jun 12 20:04:24 UTC 2023

Is it possible to keep the logs flowing?

allow users to view and revoke tokens

I don't think there's an OAuth or OIDC standard for this, but it's common for OAuth providers to give the user a page to view a list of active tokens with the ability to revoke them. https://myaccount.google.com/permissions is one example.

I expect this functionality would only be supported for servers that use REMOTE_USER authentication so the user can authenticate to view their tokens.

oa4mp-co-oidc: Compilation failure

https://travis-ci.org/ncsa/OA4MP/builds/178429147

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project oa4mp-co-oidc: Compilation failure: Compilation failure:
[ERROR] /home/travis/build/ncsa/OA4MP/oa4mp-co-oidc/src/main/java/edu/uiuc/ncsa/co/servlet/ClientServlet.java:[31,46] error: incompatible types: ServiceEnvironmentImpl cannot be converted to COSE
[ERROR] /home/travis/build/ncsa/OA4MP/oa4mp-co-oidc/src/main/java/edu/uiuc/ncsa/co/ClientManager.java:[89,60] error: incompatible types: List cannot be converted to PermissionList
[ERROR] /home/travis/build/ncsa/OA4MP/oa4mp-co-oidc/src/main/java/edu/uiuc/ncsa/co/ClientManager.java:[107,61] error: incompatible types: List cannot be converted to PermissionList
[ERROR] /home/travis/build/ncsa/OA4MP/oa4mp-co-oidc/src/main/java/edu/uiuc/ncsa/co/ClientManager.java:[110,61] error: incompatible types: List cannot be converted to PermissionList

add fork()

Add a fork function, i.e., run a script in its own thread.

Convert OA4MP to non-OIDC OAuth 2 protocol

Currently, OA4MP is a dedicated OIDC server. It should be converted to being an OAuth 2.0 only server. This won't take a lot, mostly not checking for the openid scope and not returning ID tokens. It should, however, be configurable at the server level, so a simple change will turn on/off OIDC compliance.

Option to not forward scopes to via proxy

The proxy mode to CILogon for device flow defaults to passing along all the scopes in the token request to CILogon:

        InputLine inputLine = new InputLine("set_param", OA2CLCCommands.SHORT_REQ_PARAM_SWITCH, OA2Constants.SCOPE, scopesToString(t));
        debugger.trace(ProxyUtils.class, "getProxyUserCode input line=" + inputLine);
        clcCommands.set_param(inputLine);

In my case, this is wrong -- I want only the default openid scope that is set in the proxy OAuth2 client (in the proxy-config.xml file). The "real" client is requesting a number of WLCG scopes which, of course, isn't recognized by CILogon.

From CILogon's response, I will decide on which scopes to approve.

Can we either remove these lines or make it a configuration option?

Support Public Clients

To support clients like kubernetes kubectl (see kubernetes/kubernetes#37874), OA4MP should support the option to register Public Clients. As documented at http://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication, a Public Client does not authenticate itself at the Token Endpoint.

OA4MP MUST validate redirection URIs for public clients according to https://tools.ietf.org/html/rfc6749#section-10.6. I think OA4MP is already doing that for all clients.

Public Clients should have limited token scope (https://tools.ietf.org/html/rfc6819#section-5.1.5.1). For OA4MP, I think they should be limited to the openid scope, and not have access to the getcert, email, profile, or other scopes.

Add support for RFC 7523

Allow for client authorization using a key (section 2.2). Allow for authorization grant as well (section 2.1).

Have an "atime" equivalent for clients

On the OSG Slack, there was good discussion about reasonable protections that could be added for dynamically-registered clients.

One idea proposed was to be able to implement reasonable garbage collection of clients. Particularly, the thinking was:

  1. Garbage collect a dynamic client after 2 hours if it's never been used as part of a successful flow.
  2. Garbage collect a dynamic client 60 days after its last successful flow.

Now, I don't think we need to implement such early-stage ideas. However, if I were to implement them out-of-band via a script, the script would need to know, for a given client, when the last successful flow occurred -- think of it as an atime equivalent to the existing last-modified-time attribute currently saved in the client config.

Could we add such a field? Obviously, we'd need to do the same sort of tricks as Linux does for filesystem atime (such as only persisting this information once an hour).

If it's prohibitively difficult to add this information, is there something specific we can look for in the logs such that a script could generate an atime database from the logs themselves?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.