• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

how to create custom annotation in jersey

 
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
want to create a custom annotation to check the user role and username (similar to@RolesAllowed)

tried google it , but no luck.

got some hint from here:
an example on how to create seculity filter

author said I can create a filter similar to "SecurityContextFilter" as he explained. I don't know how to read the injected values in my custom annotation.
For example, for @MyAnnotation("username", "rolename"), How can I get the value of "username" and "rolename" in "MySecurityContextFilter".

Anyone can show me an example? Hope I explained my question clear enough. thanks a lot!
 
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So you want to restrict things to hard-coded usernames in the code? Does that really make any sense?
 
Jimmy Chen
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Actually its for authorization. for a request uri: webservice/XXX/{userID}. it should only be accessed by administrator or user(other roles: user, superuser, etc) itself.

So, basically this filter will check the userID and {userID} in URI if they are match and the roles (user or superuser).

please check this post also
similar question

thanks!
 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Yu Chen wrote:
Actually its for authorization. for a request uri: webservice/XXX/{userID}. it should only be accessed by administrator or user(other roles: user, superuser, etc) itself.


That still does not explain why you want to hard-code usernames in an annotation.
 
Jimmy Chen
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No, I'm not going to hard-code it. the userid will be retrieved from principal through securitycontext.

Actually I borrowed it from the webpage linked in previous post.

"
You can inject the UriInfo to obtain the "username" path parameter.
Your annotation could declare the path parameter name that needs to be
checked, e.g.

@MyRolesChecker("username", "myole");
public String get() { ... }
"

For me, probably @MyAnnotation("rolename") will be enough. the userIDs will be retrieved from pricipal and URI.


thanks!
 
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Maybe start here: https://coderanch.com/how-to/java/AnnotationsExample
 
Jimmy Chen
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Ulf! That's a good tutorial. Sorry for the late response, I was out of internet for a while.

I still have trouble to get the annotation values.

As in the sample code:
"
AnnotationTest at = new AnnotationTest();
Class atClass = at.getClass();

Method mth = atClass.getMethod("someMethod");
annotations = mth.getAnnotations();
"

How can I implement it in my Jersey request/resource filter? the filter don't know which class will apply this annotation.

Thanks a lot!
 
Ulf Dittmer
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The article actually shows how to do that with the Audit annotation - the AuditFilter is only applied to resource methods that have that annotation.
 
Jimmy Chen
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Ulf!

Actually I don't know how to create the AuditFilter to read the "Audit" annotation values. I tried to figure it out from the tutorial, but still no clue.
 
Ulf Dittmer
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's in the ResourceFilterFactory class, almost at the end - to every AbstractMethod (an object that goes with a resource method, from what I understand) it adds an AuditFilter if the method is annotated with "@Audit".
 
Jimmy Chen
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for your prompt response.

The ResourceFilterFactory just adds all the filters needed to apply. My problem now is how to implement the AuditFilter.

E.g. in the tutorial,
@Audit("edit-book")

How to get the value "edit-book" in AuditFilter.
 
Ulf Dittmer
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The AnnotationsExample I linked to earlier shows that - both FirstAnno and SecondAnno have parameters which that are later retrieved at runtime.
 
Jimmy Chen
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I saw it. However, it requires a main class to access it. As below: "AnnotationTest at"

For the REST service, you don't know which class will be added annotation. So in my Filter class, how to do something like in the sample code:

"
AnnotationTest at = new AnnotationTest();
Class atClass = at.getClass();
"

The filter class don't know what class is "AnnotationTest".

Thanks a lot!
 
Ulf Dittmer
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't understand where you see the difficulty.

If you want a filter to so something about a particular annotation X it's annotated with, or one of its methods or fields are annotated with, then it would do it exactly as that example shows. No main method is required, that can happen in any method, or the constructor. The "AnnotationTest" of the example would be the filter object and class itself.

If you want some external class (not a resource) to do something about a resource class being annotated, then the approach of a ResourceFilterFactory would work - it gets called for each resource filter, no matter what class it is. Obviously it needs to know which annotations to look out for, but that's a reasonable requirement - otherwise there's no way it could do whatever needs doing for each annotation.
 
Jimmy Chen
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think I want to go with the first method.
Looks like working now, but not sure if it is the right way:

  • 1. I have to add the annotation value in ResourceFilterFactory through the AbstractMethod
  • 2. Initialize the annotation values in filter constructor








  • The previous problem I was missing is that I didn't pass by annotation values to filter as in <1> and <2>:

    securityFilters.add(new UserInRoleSecurityContextFilter(userInRoleAllowed.value()));

    this.rolesAllowed = (rolesAllowed != null) ? rolesAllowed : new String[] {};


    So, my understand is that each method has @UserInRoleAllowed annotation will have its own/separate UserInRoleSecurityContextFilter?


    ======================

    other questions:

    1. why am.getResource().getAnnotation() not working.

    this example in post uses both statements.

    UserInRoleAllowed userInRoleAllowed = am.getResource().getAnnotation(UserInRoleAllowed.class); //fails
    UserInRoleAllowed userInRoleAllowed = am.getAnnotation(UserInRoleAllowed.class); //works

    2. in <3>
    if (securityContext == null) {
    // securityContext should be set up in constructor, but still null <3>
    securityContext = request.getSecurityContext();
    }

    securityContext is declared as "private @Context", it suppose to be set up/initialized by jersey after constructor method. Why it is still null and I have to call request.getSecurityContext();

    If you can give me some explanation, I really appreciate.




     
    Ulf Dittmer
    Rancher
    Posts: 43081
    77
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    each method has @UserInRoleAllowed annotation will have its own/separate UserInRoleSecurityContextFilter?


    It needs to, the way this code works, since the list of allowed roles is encapsulated in the filter. Since each method can have a different set of roles, you need a different filter.

    why am.getResource().getAnnotation() not working.


    I'm sure it works fine, it just doesn't do what you think it does. Read the comments that go with the two different usages in the example you linked to - they explain the difference.
     
    Jimmy Chen
    Ranch Hand
    Posts: 54
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    A million thanks!!!
     
    Don't get me started about those stupid light bulbs.
    reply
      Bookmark Topic Watch Topic
    • New Topic