-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TRUNK-381: Support for alternate authentication schemes #2833
Conversation
api/src/main/java/org/openmrs/api/context/UserPassAuthenticationScheme.java
Outdated
Show resolved
Hide resolved
|
||
/** | ||
* A basic implementation of {@link Authenticated} that contains the necessary elements for an OpenMRS authentication. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you put a since annotation on this class?
api/src/main/java/org/openmrs/api/context/ContextAuthenticationException.java
Show resolved
Hide resolved
* Base class for authentication schemes that intend to leverage OpenMRS' {@link ContextDAO}. | ||
* | ||
* @see {@link Context#authenticate(AuthenticationScheme, Credentials)} | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you put a since annotation on this?
api/src/main/java/org/openmrs/api/context/UserPassAuthenticationScheme.java
Outdated
Show resolved
Hide resolved
api/src/main/java/org/openmrs/api/context/UserPassCredentials.java
Outdated
Show resolved
Hide resolved
* Typically in the case of a user the client would simply be identified with its username. | ||
*/ | ||
public String getClientName(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you plan to deal with this? "Credentials will contains scheme-specific properties"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dkayiwa this quote comes from @bmamlin's suggested JavaDoc on the ticket's description. I think the point is that devs/implementers can keep extending Credentials
implementations (such as extending UserPassCredentials
for example) or can provide their own implementations of Credentials
. Either way they will add members and methods that are useful to their custom auth. schemes. We can't anticipate as of yet what will be done, we can just leave the design open enough.
api/src/main/java/org/openmrs/api/context/BasicAuthenticated.java
Outdated
Show resolved
Hide resolved
api/src/main/java/org/openmrs/api/context/UserPassAuthenticationScheme.java
Outdated
Show resolved
Hide resolved
*/ | ||
public class UserPassAuthenticationScheme extends DaoAuthenticationScheme { | ||
|
||
protected static Log log = LogFactory.getLog(UserPassAuthenticationScheme.class); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why the above is not private static final?
api/src/main/java/org/openmrs/api/context/UserPassAuthenticationScheme.java
Outdated
Show resolved
Hide resolved
api/src/main/java/org/openmrs/api/context/UserPassAuthenticationScheme.java
Outdated
Show resolved
Hide resolved
*/ | ||
public class UserPassCredentials implements Credentials { | ||
|
||
protected String username; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why these are not private?
/* | ||
* This test auth scheme logs a user simply based on asserting that its UUID is valid and points to an exisiting user. | ||
*/ | ||
public class TestUuidAuthenticationScheme extends DaoAuthenticationScheme { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be better to instead of use a test with a username and password? Some sort of admin/test combination. For this to me looks closer to the real basic authentication which we have that is based on a username and password combination.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to say this more explicitly, this test should also stay to ensure that we support more than just our basic username and password db based authentication.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public Authenticated authenticate(AuthenticationScheme authenticationScheme, Credentials credentials) | ||
throws ContextAuthenticationException { | ||
|
||
if (log.isDebugEnabled()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the log.isDebugEnabled() check?
|
||
return this.user; | ||
if (log.isDebugEnabled()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the log.isDebugEnabled() check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dkayiwa those checks are all over the code base though, so I will let them in for now. I agree that it's weird, I would have assumed that a logger knows whether it supports debugging or not. Please advise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure there is any such in the latest version of master?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dkayiwa yes if you do a search, simply via GitHub like here, you will find dozens. One example on Concept
: https://github.com/openmrs/openmrs-core/blob/master/api/src/main/java/org/openmrs/Concept.java#L451
Permalink here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a pull request which removed those in a number of classes. I just noticed that it did not fully remove them from the entire codebase. 😊
public Authenticated authenticate(Credentials credentials) | ||
throws ContextAuthenticationException { | ||
|
||
if (log.isDebugEnabled()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the log.isDebugEnabled() check?
Which API will a module use for the wiring of a new authentication scheme? Will that be in another pull request? |
@dkayiwa no wiring per se, you just explicitly invoke We are working on a OAuth2 client module that authenticates with Keycloak, we will be able to provide an example shortly with a custom scheme. No Spring magic as of yet. |
@mks-d what i mean is when some one wants the existing unmodified openmrs reference application login page to use a custom authentication scheme provided by a module. |
@@ -267,6 +267,9 @@ public static void setContext(ServiceContext ctx) { | |||
} | |||
|
|||
/** | |||
* @deprecated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you take a look at this? https://wiki.openmrs.org/display/docs/Java+Conventions#JavaConventions-Deprecation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dkayiwa I did this in my last commit:
/**
* @deprecated as of 2.3.0, replaced by #authenticate(AuthenticationScheme, Credentials)
...
*/
Is that what you expect? If not please point me to the exact JavaDoc that you would like to have in place.
public Authenticated authenticate(Credentials credentials) | ||
throws ContextAuthenticationException { | ||
|
||
if (log.isDebugEnabled()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the log.isDebugEnabled() check?
@dkayiwa this PR does not yet cover such use case. It rather provides devs with an API to authenticate with other schemes if they need to. Btw I would suggest that we follow up with a PR on the Ref App module so that it uses the new API rather than the one that will be deprecated. |
I was looking at this text in the ticket description: " Ideally, substitution (or addition) of the authentication scheme would be protected (e.g., limited to the configuration file setting or not easily done through the API) so that random code could not easily substitute a bogus authentication scheme to subvert proper authentication." My understanding of the above was not to necessarily hard code the UsernamePasswordAuthenticationScheme but provide it as the default with ability to be overridden by the same authenticate(String username, String password) method call. |
Infact the public authenticate(AuthenticationScheme authenticationScheme, Credentials credentials) seems to do the opposite of the above. That is, makes it so easy for some random code to substitute a bogus authentication scheme to subvert proper authentication. 😊 |
@dkayiwa I see, so authentication schemes should be Spring-wired, and the Spring config would use the add and remove Does that imply that the only user identification that could ever be passed downstream is the username? |
Issue I worked on
see https://issues.openmrs.org/browse/TRUNK-381
Checklist: I completed these to help reviewers :)
My pull request only contains ONE single commit
(the number above, next to the 'Commits' tab is 1).
No? -> read here on how to squash multiple commits into one
My IDE is configured to follow the code style of this project.
No? Unsure? -> configure your IDE, format the code and add the changes with
git add . && git commit --amend
I have added tests to cover my changes. (If you refactored
existing code that was well tested you do not have to add tests)
No? -> write tests and add them to this commit
git add . && git commit --amend
I ran
mvn clean package
right before creating this pull request andadded all formatting changes to my commit.
No? -> execute above command
All new and existing tests passed.
No? -> figure out why and add the fix to your commit. It is your responsibility to make sure your code works.
My pull request is based on the latest changes of the master branch.
No? Unsure? -> execute command
git pull --rebase upstream master