Unable to access my @AnonymousAllowed REST method anonymously

Hi there,

I’m trying to implement a REST service for my Confluence app that should be accessible to anonymous users. I proceeded as described in the Atlassian tutorial.

I wrote a single REST GET endpoint and annotated it with @AnonymousAllowed. As far as I understand the tutorial and any example code I’ve seen so far, this should do. When I run the refapp example from this tutorial, everything works as expected. When I try to access my own @AnonymousAllowed endpoint anonymously, however, I get a 401 status code with the error message “Client must be authenticated to access this resource”. Anonymous access to the Confluence instance is enabled. I just can’t spot the difference between the refapp and my own implementation.

I created a small demo app which shows this exact behaviour. It can be found here. When you run this demo with atlas-package && atlas-run, you can try to access http://localhost:1990/confluence/rest/oio-demo/1.0/configuration anonymously. You will get an Access Denied even though the corresponding REST method is annotated with @AnonymousAllowed (see class RestPluginConfigurationService).

What am I doing wrong?

Cheers, Roland

Hi @roland.krueger,

Can you try doing this, while I try to see your issue:

  1. Create confluence-plugin by: atlas-create-confluence-plugin
  2. Create a rest module via, go to directory created in 1: atlas-create.confluence-plugin-module (click on tab to see more details)
  3. Choose 9 (REST module), Specify REST details
  4. Enter atlas-run
  5. Look at your atlassian-plugin descriptor to see the url path of your rest, should be like http://localhost:1990/confluence/rest/endpoint-in-1/1.0/message and access this anonymously
  6. Should display a “Hello World”

Thanks!

Cheers,
Anne Calantog

2 Likes

Hi Anne,

thanks for your answer! I executed the steps you proposed and the result was working fine. The next thing to do for me was to figure out the difference between this skeleton application and my own non-functional code. Up to now I managed to narrow the problem down to the list of <Import-Package> in my pom.xml. When I replace my OSGi package imports with the package imports from the skeleton app

<Import-Package>
    org.springframework.osgi.*;resolution:="optional", 
    org.eclipse.gemini.blueprint.*;resolution:="optional", 
    *
</Import-Package>

then my @AnonymousAllowed REST service actually works. Now I’m trying to pinpoint the exact package import which is causing this issue. I’ll come back later to report my findings when I have found the culprit.

1 Like

Ok, so I finally managed to find my error: In my app, I don’t use the catch-all asterisk in the OSGi package imports in the pom.xml since this results in errors in a real-world app with lots of dependencies. Now, what I missed was adding the package com.atlassian.plugins.rest.common.security to my package imports. This is the package that contains the @AnonymousAllowed annotation. The tricky part about this is that there is no hint given by the running application as to what is going wrong. Usually, I get a NoClassDefFoundError when I forget to update my package imports. But in this case, since the problematic class is an annotation, the console log remains silent.

So, to wrap it up, I had to update the package import of my app with the annotation’s package like so

<Import-Package>
    org.springframework.osgi.*;resolution:="optional", 
    org.eclipse.gemini.blueprint.*;resolution:="optional", 
    ....
    com.atlassian.plugins.rest.common.security,
    ...
</Import-Package>

which makes the annotation take effect.

Hi @roland.krueger,

Awesome! Good to know you got it working! I was also looking at the pom.xml part because that would be the only difference between the two.

Cheers,
Anne